从JPA / Hibernate中的View加载实体

时间:2011-12-21 12:25:56

标签: java hibernate jpa view entity

我有一个使用Spring和Hibernate的应用程序。在我的数据库中,我需要在某些实体中加载一些视图。所以我正在尝试执行本机查询并使用从视图中检索到的数据加载类:

//In my DAO class (@Repository) 
public List<MyClass> findMyEntities(){
    Query query = em.createNativeQuery("SELECT * FROM V_myView", MyClass.class);
    return query.getResultList();
}

和MyClass的字段与视图的列名相同。

问题是Hibernate无法识别MyClass,因为它不是一个实体(它没有用@Entity注释)

  

org.hibernate.MappingException:未知实体

如果我将MyClass作为一个实体,系统会尝试为该实体创建/更新一个表,因为我已经配置了它:

  

<property name="hibernate.hbm2ddl.auto" value="update"/>

所以我提出这些问题:

  1. 我可以为单个实体禁用“hibernate.hbm2ddl.auto”吗?
  2. 有没有办法将视图中的数据加载到非实体类中?
  3. 如果没有,在我的情况下,将视图中的数据加载到hibernate类中的最佳方法是什么?
  4. 由于

3 个答案:

答案 0 :(得分:7)

放在你的班级

@Entity
@Immutable
@Subselect(QUERY)
public MyClass {....... }

Hibernate执行查询以检索数据,但不创建表或视图。这样做的缺点是它只能用于读数。

答案 1 :(得分:2)

您可以使用axtavt solution。您也可以只执行查询,并将List<Object[]>变换为明确返回List<MyClass>。或者您可以将视图映射为只读实体,这可能是最佳解决方案,因为它允许与其他表关联,通过JPQL,条件等查询。

在我看来,hibernate.hbm2ddl.auto应该仅用于快速n'脏原型。使用hibernate工具生成允许创建模式的SQL文件,并修改它以删除视图的创建。无论如何,如果它被设置为更新,它不应该跳过表创建,因为它已经存在(作为视图)?

答案 2 :(得分:1)

您可以使用AliasToBeanResultTransformer。由于它是特定于Hibernate的功能,因此您需要访问底层的Hibernate Session

return em.unwrap(Session.class)
         .createSQLQuery("...")
         .setResultTransformer(new AliasToBeanResultTransformer(MyClass.class))
         .list();