我有一个实体类和一个基于该实体的子类:
@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发生变化,则容易出现维护问题。
我的问题是:如何在已定义继承的实体上使用存储过程进行查询?
答案 0 :(得分:9)
正如您可能已经看到的那样,Hibernate团队并未在定义您如何执行此操作方面投入大量精力。文档只是声明:
16.1.6。处理继承
查询的本机SQL查询 作为一部分映射的实体 继承必须包括所有 基类和所有的属性 它的子类。
因此,如果你想使用Native查询,看起来你就像是在做这样的事情。关于子类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获取所有属性。
答案 1 :(得分:0)
您需要使用鉴别器来区分A的实例和B的实例。 使用以下注释之一:
@DiscriminatorValue
http://docs.oracle.com/javaee/5/api/javax/persistence/DiscriminatorValue.html
@DiscriminatorColumn
https://docs.oracle.com/javaee/5/api/javax/persistence/DiscriminatorColumn.html
@DiscriminatorFormula
http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html#d0e1168