2013-08-10 101 views
10

私は単純なJava EEアプリケーションを開発中です。PostConstructが呼び出されないのはなぜですか?

私はこのようなクラスを持っている:

import javax.annotation.PostConstruct; 
import javax.ejb.Stateless; 
import javax.persistence.EntityManager; 
import javax.persistence.EntityManagerFactory; 
import javax.persistence.Persistence; 

@Stateless 
public class BlogEntryDao { 

    EntityManager em; 

    @PostConstruct 
    public void initialize(){ 
     EntityManagerFactory emf = Persistence.createEntityManagerFactory("Persistence"); 
     em = emf.createEntityManager(); 
    } 

    public void addNewEntry(){ 
     Blogentry blogentry = new Blogentry(); 

     blogentry.setTitle("Test"); 
     blogentry.setContent("asdfasfas"); 

     em.persist(blogentry); 

    } 
} 

だから私のマネージドBeanは、このメソッドを呼び出します。ここまで問題はありません。しかし、initializeメソッドが呼び出されていないので、em.persistにNPEを取得しています。

なぜinitializeメソッドが呼び出されないのですか? Glassfishサーバーでこれを実行しています。

よろしくお願いいたします。

+2

、あなたがグローバルスコープで、あなたの 'EntityManager'を開くべきではありません。 'EntityManager'は大体セッションに対応しています。独自のセッション管理(@PersistenceContextの注入が優れています)を本当に処理する必要がある場合は、 'addNewEntry'を呼び出すたびに' EntityManager'を作成して閉じる必要があります。 – chrylis

+1

コンテナがオブジェクトを依存性注入が必要なものとして扱っていることを確認しましたか?すべてのオブジェクトに夢中になるわけではなく、 'new BlogEntryDao()'をどこかで呼び出すだけであれば、コンテナはそれをBeanとして初期化することを知らないかもしれません。 – chrylis

+0

@chrylisありがとう、私は実際に新しいBlogEntryDaoを呼び出しています。 –

答えて

16

@PostConstructなどのJava EE Beanアノテーションは、コンテナ管理Beanにのみ適用されます。単純にnew BlogEntryDaoを呼び出す場合は、コンテナが作成を傍受して@PostConstructメソッドを呼び出すことはありません。

(さらには、手動でinitialize()方法でEntityManagerFactoryをフェッチするのではなく、@PersistenceContext@PersistenceUnitを使用したほうが良いだろう、と彼らは短命だので、あなたは、addNewEntry()への呼び出しごとにEntityManagerを作成する必要があります。メイキングこれらの変化は全くinitialize()の必要性を排除するであろう。)

10

この質問は「と呼ばれていないpostconstruct」のためにGoogleで最初に起動するので、@PostConstruct方法はnewキーワードを使用しての代わりに@PostConstructを置く以外に呼び出されていない可能性があります別の理由を循環依存がある場合、Spring Beanがあります。

このBeanがこのBeanに依存する別のBeanに依存する場合、BlogEntryDaoが他のBeanの依存関係であっても、もう1つのBeanはを呼び出す可能性があります(BlogEntryDaoが初期化されました)。

これは、Springが循環参考のために最初にロードしたいBeanを認識しなかったためです。この場合、循環参照を削除するか、メンバー値またはセッターの代わりに@AutoWired/@Valueコンストラクターパラメーターを使用するか、xml構成を使用する場合は、Beanが定義されている順序を入れ替えることができます。

6

私のアプリケーションで同じ問題がありました。あなたのBeanコンテキストの設定xmlファイルを投稿する(ので、私はそれは同じ問題だかはわからない)が、私の場合には、この行を追加しませんでした :

<context:annotation-config/> 

は私の問題を解決しました。 @PostConstructアノテーションを有効にするには、<context:annotation-config/>または<context:component-scan/>が必要です。

+0

注:これはSpringアプリケーションでは正しいですが、一般的なJavaEEアプリケーションに関する質問がありました。 –

1

私の場合、initialize()メソッドが静的で例外もスローされていたため、@PostConstructは呼び出されませんでした。どちらの場合も、このメソッドは無視されます。私はそれが同じ間違いをした他の誰かを助けることを願っています。 これはコンソールで確認できます。手始めに

WARNING: JSF1044: Method '<XXX>' marked with the 'javax.annotation.PostConstruct' annotation cannot be static. This method will be ignored. 
WARNING: JSF1047: Method '<XXX>' marked with the 'javax.annotation.PostConstruct' annotation cannot declare any checked exceptions. This method will be ignored. 
関連する問題