Mam aplikację piaskownicy Seam 3 przy użyciu JBoss 7, Hibernate jako domyślną implementację JPA i jako JSF jako interfejs WWW.JPA/Hibernate emituje bez aktualizacji przy zatwierdzaniu w środowisku EJB/Seam
Mam problem, że SQL UPDATE jest domyślnie połknięta.
Moja Stateful EJB w zakresie konwersacji utrzymuje rozszerzony scoped EntityManager i jeden podmiot, Container Managed Transakcje (wymaga nowy)
- EntityManager zostaje wstrzyknięty
- EJB używa EM załadować podmiotu i utrzymuje to w polu
- aplikacja JSF ma dostęp do EJB i jego podmiot, zmienia polu String
- Calles aplikacji JSF „Zapisz” metody w EJB
- w save() Sprawdzam, czy pole Entities zostało zmienione -> zostało poprawnie zmienione
- Nic więcej nie robię, kontener zatwierdza transakcję po zakończeniu save().
- Problem: Nie wykonano aktualizacji SQL w stosunku do bazy danych.
Jeśli mogę przedłużyć save() przez:
a) entityManager.contains (podmiot) Aktualizacja jest wykonywane zgodnie z oczekiwaniami (wynik jest "true")
LUB
b) entityManager.persist (encja) UPDATE jest wykonywana zgodnie z oczekiwaniami.
P: O ile rozumiem, specyfikacje ani a), ani b) nie powinny być wymagane, ponieważ Jednostka pozostaje zarządzana podczas całego procesu. Nie rozumiem, dlaczego a) ma wpływ na zapisywanie. Potrafię zobrazować b) ma wpływ na zapisywanie, ale nie powinno być wymagane, czy powinno?
Wszelkie wyjaśnienia są mile widziane.
Oto moja 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";
}
}
okazało się, entityManager.flush() rozwiązuje również problem. Ale nie rozumiem, dlaczego wydaje się to wymagane. Ze specyfikacji JPA: "Po zatwierdzeniu transakcji JTA dostawca musi przepłukać cały zmodyfikowany stan obiektu do bazy danych ." – user1187037
może gdzieś w FlushMode sesji hibernacji jest ustawiona na none? – Firo