detachedcriteria和detachedquery没有EntityManager

时间:2012-10-31 13:14:02

标签: java hibernate jpa

我有一个关于JPA的问题: 有没有办法使用JPA 2.0的API来模拟DetachedCriteria(来自Hibernate)?

如果有一种方法我需要扩展哪些类来实现这个目标?

我正在使用hibernate 3.6.5和hibernate-jpa-2.0-api-1.0.0.Final。

1 个答案:

答案 0 :(得分:2)

在hibernate中,你在Hibernate Session之外创建一个DetachedCriteria对象,然后将它附加到以后的Session中执行。

总之 - EJB样式的JPA EntityManagers(使用容器管理的PersistenceContext)可以创建一个自动行为类似于Hibernate DetachedCriteria的Query对象,但是“核心java”样式的EntityManagers(即应用程序管理的)永远不会创建行为相似的查询到Hibernate DetachedCriteria。

JPA的PersistenceContext相当于一个Hibernate Session JPA的查询等同于DetachedCriteria JPA EntityManager可能随时存在或不存在PersistenceContext。 EntityManager有三种类型:

  1. 事务上下文EM - 此类型的EM只能在SessionBean EJB中创建 - @Stateless或@Stateful。 PC完全由容器管理。当没有执行任何事务时,PC不存在。当事务已经启动并且持久性操作发生时,PC将自动创建并随事务一起附加和传播 - 每个EM操作在事务私有数据中查找PC。交易结束时,PC会自动清除并删除。
  2. 扩展上下文EM - 这种类型的EM也只能在SessionBean EJB中创建 - 但只能在@Stateful中创建。 PC也完全由容器管理。当bean启动会话对话时创建PC(从对bean的引用调用的第一个方法)。 PC附加到有状态会话Bean的私有数据。当会话对话的最后一个方法完成时(即调用@Remove标记的方法),PC被清除并删除。
  3. Application Managed EM - 这种类型的EM可以在任何地方创建 - 在任何类型的EJB或任何在其类路径中具有JPA类的Java POJO中。创建EM时会创建PC,并在EM关闭时清除并移除PC。
  4. 在情况(1)和(2)下,EntityManager可以随时创建一个Query(通过em.createQuery()方法)。稍后,当PC存在时,可以运行查询。这是Hibernate的身份行为。在情况(3)下,没有与Hibernate DetachedCriteria等效的东西。

    不要害怕我在这里提到EJB的事实。它们很容易实现,基本上只是添加了一些额外注释的POJO,并且无形地添加了一些App Server功能,使它们比POJO“更大,更快,更强”。

    (2)的一个例子:

    @Stateful   
    class MyStatelessEJB {    
       // Entity Manager is automatically created and injected     
       // persistent unit name is in persistence.xml
       @PersistenceContext(unitName="myPersistenceUnitName",type=PersistenceContextType.EXTENDED)   
       EntityManager em;    
       Query q1 = null;    
       Query q2 = null;
    
       @NOT_SUPPORTED                                     // no transaction or PC here 
       public methodA() {....                               
                          q1 = em.createQuery(...);       // create query anyway
                          q2 = em.createTypedQuery(...);
                          ...}  
    
       public methodB() {....  q.execute();  ...}    // transaction & PC here - just use Query
    
       @Remove   
       // when this method is completes the EJB Session ends    
       public methodC() {....  List<Foo> fooList = q.execute().getResultList; ...} 
    
    }
    

    (1)(具有事务范围PC的无状态会话Bean)的示例看起来类似,但没有实例变量,因为它是无状态的。 EntityManager&amp;查询必须在每个方法中创建并存储为本地变量,或者必须传递/传输到另一个可以存储它们的有状态EJB。