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
Hibernate 满足接口定义的自引用JPA实体_Hibernate_Jpa_Spring Data Jpa_Spring Data_Self Referencing Table - Fatal编程技术网

Hibernate 满足接口定义的自引用JPA实体

Hibernate 满足接口定义的自引用JPA实体,hibernate,jpa,spring-data-jpa,spring-data,self-referencing-table,Hibernate,Jpa,Spring Data Jpa,Spring Data,Self Referencing Table,我有一个spring+Data JPA设置,其中包含几个实体,这些实体继承自“伪”Java中的接口定义: @Entity A implements WithSubProperty @Id Long Id SubProperty subProperty … @Entity B implements WithSubProperty @Id Long Id SubProperty subProperty … Interface WithSubProperty SubProperty subPro

我有一个spring+Data JPA设置,其中包含几个实体,这些实体继承自“伪”Java中的接口定义:

@Entity 
A implements WithSubProperty
@Id
Long Id
SubProperty subProperty
…

@Entity
B implements WithSubProperty
@Id
Long Id
SubProperty subProperty
…

Interface WithSubProperty
SubProperty subProperty
…

@Entity
SubProperty
@Id
Long Id
…
每个实体都有自己的表。 此外,有几个存储库片段使用接口定义,以便仅为以下兼容类实现一次自定义逻辑:

RepositoryFragment<WithSubProperty, K>
List<WithSubProperty> findAllWithSubProperty(SubProperty subProperty)
…
一个想法是引用id列,基本上形成一个与自身的OneToOne关系。到目前为止,我无法让它工作。 乍一看,这种方法看起来有点笨拙,但除了可能缺少JPA/Hibernate的支持以及最终陷入递归的风险之外,不应该存在其他问题。思想?谢谢

更新: 下面是一个最小的不起作用的示例:

很抱歉,上面的代码可能会造成混乱。我的原始代码是用Kotlin编写的,我试图从头到脚将其翻译成Java,但没有预料/考虑样板Java是如何获得的,例如Java中没有接口属性。。。
希望工作示例现在能让它更清楚。它在启动时会创建相同的异常,因此我假设字节码是等效的。

最后我找到了一个解决方案: 这一次在Kotlin,因为Java是太多的pita了

基本上

@OneToOnefetch=FetchType.LAZY @JoinColumnname=id

足够了:

@Entity class Property : WithProperty {

@Id
@GeneratedValue
val id: Long? = null

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "id", insertable=false, updatable =false)
override val property: Property? = null
了解问题的一个良好起点是测试:

测试还揭示了org.hibernate.loader.hql.QueryLoader中的一个bug,如果一个参数在具有上述自引用实体的查询中出现多次,则该bug似乎会变得混乱。
hibernate问题是由@OneToOne关联引起的,可以通过使用上面提到的@ManyToOne来解决。

我不太确定您试图实现什么映射。你想要几张桌子?A和B,或A和B以及子属性。您是否考虑过为WithSubProperty接口使用MappedSuperclass?无论如何,我认为你不想引入一对一的关系,除非你在实体之间有关系,例如一个人与另一个人有亲戚关系。一般来说,在Spring数据中应该可以创建一个共享的基本存储库,以避免重复代码,而无需向映射添加新的关系其中e.subperty=:subperty我链接了一个MWE以使情况更清楚@DarioSeidl由于Subperty只是许多可能的接口之一,MappedSuperclass将无法工作。实际上,我不想要任何关系,这些只是以某种符合JPA的方式允许引用实体实例本身的变通方法。好的,不直接回答您的问题,但我个人发现在JPA/Hibernate中使用太多的继承并不好,很难正确地获得映射,然后更难获得正确的性能。我坚持最多一级的单表继承。在一个层次结构中可以有多个MappedSuperclass,这样可以很好地共享一些公共字段,但确实不能像这样组合多个接口。也许考虑合成,例如嵌入可继承性?
     @ManyToOne(fetch = FetchType.LAZY)
     @JoinColumn(name = "id", insertable=false, updatable =false)
@Entity class Property : WithProperty {

@Id
@GeneratedValue
val id: Long? = null

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "id", insertable=false, updatable =false)
override val property: Property? = null