0

環境

アプリケーションサーバー:JBoss AS7(7.1.1 Final)

JPAの実装:EclipseLink(2.4.1)

OS:Windows 7 DB:PostgreSQL 8.4

アップデート2、解決済み

問題は、を使用して注入する代わりに、AccountServiceクラスをインスタンス化したことでした@EJB。EntityManagerがサービスで正しく感染し、トランザクションを実行できるように修正した後em.persist(account);

アップデート

私は自分の問題を示す最小限のプロジェクトを作成しました。Githubに投稿:

https://github.com/gotling/jboss-eclipselink-problem

おそらく関連している2つの問題があり、EJBの正しい使用法を理解していないことが原因です。

  1. EnityManagerを永続性JARのAccountService.javaに挿入できないため、NullPointerExceptionが発生します。

  2. コンストラクターでEntityManagerをAccountServiceに送信する場合、em.persistを実行するときにtranasactionは見つかりません。

プロジェクト構造

EJB

  • lib /persistanceunit.jar

  • web-service.war

問題

JBossにJavaEEサービスのトランザクションを管理させようとしています。問題は、エンティティを永続化しようとしたときに、EclipseLinkがJBossによって管理されているトランザクションを取得していないように見えることです。

EclipseLinkを使用してJBossを設定する方法については、ガイドhttps://community.jboss.org/wiki/HowToUseEclipseLinkWithAS7(代替1および代替2ステップ4)に従いました。

設定

戦争

エンティティマネージャは、次のようにweb-service.warに挿入されます。

@WebService(....)
public class NotificationConsumerImpl implements NotificationConsumer {
    @PersistenceContext(unitName="foo")
    EntityManager em;

    public void notify(Notify notify) {
        AccountService accountService = new AccountService(em);
        accountService.create(notify);
    }
}

上記のクラスとサービスクラスの間に実際にはコントローラークラスがあり、Accountオブジェクトの変換が行われ、コードを短縮するためにそれが削除されました。

永続性ユニット

エンティティはこのように作成されます

persistanceunit.jarのAccountService.java

@Stateless
public class AccountService {
    private EntityManager em;

    public AccountService(EntityManager em) {
        this.em = em;
    }

    public void create(Account account) {
        em.persist(account);
    }
}

スタックトレース

アカウントエンティティを永続化する必要があるWSを呼び出すと、em.persist(account)で例外が発生します。

... 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:]

質問

  1. トレースロギングを有効にしました。id.au.ringerc.as7.eclipselinkpersistenceをログに表示するべきではありませんか?

  2. EntityManagerをpersistanceunit.jar内のサービスクラス内に注入することはどういうわけか可能ですか?

  3. これは、JBoss / EclipseLinkのどのバージョンですぐに使用できますか?

4

2 に答える 2

2

Bean に@TransactionManagement(TransactionManagementType.CONTAINER)で、createメソッドに でアノテーションを付ける必要があり@TransactionAttribute(TransactionAttributeType.REQUIRED)ます。最初のアノテーションは、トランザクションがコンテナーによって管理されていることをアプリケーション サーバーに知らせるために必要です。後者は、現在のトランザクションがない場合に、呼び出されるとすぐにメソッドがトランザクションを開始できるようにするために必要です。

于 2012-11-14T13:45:41.677 に答える
1

問題は、AccountService クラスが@EJBアノテーションを使用して注入されるのではなく、インスタンス化されることでした。EntityManager がサービスに正しく挿入され、 em.persist(account); の実行時にトランザクションが利用可能であったことを修正した後。

@WebService(....)
public class NotificationConsumerImpl implements NotificationConsumer {
    @PersistenceContext(unitName="foo")
    EntityManager em;

    public void notify(Notify notify) {
        AccountService accountService = new AccountService(em);
        accountService.create(notify);
    }
}

@WebService(....)
public class NotificationConsumerImpl implements NotificationConsumer {
    @PersistenceContext(unitName="foo")
    EntityManager em;

    @EJB
    AccountService accountService;

    public void notify(Notify notify) {
        accountService.create(notify);
    }
}
于 2012-11-19T07:36:28.373 に答える