如果我有实体管理器,如何获取会话对象?
Posted
技术标签:
【中文标题】如果我有实体管理器,如何获取会话对象?【英文标题】:How can I get the session object if I have the entity-manager? 【发布时间】:2011-05-08 02:06:26 【问题描述】:我有
private EntityManager em;
public List getAll(DetachedCriteria detachedCriteria)
return detachedCriteria.getExecutableCriteria("....").list();
如果正在使用 entitymanager,我如何检索会话,或者如何从我的分离条件中获取结果?
【问题讨论】:
另见((EntityManagerImpl)em).getSession();
【参考方案1】:
为了完全详尽,如果您使用的是 JPA 1.0 或 JPA 2.0 实现,情况会有所不同。
JPA 1.0
使用 JPA 1.0,您必须使用 EntityManager#getDelegate()
。但请记住,此方法的结果是特定于实现的,即不能从使用 Hibernate 的应用程序服务器移植到另一个。例如with JBoss 你会这样做:
org.hibernate.Session session = (Session) manager.getDelegate();
但是with GlassFish,你必须这样做:
org.hibernate.Session session = ((org.hibernate.ejb.EntityManagerImpl) em.getDelegate()).getSession();
我同意,这太可怕了,这里应该归咎于规范(不够清楚)。
JPA 2.0
在 JPA 2.0 中,有一个新的(更好的)EntityManager#unwrap(Class<T>)
方法,对于新应用程序来说,它比 EntityManager#getDelegate()
更受欢迎。
因此,使用 Hibernate 作为 JPA 2.0 实现(请参阅 3.15. Native Hibernate API),您会这样做:
Session session = entityManager.unwrap(Session.class);
【讨论】:
entityManager.unwrap(Session.class);
Session
在 Session.class
中是什么?是进口吗?
取决于 JPA 实现,如果您使用的是 eclipselink,则为 org.eclipse.persistence.sessions.Session
我必须使用entityManager.unwrap(Session.class)
将@Transactional
放在存储库类中。否则,我会收到java.lang.IllegalStateException: No transactional EntityManager available
。【参考方案2】:
请参阅Hibernate ORM User Guide 中的“5.1. 从 JPA 访问 Hibernate API”部分:
Session session = entityManager.unwrap(Session.class);
【讨论】:
entityManager.unwrap(Session.class);
Session
在 Session.class
中是什么?是进口吗?
Hibernate 手册已更改。第 15.8 点不再提供有关获取会话的任何信息。
截至 2019 年 1 月,Hibernate current (5.3.7) 手册 §5.1 仍将其声明为获取 Session 对象引用的方式。【参考方案3】:
这样会更好解释。
EntityManager em = new JPAUtil().getEntityManager();
Session session = em.unwrap(Session.class);
Criteria c = session.createCriteria(Name.class);
【讨论】:
【参考方案4】:'entityManager.unwrap(Session.class)' 用于从 EntityManager 获取会话。
@Repository
@Transactional
public class EmployeeRepository
@PersistenceContext
private EntityManager entityManager;
public Session getSession()
Session session = entityManager.unwrap(Session.class);
return session;
......
......
演示应用程序link。
【讨论】:
【参考方案5】:我在 Wildfly 工作,但我正在使用
org.hibernate.Session session = ((org.hibernate.ejb.EntityManagerImpl) em.getDelegate()).getSession();
正确的是
org.hibernate.Session session = (Session) manager.getDelegate();
【讨论】:
以上是关于如果我有实体管理器,如何获取会话对象?的主要内容,如果未能解决你的问题,请参考以下文章