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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2140992/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 19:39:08  来源:igfitidea点击:

JPA Native Query for Entity with Inheritance

javahibernateinheritanceormjpa

提问by AnthonyF

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. If I attempt it as follows:

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

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". I assume that the JPA provider adds this column in order to discriminate between the base class and the extended class. I can work around this problem by explicitly adding the clazz column and all of the fields from the subclass:

我收到有关“在 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()

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 的属性。然而,这似乎是一个不必要的 hack,如果子类 B 更改,则容易出现维护问题。

My question is: How can I query using a stored procedure on an entity that has inheritance defined on it?

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

采纳答案by BryanD

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. 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.

16.1.6. 处理继承

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

So if you want to use Native queries it looks like you're stuck doing something like this. 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 获得所有属性。