2013-08-10 3 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); 

    } 
} 

그래서 내 관리 빈은이 메소드를 호출합니다. 여기까지 아무 문제 없어. 하지만 initialize 메서드가 호출되지 않았으므로 em.persist에 NPE가 표시됩니다.

초기화 메서드가 호출되지 않는 이유는 무엇입니까? Glassfish 서버에서 실행하고 있습니다.

감사합니다.

+2

처음 엔 글로벌 범위에서'EntityManager'를 열면 안됩니다; EntityManager는 대략 세션에 해당합니다. 자신의 세션 관리 (@PersistenceContext를 주입하는 것이 더 좋다)를 처리해야한다면,'addNewEntry'를 호출 할 때마다'EntityManager'를 만들고 닫아야합니다. – chrylis

+1

컨테이너가 오브젝트를 종속성 주입이 필요한 것으로 처리하고 있음을 확인 했습니까? 모든 객체가 푹 빠져있는 것은 아니며,'new BlogEntryDao() '를 어딘가에 호출하는 경우, 컨테이너는 그것을 bean으로 초기화하도록 알지 못할 수도 있습니다. – chrylis

+0

@chrylis 그래, 고마워, 나는 새로운 BlogEntryDao를 실제로 부르고있다. –

답변

16

@PostConstruct과 같은 Java EE Bean 어노테이션은 컨테이너 관리 빈에만 적용됩니다. 단순히 new BlogEntryDao을 호출하는 경우 컨테이너는 생성을 가로 채고 @PostConstruct 메서드를 호출하지 않습니다.

(또한, 수동으로 initialize() 방법에 EntityManagerFactory를 가져 오는 대신 @PersistenceContext 또는 @PersistenceUnit를 사용하여 더 나을 것, 그리고 그들이 단명에 있기 때문에 당신은 addNewEntry() 각 호출에 대한 EntityManager를 작성해야합니다. 만들기 이러한 변화는 전혀 initialize()에 대한 필요성을 제거한다.)

10

을이 질문은 "호출되지 PostConstruct의"구글에 먼저 온다 때문에, @PostConstruct 방법은 new 키워드를 사용하는 대신에 @PostConstruct 퍼팅 외에라고하지 않을 수 있습니다 또 다른 이유를 순환 bean이 있다면 Spring bean이있다.

이 bean이이 bean에 종속 된 다른 bean에 종속 될 경우, BlogEntryDao가 다른 bean에 대한 종속성 임에도 불구하고 BlogEntryDao이 초기화되기 전에 다른 bean은 addNewEntry()을 호출 할 수 있습니다.

이것은 Spring이 순환 참조로 인해 처음으로로드하고자하는 bean을 알지 못했기 때문입니다. 이 경우 순환 참조를 제거하거나 멤버 값 또는 설정자 대신 @AutoWired/@Value 생성자 매개 변수를 사용하거나 xml 구성을 사용하는 경우 bean 정의 순서를 바꿀 수 있습니다.

6

나는 내 응용 프로그램에서 동일한 문제가있었습니다. 당신은 당신의 빈 컨텍스트 구성 XML 파일을 게시되지 않은 (그래서 잘 모르겠어요이 같은 문제가 있다면)하지만 내 경우에이 줄을 추가 :

<context:annotation-config/> 

내 문제를 해결합니다. @PostConstruct 주석을 사용하려면 <context:annotation-config/> 또는 <context:component-scan/> 중 하나가 필요합니다.

+0

참고 : 이것은 Spring 애플리케이션에 대해서는 맞지만 일반적인 JavaEE 애플리케이션에 대한 질문이었습니다. –

1

내 initialize() 메서드가 정적이고 예외를 throw했기 때문에 @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. 
관련 문제