Я использую сессионного компонента ж/в EXTENDED контексте постоянства, и следующие настройки: @TransactionAttributeсохранялось объект не извлекается запрос, пока не совершат
@Stateful(...)
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class StatefulExtendedEJBBea {
@PersistenceContext(unitName = "JPAModel", type = PersistenceContextType.EXTENDED)
private EntityManager em;
...
/**
* With the REQUIRED txn attribute, we can ensure that each time
* this method is called a new transaction is created and any
* pending changes in the persistence context are committed.
*/
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void commitTransaction() {
}
/** <code>select o from Departments o</code> */
public List<Departments> getDepartmentsFindAll() {
return em.createNamedQuery("Departments.findAll").getResultList();
}
public <T> T persistEntity(T entity) {
em.persist(entity);
return entity;
}
}
Некоторые важные вещи, чтобы вызвать в этом примере :
- TXN не начато, когда метод persistEntity() вызывается, из-за фасоли уровня @TransactionAttribute (NOT_SUPPORTED) настройки.
- Txn только начинается и завершается, когда вызывается метод commitTransaction(), потому что он аннотируется @TransactionAttribute (ТРЕБУЕТСЯ).
Такой подход позволяет новым компаниям сохраняться (и их идентификаторы сгенерирован и автоматически присваиваемый JPA, используя @GeneratedValue) без JPA жадностью выдачи ВСТАВИТЬ STMT в БД. Следовательно, я могу сохранить объект сразу, прежде чем назначать значения свойств, потому что ограничения NOT NULL столбца еще не проверены. Только когда вызывается метод commitTransaction(), JPA выполняет INSERT stmt и выполняет COMMIT.
Теперь, похоже, работает так, как я ожидал, с перечисленными выше преимуществами. Проблема, с которой я сталкиваюсь, заключается в том, что я не могу получить новые постоянные объекты через запрос JPQL до тех пор, пока не будет вызвана commitTransaction(). Новые сохраняемые объекты, как представляется, управляются контекстом персистентности, потому что я могу продолжать их обновлять после вызова persistEntity(), и все последующие изменения должным образом сохраняются в БД при вызове commitTransaction(). Тем не менее, они не отображаются в кэше запросов, пока я не выдаю коммит.
Я предполагаю, что моя стратегия подавления txn до момента фиксации влияет на результаты запроса каким-то образом.
Есть подсказка для запроса, которую я могу использовать для принудительного сохранения (за пределами транзакции), но не завершенных объектов, которые должны быть включены в запросы JPQL?
TIA
Запросы всегда идут в базу данных. Если ваши объекты не находятся в базе данных, они не будут найдены по вашему запросу. –
Итак, когда JPA выполняет JPQL stmt, он выдает предварительный запрос для извлечения только значений PK? Затем он выполняет итерации по этим значениям PK, находит какие-либо сущности в своем кеше, которые соответствуют, и выдает только полный запрос с предложением where - список ПК, которые не были найдены? –
Это более или менее то, что происходит, когда у вас есть кеш второго уровня и кеш запросов, с Hibernate (не знаю других реализаций). Но я не понимаю, что это касается вашего вопроса. –