org.hibernate.AnnotationException:引用未映射到单个属性的referencedColumnNames [英] org.hibernate.AnnotationException: referencedColumnNames referencing not mapped to a single property

查看:704
本文介绍了org.hibernate.AnnotationException:引用未映射到单个属性的referencedColumnNames的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在两个实体之间映射一对一时遇到了下面的异常。第一个实体具有嵌入式组合键。第二个实体也有嵌入式组合键。这些表格是遗留系统的一部分。数据持平,关系不明确。请帮助



 产生的原因:org.hibernate.AnnotationException:referencedColumnNames(FLAG_NAME)net.javabeat.spring.model.ReferralsM的.mnEditFlag引用net.javabeat.spring.model.MnEditFlag未映射到org.hibernate.cfg.BinderHelper.createSyntheticPropertyReference(BinderHelper.java:205)
org.hibernate.cfg中的单个属性
。 ToOneFkSecondPass.doSecondPass(ToOneFkSecondPass.java:116)
在org.hibernate.cfg.Configuration.processEndOfQueue(Configuration.java:1515)
在org.hibernate.cfg.Configuration.processFkSecondPassInOrder(Configuration.java:在org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1358 1440)

在org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1727)
。在组织.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1778)
在org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(的LocalSessionFactory Builder.java:247)
at org.springframework.orm.hibernate4.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:373)
at org.springframework.orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java: 358)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1571)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java: 1509)
... 34 more

这是我在主要的一对一映射/父表

  @OneToOne(targetEntity = MnEditFlag.class,取= FetchType.LAZY)
@JoinColumn( name =REFFLG,referencedColumnName =FLAG_NAME,insertable = false,updatable = false)
MnEditFlag mnEditFlag;


解决方案

问题的原因在于您试图使用单个连接列,而引用实体的标识由多个列定义。您只需定义所有需要加入colums,你是好去:

  @JoinColumns({
@ JoinColumn(name =REFFLG,referencedColumnName =FLAG_NAME),
@JoinColumn(name =OTHER_KEY,referencedColumnName =SOME_OTHER_NAME))
...
})
MnEditFlag mnEditFlag;

OT:您不需要 targetEntity 属性放在 OneToOne 注释中。这已经由目标实体的类型定义: MnEditFlag 。您可能需要 targetEntity 才能为非类型化集合



编辑:如果有一个单一的连接列,它只是PK的一部分,并且你不能改变现有的表,也许你可以定义一个新的连接表和所有必要的列。



然后,你定义联接表,以用于关系:

  @JoinTable(名称= ReferralsM_MnEditFlag,
joinColumn = {
@JoinColumn(name =REFERRALS_ID1,referencedColumnName =ID1),
@JoinColumn(name =REFERRALS_ID2,referencedColumnName =ID2)
} ,inverseJoinColumns = {
@JoinColumn(name =REFFLG,referencedColumnName =FLAG_NAME),
@JoinColumn(name =REFFLG2,referencedColumnName =FLAG_NAME2)
})
MnEditFlag mnEditFlag;

您必须以编程方式或通过查询将数据迁移到新的连接表。



不幸的是,你不能用vanilla JPA定义一个与部分PK的关系,或许Hibernate有这样的功能,比如一对一查询,但我无法确认它。

编辑2:连接表应包含两个实体的所有PK列以充分发挥作用。这就是为什么我在我的例子中为每一边定义了两个连接列的原因。列数和名称是纯粹的示例。



只提取表中已有的一个连接列不会添加任何值。



最佳解决方案是更改实体表,以便它们定义实体之间的适当关系。仅更改其中一个表并将其定义为拥有方,就足够了,但使用所有FK列即可。这需要迁移工作,因为您需要为上述缺失的FK列添加数据。



编辑3:我推荐的策略基于assubmption你想拥有完整的CRUD功能。如果您只想提取数据以供显示或报告,则视图完全正确。您可以定义所需的列并将整个视图映射到单个实体。但是,因为它是一个视图,您将无法更改或迁移数据。

I ran into the below exception while mapping a one-to-one between 2 entities. The 1 first entity has embedded composite key. The second entity also has embedded composite key. The tables are part of legacy system. Data is flat, relations are not well defined. Please help.

Caused by: org.hibernate.AnnotationException: referencedColumnNames(FLAG_NAME) of net.javabeat.spring.model.ReferralsM.mnEditFlag referencing net.javabeat.spring.model.MnEditFlag not mapped to a single property
    at org.hibernate.cfg.BinderHelper.createSyntheticPropertyReference(BinderHelper.java:205)
    at org.hibernate.cfg.ToOneFkSecondPass.doSecondPass(ToOneFkSecondPass.java:116)
    at org.hibernate.cfg.Configuration.processEndOfQueue(Configuration.java:1515)
    at org.hibernate.cfg.Configuration.processFkSecondPassInOrder(Configuration.java:1440)
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1358)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1727)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1778)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:247)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:373)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:358)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1571)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1509)
    ... 34 more

Here is my one to one mapping in the main/parent table.

@OneToOne(targetEntity = MnEditFlag.class, fetch = FetchType.LAZY)
@JoinColumn(name = "REFFLG", referencedColumnName = "FLAG_NAME", insertable = false,     updatable = false)
MnEditFlag mnEditFlag;

解决方案

The cause of the issue is that you are trying to use a single join column, while the identity of the referenced entity is defined by multiple columns. You simply have to define all the needed join colums and you are good to go:

@JoinColumns({
   @JoinColumn(name = "REFFLG", referencedColumnName = "FLAG_NAME"),
   @JoinColumn(name = "OTHER_KEY", referencedColumnName = "SOME_OTHER_NAME"))
   ...
})
MnEditFlag mnEditFlag;

OT: you should not need the targetEntity attribute on the OneToOne annotation. This is already defined by the type of the target entity: MnEditFlag. You probably need targetEntity only for untyped Collections.

EDIT: If there is a single join column, which is only part of the PK and you cannot change the existing tables, perhaps you can define a new join table with all necessary columns.

Then you define the join table to be used for the relationship:

@JoinTable(name="ReferralsM_MnEditFlag",
  joinColumns={
    @JoinColumn(name="REFERRALS_ID1", referencedColumnName="ID1"),
    @JoinColumn(name="REFERRALS_ID2", referencedColumnName="ID2")
  }, inverseJoinColumns={
    @JoinColumn(name="REFFLG", referencedColumnName="FLAG_NAME"),
    @JoinColumn(name="REFFLG2", referencedColumnName="FLAG_NAME2")
})  
MnEditFlag mnEditFlag;  

You would have to migrate the data to the new join table programmatically or by queries.

Unfortunately you cannot define a relationship with a partial PK with vanilla JPA, perhaps Hibernate has such a feature, like one-to-one by query, but I cannot confirm it.

EDIT2: The join table should contain all PK columns for both entities to be fully functional. That is why I have defined two join columns for each side in my example. The number of columns and their names are purely exemplary.

Extracting only the one join column you already have in your table would not add any value.

The optimal solution would be to change the entity tables so they define a proper relationship between the entities. It is sufficient to change only one of the tables and define it as the owning side as you did, but with all FK columns. This would require a migration effort, since you would need to add the data for the missing FK columns like described above.

EDIT3: The strategies I recommended were based on the assubmption that you want to have complete CRUD functionality. If you just want to pull the data for display or reporting, a view is perfectly fine. You can define the columns you need and map the whole view to a single entity. However, as it is a view, you will not be able to change the data or migrate it.

这篇关于org.hibernate.AnnotationException:引用未映射到单个属性的referencedColumnNames的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆