2010-01-26 88 views
9

我有一个实体类,并基于该实体的一个子类:JPA本机查询的实体继承

@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() 

我得到一个关于“在结果集中找不到列clazz_”的错误。我假设JPA提供程序添加此列以区分基类和扩展类。

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

其中“PROP1”和“PROP2”是子类B.然而性能,这似乎是不必要的:我可以明确地添加clazz中列和所有从子类领域的解决此问题如果子类B发生变化,则容易出现维护问题。

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

回答

9

正如你可能已经看到,Hibernate的球队还没有把大量的工作,确定你是如何做到这一点..文档只是说:

16.1.6。处理继承

原生查询,其查询被映射为 遗产的一部分,必须包括基类的所有 性能 实体和所有 它的子类。

所以,如果你想使用原生查询,它看起来像你卡住做这样的事情。至于有关的子类b更改,也许是实现这个稍显逊色繁重的方式所关心的是使用LEFT OUTER JOIN上的共享ID属性语法尝试:

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属性。

+0

所以,我已经想到了这一点,但问题是,当Hibernate尝试从结果中膨胀对象et行,它找到两个id列,其中一个是null。我想我可以添加一个额外的where子句过滤器'b.id为空'。 – AnthonyF 2010-01-28 14:22:18

+0

问题是:当我们这样写时,我们总会得到B类的实例吗? – 2015-04-21 06:21:57