Ich habe Java EE-Projekt, wo ich eine injizierte JTA EntityManager
in der Methode verwenden möchte. EntityManager.persist
schlägt aufgrund javax.persistence.TransactionRequiredException
fehl. Es ist erfolgreich, wenn es über eine EJB-Instanz aufgerufen wird, die in eine von JSF verwaltete Bean injiziert wird. Manuelles Starten einer Transaktion mit @Resource UserTransaction
und UserTransaction.begin/commit
oder EntityManager.getTransaction.begin/commit
, weil es ein JTA EntityManager
ist.Warum erhalte ich eine TransactionRequiredException in der @ PostConstruct-Methode in JTA EJB?
Die EJB-Schnittstelle
@Local
public interface UserService extends Serializable {
public void saveUser(AUser user);
}
@Entity
public class AUser implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private Long id;
private String username;
public AUser() {
}
public AUser(String username) {
this.username = username;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
Die EJB Implementierung:
@Stateless
public class DefaultUserService implements UserService {
private static final long serialVersionUID = 1L;
@PersistenceContext
private EntityManager entityManager;
public DefaultUserService() {
}
@PostConstruct
private void init() {
AUser user = new AUser("initUser");
saveUser(user);
}
@Override
public void saveUser(AUser user) {
entityManager.persist(user);
}
}
persistence.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="richtercloud_javaee-persist-in-postconstruct-jar_jar_1.0-SNAPSHOTPU" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/example1</jta-data-source>
<class>richtercloud.javaee.persist.in.postconstruct.jar.entities.AUser</class>
<properties>
<property name="eclipselink.target-database" value="Derby"/>
<!-- necessary in order to avoid syntax errors -->
<property name="javax.persistence.schema-generation.database.action" value="create"/>
<property name="eclipselink.ddl-generation" value="create-or-extend-tables"/>
<property name="eclipselink.target-server" value="Glassfish"/>
<!-- avoid non-severe NullPointerException being logged in GlasFish
<ref>https://java.net/jira/browse/GLASSFISH-21468f</ref>-->
</properties>
</persistence-unit>
</persistence>
ich nicht wusste, wie die jdbc/example1
Datenquelle zur Verfügung zu stellen (es Glassfish ist 4.1 JDBC-Ressource basierend auf einem JDBC-Verbindungspool, der sich auf einen Derby bezieht d atabase mit Netzwerktreiber). Alles andere ist verfügbar unter https://github.com/krichter722/javaee-persist-in-postconstruct.
Ich las Persisting in @PostConstruct: javax.persistence.TransactionRequiredException, die das Beispiel eines einfachen EntityManager.persist
Anruf in @PostConstruct
und http://www.tikalk.com/java/doing-transactional-work-spring-service-using-postconstruct-method/, die auf Frühling bezieht sich übersteigt, die ich nicht verwenden. Ich habe keine Aussage gefunden, dass sich @PersistenceContext EntityManager
in anders verhält.