JTA-gesteuerte Transaktionen in JBoss AS7 mit EclipseLink, Transaktion ist benötigt
Umwelt
Application server: JBoss AS7 (7.1.1 Final)
JPA-Implementierung: EclipseLink (2.4.1)
OS: Windows 7 DB: PostgreSQL 8.4
Update 2 gelöst
Das problem war, dass ich instanziiert die AccountService-Klasse anstelle der Injektion mit @EJB
. Nach der Festsetzung des EntityManager war inected korrekt in der service und eine Transaktion zur Verfügung Stand, wenn dabei em.persist(account);
Update
Machte ich ein minimal-Projekt, das zeigt meine Probleme. Veröffentlicht auf Github:
https://github.com/gotling/jboss-eclipselink-problem
Habe ich zwei Probleme, die vermutlich im Zusammenhang und durch mich nicht zu verstehen, die Verwendung von EJB ist richtig.
-
Kann ich nicht EnityManager injiziert werden in AccountService.java in der Persistenz-GLAS, was in NullPointerException.
-
Wenn der Versand EntityManager im Konstruktor AccountService keine tranasaction gefunden wird, wenn dabei die em.weiterhin bestehen.
Projektstruktur
EJB
-
lib/persistanceunit.jar
-
web-service.Krieg
Problem
Ich versuche, JBoss-Software zum verwalten von Transaktionen in der Java EE service. Problem ist, dass EclipseLink scheint nicht zu Holen, die Transaktion verwaltet von JBoss wenn Sie versuchen, zu persistieren einer Entität.
Ich habe den guide befolgt https://community.jboss.org/wiki/HowToUseEclipseLinkWithAS7 (Alternative 1 und Alternative 2 Schritt 4) auf, wie Sie zum konfigurieren von JBoss mit EclipseLink.
Setup
KRIEG
Entity manager eingespritzt, wie dies in web-service.Krieg:
@WebService(....)
public class NotificationConsumerImpl implements NotificationConsumer {
@PersistenceContext(unitName="foo")
EntityManager em;
public void notify(Notify notify) {
AccountService accountService = new AccountService(em);
accountService.create(notify);
}
}
Gibt es eigentlich eine controller-Klasse, die zwischen der obigen Klasse und die service-Klasse, wo die Umwandlung der Konto-Objekt fertig ist, entfernt es zu verkürzen-code.
Persistenz-Einheit
Entität wird wie folgt erstellt
AccountService.java in persistanceunit.jar
@Stateless
public class AccountService {
private EntityManager em;
public AccountService(EntityManager em) {
this.em = em;
}
public void create(Account account) {
em.persist(account);
}
}
Stack-trace
Beim Aufruf eines WS, der sollte fortbestehen der Entität Account bekomme ich auch eine exception auf em.persist(Konto);
...
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:]
Fragen
-
Habe ich aktiviert Trace-Protokollierung. Sollte nicht id.au.ringerc.as7.eclipselinkpersistence im Protokoll sichtbar sein?
-
Ist es irgendwie möglich, den EntityManager injiziert, die innerhalb der service-Klasse in den persistanceunit.jar?
-
In die JBoss /EclipseLink-version sollte dieses wor, out of the box?
- Könnte Sie post
AccountService
Klasse? - Sind Sie sicher, dass es OK ist, zu erstellen und die EJB-Instanz mithilfe von operator new? IMO, sollte man es injizieren mit
@EJB AccountService accountService
. - Interessant. Nein, ich bin nicht sicher. Ganz neu in EJB. Nur ein test-Projekt und hochgeladen. Update main-post.
- Dank tair, das war es!! Ich fügte hinzu, @EJB AccountService accountService; in der WS-Klasse, in der es funktionierte wie ein Charme. Verrückt, das problem hat mich 3 Tage, um gelöst zu werden. Nun weiß ich ein wenig mehr obwohl.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sollten Sie kommentieren die Bohne mit
@TransactionManagement(TransactionManagementType.CONTAINER)
und diecreate
Methode mit@TransactionAttribute(TransactionAttributeType.REQUIRED)
.Die erste Anmerkung ist erforderlich, damit der application server wissen, dass die Transaktionen verwaltet der container, die letzteren lassen die Methode eine Transaktion zu starten, wenn es keine gegenwärtige, sobald es aufgerufen wird.
AccountService
bean verwenden Sie ein entity-manager kommen aus dem aufrufenden Objekt, auf diese Weise gibt es keine Transaktion erstellt und müssen Sie eines erstellen manuell. Nach dem Java-EE-standard und um Transaktionen verwaltet die container, in den entity-manager sollte injiziert werden in der ejb selbst. Also, bewegen Sie einfach die '@PersistenceContext(unitName="foo") EntityManager em; " auf derAccountService
bean und alles sollte funktionieren.persistence.xml
Konfigurationsdatei.notify(Notify notify)
Funktion, in der gleichen Klasse, wo kann ichem
gespritzt, bekomme ichjavax.persistence.TransactionRequiredException
You should annotate the bean with @TransactionManagement(TransactionManagementType.CONTAINER) and the create method with @TransactionAttribute(TransactionAttributeType.REQUIRED)
- Dies ist nicht der Fall. Diese sind beide bereits die Standardeinstellung.Das problem war, dass AccountService-Klasse instanziiert wurde, anstatt injiziert mit
@EJB
annotation. Nach der Festsetzung des EntityManager injiziert wurde korrekt in der service und eine Transaktion zur Verfügung Stand, wenn dabei die em.persist(Konto);Vor
Nach