2013-08-10 4 views
10

Ich arbeite an einer einfachen Java EE-Anwendung.Warum wird PostConstruct nicht aufgerufen?

Ich habe Klasse wie folgt:

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); 

    } 
} 

Also mein Managed Bean ruft diese Methode. Bis hier keine Probleme. Aber da die Initialisierungsmethode nicht aufgerufen wird, erhalte ich eine NPE in em.persist.

Warum wird die Initialisierungsmethode nicht aufgerufen? Ich führe dies auf Glassfish Server.

Grüße.

+2

Für den Anfang sollten Sie nicht eröffnen Ihren 'EntityManager' in einem globalen Umfang; der 'EntityManager' entspricht grob einer Sitzung. Wenn Sie wirklich Ihre eigene Sitzungsverwaltung verwalten müssen (das Eingeben von @PersistenceContext ist besser), sollten Sie bei jedem Aufruf von 'addNewEntry' einen' EntityManager' erstellen und schließen. – chrylis

+1

Haben Sie bestätigt, dass Ihr Container das Objekt als Abhängigkeitsinjektion behandelt? Nicht jedes Objekt wird eingebunden, und wenn Sie nur 'new BlogEntryDao()' irgendwo aufrufen, weiß der Container möglicherweise nicht, dass es als Bean initialisiert werden soll. – chrylis

+0

@chrylis Ja danke, ich rufe eigentlich neuen BlogEntryDao an. –

Antwort

16

Die Java EE-Bean-Annotationen wie gelten nur für containergesteuerte Beans. Wenn Sie selbst new BlogEntryDao aufrufen, wird der Container die Erstellung nicht abfangen und die Methode aufrufen.

(Außerdem sollten Sie besser dran mit @PersistenceContext oder @PersistenceUnit anstatt manuell die EntityManagerFactory in Ihrem initialize() Methode holen, und Sie sollten einen EntityManager für jeden Anruf zu addNewEntry() erschaffen, da sie nur von kurzer Dauer-sind geschlagen. diese Änderungen würden die Notwendigkeit initialize() gar beseitigen.)

10

Da diese Frage für die erste auf Google kommt „postconstruct nicht genannt“, einen weiteren Grund, eine @PostConstruct Methode außer mit dem new Schlüsselwort möglicherweise nicht statt @PostConstruct des setzen aufgerufen wird in Eine Spring Bean ist, wenn Sie eine zirkuläre Abhängigkeit haben.

Wenn diese Bean von einer anderen Bean abhängig war, die von dieser Bean abhing, konnte die andere Bean addNewEntry() initialisiert werden, bevor BlogEntryDao initialisiert wurde, obwohl BlogEntryDao eine Abhängigkeit für diese andere Bean ist.

Dies liegt daran, dass Spring aufgrund des Zirkelverweises nicht wusste, welche Bean zuerst geladen werden sollte. In diesem Fall kann man den Zirkelverweis entfernen oder @AutoWired/@Value Konstruktorparameter anstelle von Elementwerten oder Sätzen verwenden, oder bei Verwendung der XML-Konfiguration können Sie die Reihenfolge ändern, in der die Beans definiert sind.

6

Ich hatte das gleiche Problem in meiner Anwendung. Sie haben nicht posten Sie Ihre Bean Kontextkonfiguration xml-Datei (also bin ich nicht sicher, ob es das gleiche Problem ist), aber in meinem Fall das Hinzufügen dieser Zeile:

<context:annotation-config/> 

mein Problem gelöst. Sie benötigen entweder <context:annotation-config/> oder <context:component-scan/>, um die Annotation @PostConstruct zu aktivieren.

+0

Hinweis: Dies ist für Spring-Anwendungen zwar richtig, aber die Frage bezog sich auf allgemeine JavaEE-Anwendungen. –

1

In meinem Fall wurde @PostConstruct nicht aufgerufen, weil meine initialize() -Methode statisch war und auch eine Ausnahme ausgelöst hat. In beiden Fällen wird die Methode ignoriert. Ich hoffe, es hilft jemandem, der denselben Fehler gemacht hat. Diese kann in der Konsole zu finden:

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.