如果我有实体管理器,如何获取会话对象?

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); SessionSession.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); SessionSession.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();

【讨论】:

以上是关于如果我有实体管理器,如何获取会话对象?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Symfony 2.1 从内部控制器获取 Doctrine 实体的实体管理器

如果我有会话 ID,如何获取会话参数详细信息

Symfony 2 从实体管理器获取实体的原始数据

并行获取文件

从众多实体中恢复一个获取的实体——核心数据

如何获取所有对象A的一对多关系B的所有属性的NSSet