Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Inheritance OpenJPA连接继承-避免数据库连接_Inheritance_Jpa_Discriminator - Fatal编程技术网

Inheritance OpenJPA连接继承-避免数据库连接

Inheritance OpenJPA连接继承-避免数据库连接,inheritance,jpa,discriminator,Inheritance,Jpa,Discriminator,我将OpenJPA与联合继承策略一起使用(InheritanceType.join-因此超类中的所有字段都有一个表,而子类表只包含添加到子类中的任何字段,以及对超类表的引用)。 假设我有一个超类Person和许多子类:typePerson、TypeBPerson等,当有如下查询时: @NamedQuery( name="Person.findByName", query="SELECT p FROM Person p WHERE p.name = :name") 据我所知,我不会得到Pers

我将OpenJPA与联合继承策略一起使用(InheritanceType.join-因此超类中的所有字段都有一个表,而子类表只包含添加到子类中的任何字段,以及对超类表的引用)。 假设我有一个超类Person和许多子类:typePerson、TypeBPerson等,当有如下查询时:

@NamedQuery(
name="Person.findByName", 
query="SELECT p FROM Person p WHERE p.name = :name")
据我所知,我不会得到Person实例,而是得到适当的子类实例。 如上所述,为了实现这一点并获得适当的子类,OpenJPA将进行多个联接(每个子类一个联接)。这有相当糟糕的性能,特别是如果我有很多子类的话。 我的问题是,是否有任何方法可以通过给JPA一个要加入哪个表的提示来避免这种情况?我想到的第一件事是使用鉴别器值。OpenJPA支持使用带有连接策略的鉴别器,因此它应该能够根据鉴别器值确定子类(从而确定用于连接的适当表)?有没有办法做到这一点?
是否有其他方法可以避免不必要的数据库联接?

如果您只需要单个子类的实体,那么避免多余联接的最佳方法就是查询该子类。使用您的示例,它可能如下所示:

@NamedQuery(
name="Student.findByName", 
query="SELECT s FROM Student s WHERE s.name = :name")
queryString="SELECT p FROM Person p WHERE p.name = :name AND TYPE(p) IN (Student, Teacher)"
Student
Person
的子类。当然,应该在适当的子类上定义命名查询

这两种方法都不可能做到——使用超类查询和只连接一个子类表。持久性提供程序事先不知道结果,而向正确方向提示的唯一方法是搜索子类

EDIT:如果您不确定确切的子类,但可以限制可能的子类,则可以将JPQL
TYPE
关键字与IN子句一起使用,如下所示:

@NamedQuery(
name="Student.findByName", 
query="SELECT s FROM Student s WHERE s.name = :name")
queryString="SELECT p FROM Person p WHERE p.name = :name AND TYPE(p) IN (Student, Teacher)"
将实体名称用作
类型的参数。好的,它是区分大小写的。实际的鉴别器类型和值并不重要,因为您没有查询它。类型解析由提供程序完成


但是,我不确定它是否能使提供者限制必要的连接。如果您最终使用或基准测试了它,请说明它是否使用。

如果您只需要单个子类的实体,那么避免多余联接的最佳方法就是查询该子类。使用您的示例,它可能如下所示:

@NamedQuery(
name="Student.findByName", 
query="SELECT s FROM Student s WHERE s.name = :name")
queryString="SELECT p FROM Person p WHERE p.name = :name AND TYPE(p) IN (Student, Teacher)"
Student
Person
的子类。当然,应该在适当的子类上定义命名查询

这两种方法都不可能做到——使用超类查询和只连接一个子类表。持久性提供程序事先不知道结果,而向正确方向提示的唯一方法是搜索子类

EDIT:如果您不确定确切的子类,但可以限制可能的子类,则可以将JPQL
TYPE
关键字与IN子句一起使用,如下所示:

@NamedQuery(
name="Student.findByName", 
query="SELECT s FROM Student s WHERE s.name = :name")
queryString="SELECT p FROM Person p WHERE p.name = :name AND TYPE(p) IN (Student, Teacher)"
将实体名称用作
类型的参数。好的,它是区分大小写的。实际的鉴别器类型和值并不重要,因为您没有查询它。类型解析由提供程序完成


但是,我不确定它是否能使提供者限制必要的连接。如果您最终使用它或对其进行基准测试,请告知是否使用。

谢谢您的回答。不幸的是,这个选项不适合我的情况。我知道Person.Id,但我事先不知道它的类型,所以无法查询特定的子类。这就是为什么我问起鉴别器-我现在能想到的唯一方法是做两个查询:选择一个人,然后根据鉴别器值,查询合适的子类。但这似乎很奇怪,JPA不支持这一点,因为鉴别器用于解析子类。@Ane-我明白了。有一种我之前没有想到的不同的可能性,使用TYPE关键字。请看编辑。谢谢你的回答。不幸的是,这个选项不适合我的情况。我知道Person.Id,但我事先不知道它的类型,所以无法查询特定的子类。这就是为什么我问起鉴别器-我现在能想到的唯一方法是做两个查询:选择一个人,然后根据鉴别器值,查询合适的子类。但这似乎很奇怪,JPA不支持这一点,因为鉴别器用于解析子类。@Ane-我明白了。有一种我之前没有想到的不同的可能性,使用TYPE关键字。请查看编辑。我不是专家,但Discriminator列可能是解决方案。查看一个完整的示例,其中包含联合继承和DiscriminatorColumn用法。我不是专家,但DiscriminatorColumn可能是解决方案。查看一个完整的示例,其中包含联合继承和DiscriminatorColumn用法。