J'ai une application sandbox Seam 3 utilisant JBoss 7, Hibernate comme implémentation JPA par défaut et JSF comme frontal Web.JPA/Hibernate n'émet aucune mise à jour lors de la validation dans un environnement EJB/Seam
J'ai le problème, que le SQL UPDATE est avalé par défaut.
Mon stateful EJB portée de conversation maintient une longue portée a été définie EntityManager et une entité, les transactions gérées par conteneurs (Oblige les nouveaux)
- Le EntityManager obtient injecté
- L'EJB utilise l'EM pour charger l'entité et conserve dans un champ
- application JSF accède à l'EJB et son entité, modifie un champ de chaîne
- application JSF calles méthode « Enregistrer » dans EJB
- dans save() Je vérifie, si le champ Entities a été changé -> il a été changé correctement
- Je ne fais rien de plus, le conteneur valide la transaction après que save() soit fini.
- Problème: Aucune mise à jour SQL n'est effectuée sur le DB.
Si je transmets save() par:
a) entityManager.contains (entité) UPDATE est exécutée comme prévu (résultat est "vrai")
OU
b) entityManager.persist (entity) le UPDATE est exécuté comme prévu
Q: Dans la mesure où je comprends les spécifications, ni de a) ni de b) ne devraient être requises, car l'entité reste gérée pendant tout le processus. Je ne comprends pas, pourquoi a) a un effet sur la sauvegarde. Je peux imager le b) a un effet sur la sauvegarde, mais il ne devrait pas être nécessaire, devrait-il?
Toute explication est la bienvenue.
Voici mon 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";
}
}
J'ai découvert entityManager.flush() résout également le problème. Mais je ne comprends pas pourquoi cela semble nécessaire. De la spécification JPA: "Lorsque la transaction JTA valide, le fournisseur doit vider tout l'état de l'entité modifiée à la base de données ." – user1187037
peut-être quelque part le FlushMode de la session d'hibernation est défini sur none? – Firo