2013-08-10 28 views
10

Sto lavorando su una semplice applicazione Java EE.Perché PostConstruct non viene chiamato?

devo classe come questa:

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

    } 
} 

Quindi il mio bean gestito chiama questo metodo. Fino a qui senza problemi. Ma dal momento che il metodo di inizializzazione non viene chiamato, sto ricevendo un NPE in em.persist.

Perché il metodo di inizializzazione non viene chiamato? Sto facendo funzionare questo sul server di Glassfish.

Saluti.

+2

Per cominciare, non si dovrebbe essere aprendo il vostro 'EntityManager' in un ambito globale; "EntityManager" corrisponde approssimativamente a una sessione. Se hai davvero bisogno di gestire la tua gestione delle sessioni (iniettando @PersistenceContext è meglio), dovresti creare e chiudere un 'EntityManager' in ogni chiamata a' addNewEntry'. – chrylis

+1

Hai confermato che il tuo contenitore tratta l'oggetto come qualcosa che richiede un'iniezione di dipendenza? Non tutti gli oggetti vengono agganciati, e se stai solo chiamando 'new BlogEntryDao() da qualche parte, il contenitore potrebbe non sapere di inizializzarlo come bean. – chrylis

+0

@chrylis Sì, grazie, sto chiamando il nuovo BlogEntryDao in realtà. –

risposta

16

Le annotazioni bean Java EE come @PostConstruct si applicano solo ai bean gestiti dal contenitore. Se stai chiamando semplicemente new BlogEntryDao da solo, il contenitore non intercetterà la creazione e chiamerà il metodo @PostConstruct.

(Inoltre, si sarebbe meglio utilizzare @PersistenceContext o @PersistenceUnit invece di andare a prendere manualmente il EntityManagerFactory nel metodo initialize(), e si dovrebbe essere la creazione di un EntityManager per ogni chiamata a addNewEntry(), dato che sono di breve durata. Fare questi cambiamenti sarebbero eliminare la necessità di initialize() affatto.)

10

Dal momento che questa domanda arriva prima su Google per "postconstruct non detto", un altro motivo per un metodo @PostConstruct non potrebbe essere chiamato oltre ad utilizzare la parola chiave new invece di mettere @PostConstruct in un bean Spring è se si ha una dipendenza circolare.

Se questo bean doveva dipendere da un altro bean che dipendeva da questo bean, l'altro bean potrebbe chiamare addNewEntry() prima dell'inizializzazione di BlogEntryDao, anche se BlogEntryDao è una dipendenza per quell'altro bean.

Questo perché Spring non sapeva quale bean si voleva caricare prima a causa del riferimento circolare. In questo caso, è possibile rimuovere il riferimento circolare o utilizzare i parametri del costruttore @AutoWired/@Value anziché i valori dei membri o i setter oppure, se si utilizza la configurazione xml, è possibile scambiare l'ordine in cui sono definiti i bean.

6

Ho avuto lo stesso problema nella mia applicazione. Non hai caricato il file di configurazione XML contesto di bean (quindi non sono sicuro se è lo stesso problema), ma nel mio caso aggiungendo questa linea:

<context:annotation-config/> 

risolto il mio problema. È necessario <context:annotation-config/> o <context:component-scan/> per abilitare l'annotazione @PostConstruct.

+0

Nota: questo è corretto per le applicazioni Spring, ma la domanda riguardava le applicazioni JavaEE generali. –

1

Nel mio caso @PostConstruct non è stato chiamato perché il mio metodo initialize() era statico e lanciava anche un'eccezione. In entrambi i casi il metodo viene ignorato. Spero che aiuti qualcun altro che ha commesso lo stesso errore. Questo può essere trovato nella console:

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. 
Problemi correlati