ThreadLocal JPA EntityManager в DAO - PullRequest
       25

ThreadLocal JPA EntityManager в DAO

2 голосов
/ 15 сентября 2011

В моих DAO классах у меня есть ссылка на EntityManager. Я хочу сделать доступ к EntityManager потокобезопасным с помощью ThreadLocal.

Пока мои попытки привели только к NullPointerException с, и я не могу найти достойного примера.

Может ли кто-нибудь привести мне пример или указать правильное направление?

обновление : я попробовал предложение BalusC, но когда я одновременно получаю доступ к DAO через JSF и веб-сервис JAX-RS, я все еще получаю ошибки:

 org.hibernate.exception.GenericJDBCException: could not load an entity
 java.sql.SQLException: You can't operate on a closed Connection!!!
 java.lang.NullPointerException
    at com.mchange.v2.c3p0.impl.NewProxyConnection.prepareStatement

Я использую C3P0, поэтому я не знаю, почему закрытое соединение является проблемой.

update2 : последний комментарий BalusC, похоже, решил мою проблему: At least, you should not have a single instance of the DAO class shared throughout the application. Create a new one on every request.

Ответы [ 2 ]

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

Я хочу сделать доступ к потокобезопасному EntityManager с помощью ThreadLocal.

Не делайте этого.Пусть контейнер беспокоится об этом.Я бы сделал ваши DAO @Stateless EJB и использовал бы @PersistenceContext, чтобы ввести EntityManager.Например,

@Stateless
public class UserService {

    @PersistenceContext
    private EntityManager em;

    public User find(Long id) {
        return em.find(User.class, id);
    }

    // ...
}

Чтобы добавить его в управляемые JSF-компоненты или службы JAX-RS, просто используйте @EJB:

@EJB
private UserService userService;

Для управления уровнем транзакциииспользуйте аннотацию @TransactionAttribute (по умолчанию TransactionAttributeType#REQUIRED).

0 голосов
/ 15 сентября 2011

Почему вы заставляете CDI вводить EntityManger, когда вы не находитесь на сервере приложений EJB?Просто возьмите свой EntityManagerFactory, используя javax.persistence.Persistence и имя вашего модуля персистентности, затем с помощью EMF возьмите в свои EntityManager, как в сервлете, а что нет.Используйте блокировки транзакций базы данных для обеспечения последовательного параллельного доступа к БД, не пытайтесь сделать EntityManager безопасным для работы с потоками в коде Java.

...