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

k5hmc34c  于 2022-12-13  发布在  其他
关注(0)|答案(6)|浏览(125)

我已经

private EntityManager em;

public List getAll(DetachedCriteria detachedCriteria)   {

    return detachedCriteria.getExecutableCriteria("....").list();
}

如果我使用entitymanager,我如何检索会话,或者我如何从我的分离条件中获得结果?

aoyhnmkz

aoyhnmkz1#

为了全面说明,如果您使用JPA1.0或JPA2.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.原生Hibernate API),您将执行以下操作:

Session session = entityManager.unwrap(Session.class);
q3qa4bjr

q3qa4bjr2#

请参见《Hibernate ORM用户指南》中的“5.1.从JPA访问Hibernate API”一节:

Session session = entityManager.unwrap(Session.class);
1dkrff03

1dkrff033#

这会解释得更清楚。

EntityManager em = new JPAUtil().getEntityManager();
Session session = em.unwrap(Session.class);
Criteria c = session.createCriteria(Name.class);
ippsafx7

ippsafx74#

'entityManager.unwrap(Session.class)'用于从实体管理器获取会话。

@Repository
@Transactional
public class EmployeeRepository {

  @PersistenceContext
  private EntityManager entityManager;

  public Session getSession() {
    Session session = entityManager.unwrap(Session.class);
    return session;
  }

  ......
  ......

}

演示应用程序link

46qrfjad

46qrfjad5#

如果您使用的是Hibernate 5,那么简单地使用EntityManager.unwrap()可能不起作用,这是由于Spring的代理行为和Hibernate中的最新变化(有关详细信息,请参阅this Spring issue,它是固定的,但并不真正)。
为了使它工作,我必须先使用null进行双重解包:

/**
 * Get the Hibernate {@link Session} behind the given {@link EntityManager}.
 *  
 * @see <a href="https://github.com/spring-projects/spring-framework/issues/19577">Spring Issue #19577</a>
 */         
public static Session getHibernateSession(EntityManager entityManager) {
    Preconditions.checkArgument(entityManager != null, "null entityManager");
    return ((EntityManager)entityManager.unwrap(null)).unwrap(Session.class);
}

我相信这是由于Spring的ExtendedEntityManagerCreator中对代理的unwrap()方法的处理:

...
else if (method.getName().equals("unwrap")) {
    // Handle JPA 2.0 unwrap method - could be a proxy match.
    Class<?> targetClass = (Class<?>) args[0];
    if (targetClass == null) {
        return this.target;
    }
    else if (targetClass.isInstance(proxy)) {
        return proxy;
    }
}
irtuqstp

irtuqstp6#

我在Wildfly工作但我用的是

org.hibernate.Session session = ((org.hibernate.ejb.EntityManagerImpl) em.getDelegate()).getSession();

正确的答案是

org.hibernate.Session session = (Session) manager.getDelegate();

相关问题