JTA contrôlé les opérations dans JBoss AS7 à l'aide de EclipseLink, la Transaction est nécessaire
Environnement
Serveur d'Application: JBoss AS7 (7.1.1 Final)
Implémentation JPA: EclipseLink (2.4.1)
Système d'exploitation: Windows 7 de base de données: PostgreSQL 8.4
Mise à jour 2, résolu
Le problème est que j'ai instancié le AccountService classe au lieu de l'injecter à l'aide de @EJB
. Après la fixation de l'EntityManager était inected correctement dans le service et l'opération était disponible au moment de faire em.persist(account);
Mise à jour
J'ai fait un minimum de projet qui montre mes problèmes. Posté sur Github:
https://github.com/gotling/jboss-eclipselink-problem
J'ai deux problèmes qui sont probablement liées et en raison pour moi de ne pas comprendre l'utilisation des EJB correcte.
-
Je ne peux pas obtenir EnityManager être injecté dans AccountService.java dans la persistance JAR, résultant en une NullPointerException.
-
Si l'envoi de l'EntityManager dans le constructeur de AccountService pas tranasaction est trouvé lorsque vous faites des em.persistent.
Structure de projet
EJB
-
lib/persistanceunit.jar
-
web-service.la guerre
Problème
J'essaie de JBoss pour gérer les transactions dans mon Java EE service. Le problème est que EclipseLink ne semble pas ramasser les transactions gérées par JBoss lors de la tentative de persister une entité.
J'ai suivi le guide https://community.jboss.org/wiki/HowToUseEclipseLinkWithAS7 (Variante 1 et la Variante 2 de l'Étape 4) sur la façon de configurer JBoss avec EclipseLink.
Installation
GUERRE
Gestionnaire d'entités est injecté comme ce web-service.guerre:
@WebService(....)
public class NotificationConsumerImpl implements NotificationConsumer {
@PersistenceContext(unitName="foo")
EntityManager em;
public void notify(Notify notify) {
AccountService accountService = new AccountService(em);
accountService.create(notify);
}
}
Il est en fait un contrôleur de classe entre la classe ci-dessus et la classe de service, où la transformation de l'objet de Compte est fait, retiré de raccourcir le code.
Persistance De L'Unité De
Entité est créée comme ceci
AccountService.java dans persistanceunit.jar
@Stateless
public class AccountService {
private EntityManager em;
public AccountService(EntityManager em) {
this.em = em;
}
public void create(Account account) {
em.persist(account);
}
}
Trace de la pile
Lors de l'appel d'un WS qui devraient persister l'entité de Compte j'obtiens une exception sur em.persist(compte);
...
Caused by: javax.persistence.TransactionRequiredException: JBAS011469: Transaction is required to perform this operation (either use a transaction or extended persistence context)
at org.jboss.as.jpa.container.AbstractEntityManager.transactionIsRequired(AbstractEntityManager.java:692) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final]
at org.jboss.as.jpa.container.AbstractEntityManager.persist(AbstractEntityManager.java:562) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final]
at se.magos.service.AccountService.create(AccountService.java:50) [persistenceunit-0.0.1-SNAPSHOT.jar:]
Questions
-
J'ai activé la journalisation du suivi. Ne devrait pas id.de l'ua.ringerc.as7.eclipselinkpersistence être visible dans le journal?
-
Est en quelque sorte possible d'obtenir l'EntityManager injecté à l'intérieur de la classe de service à l'intérieur de la persistanceunit.jar?
-
Dans lequel JBoss /EclipseLink version devrait cette wor hors de la boîte?
- Pourriez-vous poster
AccountService
classe? - Êtes-vous sûr que c'est OK pour créer et EJB instance à l'aide de l'opérateur new? OMI, vous devez injecter à l'aide de
@EJB AccountService accountService
. - Intéressant. Non, je ne suis pas sûr. Tout à fait nouveau pour EJB. Viens de faire un projet de test et téléchargées. Sera mise à jour de poste principal.
- Grâce tair, qui l'a fait!! J'ai ajouté @EJB AccountService accountService; dans le WS classe elle a travaillé comme un charme. Un fou ce problème m'a fallu 3 jours pour être réglée. Maintenant, je sais un peu plus que ça.
Vous devez vous connecter pour publier un commentaire.
Vous devez annoter le haricot avec
@TransactionManagement(TransactionManagementType.CONTAINER)
et lacreate
méthode avec@TransactionAttribute(TransactionAttributeType.REQUIRED)
.La première annotation est nécessaire afin de permettre à l'application de serveur de savoir que les transactions sont gérées par le conteneur, ce dernier pour laisser la méthode de démarrer une transaction, si ce n'est pas l'un, dès qu'elle est invoquée.
AccountService
bean vous utilisez un gestionnaire d'entités provenant de l'objet appelant, de cette façon, aucune transaction n'est créé et vous devez en créer un manuellement. À la suite de la Java EE standard et afin d'obtenir transactions gérées par le conteneur, le gestionnaire de l'entité doit être injecté dans l'ejb lui-même. Donc, il suffit de déplacer le " @PersistenceContext(unitName="foo") EntityManager em; " à laAccountService
bean et tout devrait fonctionner.persistence.xml
fichier de configuration.notify(Notify notify)
fonction, dans la même classe où je peux obtenirem
injecté, - je obtenirjavax.persistence.TransactionRequiredException
You should annotate the bean with @TransactionManagement(TransactionManagementType.CONTAINER) and the create method with @TransactionAttribute(TransactionAttributeType.REQUIRED)
- Ce n'est pas le cas. Ceux qui sont à la fois déjà la valeur par défaut.Le problème était que AccountService classe est instanciée au lieu de injectée à l'aide de
@EJB
annotation. Après la fixation de l'EntityManager a été injecté correctement dans le service et l'opération était disponible au moment de faire em.persist(compte);Avant
Après