开发者

ThreadLocal JPA EntityManager in DAO

开发者 https://www.devze.com 2023-04-05 17:31 出处:网络
In my DAO classes I have a reference to an EntityManager. I want to make the acces to the EntityManager thread-safe by using ThreadLocal.

In my DAO classes I have a reference to an EntityManager. I want to make the acces to the EntityManager thread-safe by using ThreadLocal.

So far my attempts have only resulted in NullPointerExceptions, and I can't seem to find a decent example.

Can someone provide me with an example or point me in the right direction?

update: I've tried BalusC's suggestion开发者_C百科, but when I acces the DAO through JSF and the JAX-RS webservice at the same time, I'm still getting errors:

 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

I'm using C3P0, so I don't know why a closed connection is a problem.

update2: BalusC's last comment seemed to have solved my problem: At least, you should not have a single instance of the DAO class shared throughout the application. Create a new one on every request.


I want to make the acces to the EntityManager thread-safe by using ThreadLocal.

Don't do that. Let the container worry about this. I'd make your DAOs a @Stateless EJB and use @PersistenceContext to inject the EntityManager. E.g.

@Stateless
public class UserService {

    @PersistenceContext
    private EntityManager em;

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

    // ...
}

To inject it in your JSF managed beans or JAX-RS services, just use @EJB:

@EJB
private UserService userService;

To control the transaction level, use @TransactionAttribute annotation (which defaults to TransactionAttributeType#REQUIRED).


Why are you tring to CDI inject your EntityManger when you're not in an EJB app server? Just Grab a hold of your EntityManagerFactory using javax.persistence.Persistence and the name of your persistence unit, then with the EMF get a hold of your EntityManager(s) like in a servelet and what not. Use data base transaction locks to ensure consistem parallel access to the db, don't go around making EntityManager "thread" safe in java code.

0

精彩评论

暂无评论...
验证码 换一张
取 消