@PersistenceContext и статическое свойство - PullRequest
1 голос
/ 16 сентября 2011

Теперь пришло время задать новый вопрос о JPA.

У меня есть простое приложение, поэтому я хочу создать простой дао-класс для всех моих сущностей.

import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.hibernate.Session;

public class GenericDAO implements Serializable {

public GenericDAO() {
}

@PersistenceContext(unitName="TestAppPU")
public static EntityManager em;

public static <T> void save(T smth) {
    em.persist(smth);
}
public static <T> void merge(T smth) {
    em.merge(smth);
}
public static <T> void remove(T smth) {
    em.remove(smth);
    em.flush();
}

public static <T> List<T> getAll(Class<T> cls) {
    return (List<T>) ((Session) em.getDelegate()).createCriteria(cls).list();
}
}

Я пытался использовать это так:

testEntitys =GenericDAO.getAll(TestEntity.class);

Но это приводит к исключению NullPointerException относительно "em" в getAll (), поэтому похоже, что он не установлен с @PersistanceContext, как я ожидал.

@ PersistanceContext прекрасно работает, когда я использую его в управляемом компоненте:

@ManagedBean
@SessionScoped
public class TestBean {


    @PersistenceContext(unitName="TestAppPU")
    public EntityManager em;

...    
testEntitys = em.createQuery("select t from TestEntity t").getResultList();
...

Похоже, файл persistance.xml настроен правильно. Но я не хочу передавать их в GenericDAO.

Таким образом, мой вопрос заключается в том, как добиться @PersistanceContext, работающего в GenericDAO, как я ожидал (второй пример кода), и действительно ли это возможно, или мне следует внедрять дао-классы в каждый компонент, где я хочу использовать постоянство?

Ответы [ 2 ]

5 голосов
/ 17 сентября 2011

Инъекция в EntityManager в GenericDAO не сработала, потому что GenericDAO не управляется.Вместо этого, если бы класс был сессионным компонентом или управляемым компонентом, то инъекция сработала бы.

Кроме того, следует отметить несколько других моментов

  • Создание EntityManager не являетсядорогостоящая операция.Поэтому, когда вы хотите работать с сущностями, вы можете просто вставить EntityManager в требуемый класс и напрямую использовать методы в EntityManager.(Примечание: EM Инъекции в сервлеты следует избегать)
  • Этот GenericDAO, кажется, не предлагает много.EntityManager уже достаточно универсален, и вы можете просто использовать его напрямую.
  • Наконец, предупреждение об использовании static переменных и методов.Я бы посоветовал против этого ради тестируемости и безопасности потоков.

Использование @Stateless bean-компонентов с EntityManager, вводимых как DAO, является одной из распространенных практик.

Подводя итог, вы можете просто ввести EM в любой класс, который должен выполнять операции с сущностями, даже не используя DAO.Если вы хотите разделить проблемы, вы можете добавить боб Stateless с EM в виде DAO

0 голосов
/ 14 мая 2012

Spring может понимать аннотации @PersistenceContext как на уровне поля, так и на уровне метода, если PersistenceAnnotationBeanPostProcessor включен.

<!-- bean post-processor for JPA annotations -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

В качестве альтернативы явному определению PersistenceAnnotationBeanPostProcessor, рассмотрите возможность использования XML-контекста Spring: annotation-config в контексте вашего приложения конфигурации.

<!-- post-processors for all standard config annotations -->
<context:annotation-config/>
...