Что происходит после EntityManager.persist () - PullRequest
2 голосов
/ 15 января 2012

EntityManger вводится с аннотацией @PersistenceContext. Это метод из моего класса "DAO / Repository", который не аннотирован. Этот класс внедряется в EJB, которым необходимо получать данные из / в базу данных.

До сих пор я думал, что после того, как описанный ниже метод persist будет завершен, постоянный контакт сбрасывается, и данные сохраняются в базе данных, но из-за того, что происходит в моем приложении, я начинаю сомневаться в этом. Я создал источник данных и пул соединений в Glassfish, поэтому я использую транзакции, управляемые контейнером, насколько мне известно, однако я не использую аннотации транзакций.

Может ли кто-нибудь пролить на меня немного света?

public void persist(QuestionFeedback questionFeedback) {
    questionFeedback.setCreated(new Date());
    entityManager.persist(questionFeedback);
}

Использование Glassfish 3, совместимость с Java EE6

Ответы [ 3 ]

5 голосов
/ 15 января 2012

Метод persist делает объект постоянным, но еще не записывает изменение в базу данных.Обычно это происходит, когда транзакция фиксируется (провайдер может оптимизировать это, это может произойти раньше).

С помощью flush вы можете заставить запись произойти раньше, но она все равно будет видна только кодукоторый участвует в текущей транзакции.Чтобы сделать запись постоянной (видимой для всего внешнего кода), транзакция все еще должна быть зафиксирована.

Без каких-либо явных аннотаций ваш EJB-компонент будет по умолчанию транзакционным.

0 голосов
/ 15 января 2012

Поскольку EntityManager внедряется с помощью аннотации @PersistenceContext, вы наверняка используете транзакции, управляемые контейнером.

Во всяком случае, ваше предположение о том, что постоянство приводит к фиксации транзакции, неверно. Изменения, выполненные через persist, вносятся в базу данных при фиксации. Документация EntityManager говорит, что «новый экземпляр становится управляемым и постоянным, вызывая persist». В этом контексте «становится постоянным» не означает, что объект сохраняется в базе данных в этот момент. В тот момент, когда вызывается persist, сущность сохраняется в терминах PersistenceContext. Затем он сохраняется в базе данных в последний раз, когда транзакция фиксируется.

Поскольку вы не используете аннотации @TransactionAttribute для своих методов, будет применяться значение по умолчанию. По умолчанию используется TransactionAttributeType.REQUIRED. Это заставит контейнер создавать транзакцию при вызове первого бизнес-метода и распространять его на другие методы. Ваша транзакция будет зафиксирована после завершения вызова первого бизнес-метода. Тогда ваши изменения будут в базе данных (если откат не был выполнен).

0 голосов
/ 15 января 2012

Если вы не используете какие-либо аннотации транзакций, по умолчанию будут проводиться требуемые транзакции.Таким образом, ваш DAO будет выполняться в транзакции, и контекст постоянства будет сброшен не позднее, чем при фиксации транзакции.

Из JavaDoc в TransactionAttribute:

Если атрибут TransactionAttributeаннотация не указана, и бин использует демаркацию управляемой контейнером транзакции, предполагается семантика атрибута REQUIRED транзакции.

Из JavaDoc на FlushModeType:

Когда запросы выполняются внутри транзакции, если для объекта Query или TypedQuery задан FlushModeType.AUTO, илипараметр сбрасываемого режима для контекста постоянства имеет значение AUTO (по умолчанию), а параметр сбрасывающего режима не задан для объекта Query или TypedQuery, поставщик постоянства отвечает за обеспечение того, чтобы все обновления состояния всех объектов в контексте постоянствапотенциально может повлиять на результат запроса, видимые для обработки запроса.

Это означает, что контекст постоянства может быть сброшен раньше, если вы используете запрос, на результат которого может повлиять этот сброс.

...