31

私は単純な Java EE アプリケーションに取り組んでいます。

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

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 はこのメソッドを呼び出します。ここまでは問題ありません。しかし、初期化メソッドが呼び出されていないため、em.persistで NPE を取得しています。

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

よろしく。

4

9 に答える 9

24

などの Java EE Bean アノテーションは@PostConstruct、コンテナー管理の Bean にのみ適用されます。単にnew BlogEntryDao自分自身を呼び出している場合、コンテナーは作成をインターセプトして@PostConstructメソッドを呼び出すことはありません。

(さらに、メソッドで を手動で取得する代わりに or を使用する方がよいでしょう。また、for each@PersistenceContextへの呼び出しを作成する必要があります。これは、寿命が短いためです。これらの変更を行うと、 の必要がまったくなくなります。 )@PersistenceUnitEntityManagerFactoryinitialize()EntityManageraddNewEntry()initialize()

于 2013-08-10T12:18:42.427 に答える
19

私のアプリケーションでも同じ問題がありました。Bean コンテキスト構成 xml ファイルを投稿していません (同じ問題かどうかはわかりません) が、私の場合は次の行を追加します。

<context:annotation-config/>

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

于 2015-10-30T17:08:22.150 に答える
18

この質問は Google で「postconstruct not called」に対して最初に出てくるため、Spring Bean を配置する代わりにキーワード@PostConstructを使用する以外にメソッドが呼び出されない可能性があるもう 1 つの理由は、循環依存関係がある場合です。 new@PostConstruct

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

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

于 2014-12-09T02:46:47.087 に答える
0

ほとんどの方法はすでに言及されているためです。ただし、クラスの構成ファイルに Bean を作成することもできます

org.springframework.context.annotation.CommonAnnotationBeanPostProcessor

;

これにより、PostConstructおよびPreDestroyアノテーションが有効になります。

<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"></bean>

また、Predestroyの場合、 context.registerShutDownHook()を呼び出す必要があります。

于 2021-08-27T21:29:36.100 に答える