从 JPA/Hibernate 中的视图加载实体
Posted
技术标签:
【中文标题】从 JPA/Hibernate 中的视图加载实体【英文标题】:Load Entity from View in JPA/Hibernate 【发布时间】:2012-01-25 06:20:13 【问题描述】:我有一个使用 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"/>
所以我提出了这些问题:
-
我可以为单个实体禁用“hibernate.hbm2ddl.auto”吗?
有没有办法将视图中的数据加载到非实体类中?
如果不是,那么在我的情况下,将数据从视图加载到休眠中的类中的最佳方法是什么?
谢谢
【问题讨论】:
FWIW,其他 JPA 实现支持不是实体的结果类,而 JPA 2.0 规范只对实体类型只字未提。 【参考方案1】:您可以使用AliasToBeanResultTransformer
。由于是 Hibernate 特有的特性,所以需要访问底层的 Hibernate Session
:
return em.unwrap(Session.class)
.createSQLQuery("...")
.setResultTransformer(new AliasToBeanResultTransformer(MyClass.class))
.list();
【讨论】:
试一试我收到此错误:“错误 org.hibernate.property.BasicPropertyAccessor 预期类型:java.lang.Long,实际值:java.math.BigInteger”。我是否必须将所有数字设置为 BigInteger,或者有什么方法可以将它们转换为 Long? (这些数字来自另一个长值实体)。 @Javi:您可以将类的字段声明为BigInteger
,或将显式强制转换应用于 SQL 查询中的列(而不是 *
)。【参考方案2】:
您可以使用axtavt solution。您也可以只执行您的查询,并将List<Object[]>
显式转换为List<MyClass>
。或者您可以将您的视图映射为只读实体,这可能是最好的解决方案,因为它允许与其他表关联,通过 JPQL、Criteria 等进行查询。
在我看来,hibernate.hbm2ddl.auto
应该只用于快速 n' 脏原型。使用休眠工具生成允许创建模式的 SQL 文件,并修改它以删除视图的创建。无论如何,如果它设置为更新,它不应该跳过表创建,因为它已经存在(作为视图)吗?
【讨论】:
【参考方案3】:放在你的班级
@Entity
@Immutable
@Subselect(QUERY)
public MyClass .......
Hibernate 执行查询以检索数据,但不创建表或视图。这样做的缺点是它只能用于读数。
【讨论】:
以上是关于从 JPA/Hibernate 中的视图加载实体的主要内容,如果未能解决你的问题,请参考以下文章
JPA+Hibernate - 实体关系中的循环 - 级联策略
Spring JPA,Hibernate 仅从其他实体获取 PK 或 Id
Spring Boot:如何从 JPA/Hibernate 注释中保持 DDD 实体的清洁?
Spring JPA,Hibernate仅从其他实体获取PK或Ids
在 JPA/Hibernate 中使用 @OnetoMany 的实体中不存在时从数据库中删除子记录(Spring 引导应用程序)