Почему PostConstruct не вызывается?
Я работаю над простым приложением 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 вызывает этот метод. Пока здесь нет проблем. Но поскольку метод initialize не вызывается, я получаю NPE в em.persist.
Почему метод initialize не вызывается? Я запускаю это на сервере Glassfish.
С уважением.
Ответы
Ответ 1
Аннотации Java EE bean, такие как @PostConstruct
, применяются только к контейнерам beans. Если вы просто вызываете new BlogEntryDao
самостоятельно, контейнер не собирается перехватывать создание и вызывает метод @PostConstruct
.
(Кроме того, вам лучше использовать @PersistenceContext
или @PersistenceUnit
вместо ручной выборки EntityManagerFactory
в вашем методе initialize()
, и вы должны создать EntityManager
для каждого вызова addNewEntry()
, так как они недолговечны. Выполнение этих изменений полностью устранит необходимость initialize()
.)
Ответ 2
Поскольку этот вопрос сначала возникает в Google для "postconstruct not called", другая причина, по которой метод @PostConstruct
не может быть вызван, кроме того, используя ключевое слово new
вместо того, чтобы помещать @PostConstruct
в Spring bean если у вас есть круговая зависимость.
Если этот bean должен был зависеть от другого bean, зависящего от этого bean, ваш другой bean мог бы вызвать addNewEntry()
до инициализации BlogEntryDao
, хотя BlogEntryDao является зависимостью для этого другого bean.
Это потому, что Spring не знал, какой bean вы хотите загрузить первым из-за круговой ссылки. В этом случае можно удалить циклическую ссылку или использовать параметры конструктора @AutoWired
/@Value
вместо значений элементов или сеттеров или, если вы используете конфигурацию xml, возможно, вы можете поменять порядок, в котором определены beans.
Ответ 3
У меня была такая же проблема в моем приложении.
Вы не опубликовали свой XML файл конфигурации контекста bean (так что я не уверен, что это та же проблема), но в моем случае добавление этой строки:
<context:annotation-config/>
Решила мою проблему.
Вам нужно либо <context:annotation-config/>
, либо <context:component-scan/>
, чтобы включить аннотацию @PostConstruct.
Ответ 4
В моем случае @PostConstruct не был вызван, потому что мой метод initialize() был статическим и также выдавал исключение. В любом случае метод игнорируется. Надеюсь, это поможет кому-то другому, совершив ту же ошибку.
Это можно найти в консоли:
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.