У меня есть приложение-песочница Seam 3, использующее JBoss 7, Hibernate в качестве реализации JPA по умолчанию и JSF в качестве веб-интерфейса.
У меня проблема, что SQL UPDATE проглатывается по умолчанию.
Мой EJB с отслеживанием состояния в области диалога поддерживает EntityManager с расширенной областью действия и одну сущность, транзакции, управляемые контейнером (требуется новый)
- EntityManager вводится
- EJB использует EM для загрузки Entity и сохраняет его в поле
- Приложение JSF обращается к EJB и его объекту, изменяет поле String
- Приложение JSF вызывает метод «Сохранить» в EJB
- В save() я проверяю, было ли изменено поле Entities -> оно было изменено правильно
- Я больше ничего не делаю, контейнер фиксирует транзакцию после завершения save().
- Проблема: не выполняется обновление SQL для базы данных.
Если я расширим save() на:
а) entityManager.contains(entity) ОБНОВЛЕНИЕ выполняется, как и ожидалось (результат «истина»)
OR
б) entityManager.persist(entity) ОБНОВЛЕНИЕ выполняется, как и ожидалось
Q: Насколько я понимаю, спецификации ни a), ни b) не требуются, потому что сущность остается управляемой в течение всего процесса. Я не понимаю, почему а) влияет на сохранение. Я могу представить, что b) влияет на сохранение, но это не обязательно, не так ли?
Любое объяснение приветствуется.
Вот мой EJB:
@Named
@ConversationScoped
@Stateful
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class LanguageBean {
@PersistenceContext(type = PersistenceContextType.EXTENDED)
private EntityManager em;
@Inject
private UserTransaction transaction;
private Language value;
@Inject
Conversation conversation;
public LanguageBean() {
super();
}
@Begin
public void selectLanguage(Long anId) {
conversation.setTimeout(10 * 60 * 1000);
if (anId != null) {
value = em.find(Language.class, anId);
}
}
@BeforeCompletion
public void transactionComplete(){
System.out.println("transactionComplete");
}
public Language getValue() {
return value;
}
@Produces
@Named
@ConversationScoped
public Language getLanguage() {
return getValue();
}
public void setValue(Language aValue) {
value = aValue;
}
@End
public String save() {
// displays the changed attribute:
System.out.println("save code: "+value.getCode());
// why is either this required:
// boolean tempContains = em.contains(value);
// System.out.println("managed: "+tempContains);
// or: why is persist required:
em.persist(value);
return "languages?faces-redirect=true";
}
@End
public String cancel() throws SystemException {
transaction.setRollbackOnly();
return "languages?faces-redirect=true";
}
}