一尘不染

具有继承性的JPA本机查询实体

hibernate

我有一个实体类和一个基于该实体的子类:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class A

@Entity
public class B extends A

我需要发出仅在基类(A)上使用存储过程的本机查询。如果我尝试如下:

entityManager.createNativeQuery("select * from A a where procedure(f)",A.class).getResultList()

我收到有关“在ResultSet中未找到clazz_列”的错误。我假设JPA提供程序添加了此列,以便区分基类和扩展类。我可以通过显式添加clazz列和子类中的所有字段来解决此问题:

entityManager.createNativeQuery("select *,1 as clazz_,null as prop1,null as prop2 from A a where procedure(f)",A.class).getResultList()

其中“ prop1”和“ prop2”是子类B的属性。但是,这似乎是不必要的修改,并且如果子类B发生更改,则容易出现维护问题。

我的问题是:如何在已定义继承的实体上使用存储过程查询?


阅读 226

收藏
2020-06-20

共1个答案

一尘不染

正如您可能已经看到的那样,Hibernate团队在定义如何执行此方法方面并没有做很多工作。

16.1.6。处理继承

查询作为继承的一部分映射的实体的本机SQL查询必须包括基类及其所有子类的所有属性。

因此,如果您要使用本机查询,则看起来您像在做这样的事情。关于对子类B的更改的关注,实现此目的的一种较不繁琐的方法是尝试对共享ID属性使用LEFT OUTER
JOIN语法:

entityManager.createNativeQuery("select a.*, b*, 1 as clazz_, from A a LEFT OUTER JOIN B b on id = a.id where procedure(f)",A.class).getResultList()

这样,如果您添加或删除某些属性,您将始终从B获得所有属性。

2020-06-20