简体   繁体   English

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

[英]JPA Native Query for Entity with Inheritance

I have an entity class and a subclass based on that entity: 我有一个实体类和一个基于该实体的子类:

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

and

@Entity
public class B extends A

I need to issue a native query that uses a stored procedure on the base class (A) only. 我需要发出一个仅在基类(A)上使用存储过程的本机查询。 If I attempt it as follows: 如果我尝试如下:

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

I get an error regarding "The column clazz_ was not found in the ResultSet". 我收到有关“在ResultSet中找不到列clazz_”的错误。 I assume that the JPA provider adds this column in order to discriminate between the base class and the extended class. 我假设JPA提供程序添加此列以区分基类和扩展类。 I can work around this problem by explicitly adding the clazz column and all of the fields from the subclass: 我可以通过显式添加clazz列和子类中的所有字段来解决此问题:

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

where "prop1" and "prop2" are properties of the subclass B. However, this seems like an unnecessary hack and is prone to maintenance problems if the subclass B changes. 其中“prop1”和“prop2”是子类B的属性。但是,这似乎是一种不必要的破解,如果子类B发生变化,则容易出现维护问题。

My question is: How can I query using a stored procedure on an entity that has inheritance defined on it? 我的问题是:如何在已定义继承的实体上使用存储过程进行查询?

As you've probably seen, the Hibernate team hasn't put a lot of work into defining how you do this.. the documentation simply states: 正如您可能已经看到的那样,Hibernate团队并未在定义您如何执行此操作方面投入大量精力。文档只是说明:

16.1.6. 16.1.6。 Handling inheritance 处理继承

Native SQL queries which query for entities that are mapped as part of an inheritance must include all properties for the baseclass and all its subclasses. 查询作为继承的一部分映射的实体的本机SQL查询必须包括基类及其所有子类的所有属性。

So if you want to use Native queries it looks like you're stuck doing something like this. 因此,如果你想使用Native查询,你看起来就像是在做这样的事情。 Regarding the concern about the subclass B changing, perhaps a slightly less onerous way of implementing this would be to try using LEFT OUTER JOIN syntax on the shared ID property: 关于子类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()

That way you'll always get all of the properties from B if you add or remove some. 这样,如果添加或删除某些属性,您将始终从B获取所有属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM