2017-03-31 6 views
1

@PostConstructメソッドで注入JTA EntityManagerを使用するJava EEプロジェクトがあります。 EntityManager.persistjavax.persistence.TransactionRequiredExceptionのために失敗します。これは、JSFマネージドBeanに注入されたEJBインスタンスを介して呼び出されたときに成功します。 @Resource UserTransactionUserTransaction.begin/commitまたはEntityManager.getTransaction.begin/commitでトランザクションを手動で開始するのは、JTA EntityManagerです。JTA EJBの@PostConstructメソッドでTransactionRequiredExceptionが発生するのはなぜですか?

EJBインターフェース

@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; 
    } 

EJBの実装:

@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> 

私はそれはGlassFishのだ(jdbc/example1データソースを提供する方法を知りませんでした4.1 Derby dを参照するJDBC接続プールに基づくJDBCリソースネットワークドライバを持つatabase)。他のすべてはhttps://github.com/krichter722/javaee-persist-in-postconstructにあります。

私は私が使用していない春を指し@PostConstructhttp://www.tikalk.com/java/doing-transactional-work-spring-service-using-postconstruct-method/でシンプルEntityManager.persistコールの例を超えたPersisting in @PostConstruct: javax.persistence.TransactionRequiredExceptionをお読みください。 @PostConstruct@PersistenceContext EntityManagerの動作が異なっているという声明は見つかりませんでした。

答えて

1

§8.6.2:

用語「不特定のトランザクションコンテキストは、」EJBアーキテクチャは完全に定義されていないいる場合を参照するEJB仕様で使用されていますエンタープライズBeanメソッドの実行のトランザクションセマンティクス。

...
コンテナ管理のトランザクション境界設定を持つステートレスセッションBeanのPostConstructまたはPreDestroyコールバックメソッドの実行。

代替ソリューションは、persistence.xmlファイルにjavax.persistence.sql-load-script-sourceプロパティを指定することです。それはあなたのデータベースをプリロードするSQLスクリプトを指しています。これは、アプリケーションまたはファイルのURLに埋め込まれたリソースです。

3

@PostConstructと@PreDestroyがトランザクションの一部であることを保証するものではありません。 PostConstructメソッドとPreDestroyメソッドでDB操作を行う必要はありません。 EJB 3.2仕様状態の

関連する問題