Java org.hibernate.AnnotationException:referencedColumnNames 引用未映射到单个属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21536095/
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
org.hibernate.AnnotationException: referencedColumnNames referencing not mapped to a single property
提问by Superman9999
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.
我在 2 个实体之间映射一对一时遇到了以下异常。第一个实体已嵌入复合键。第二个实体也有嵌入的复合键。这些表是遗留系统的一部分。数据是扁平的,关系没有明确定义。请帮忙。
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;
回答by kostja
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
.
OT:您不应该需要注释targetEntity
上的属性OneToOne
。这已由目标实体的类型定义:MnEditFlag
。您可能targetEntity
只需要 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.
编辑:如果有一个连接列,它只是 PK 的一部分并且您不能更改现有表,也许您可以定义一个包含所有必要列的新连接表。
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.
不幸的是,您无法使用vanilla JPA 定义与部分PK 的关系,也许Hibernate 具有这样的功能,例如一对一查询,但我无法确认。
EDIT2: The join table should contain all PK columns for both entitiesto 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.
EDIT2:连接表应包含两个实体的所有 PK 列才能完全发挥作用。这就是为什么我在示例中为每一侧定义了两个连接列。列数及其名称纯粹是示例性的。
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.
最佳解决方案是更改实体表,以便它们定义实体之间的适当关系。只更改其中一个表并将其定义为拥有方就足够了,但与所有 FK 列一样。这将需要进行迁移工作,因为您需要像上述那样为缺失的 FK 列添加数据。
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.
EDIT3:我推荐的策略是基于你想要拥有完整的 CRUD 功能的 assubmption。如果您只想提取数据以进行显示或报告,则视图非常好。您可以定义所需的列并将整个视图映射到单个实体。但是,由于它是一个视图,您将无法更改数据或迁移它。
回答by Youness
You could use targetEntity on @ManyToOne. The targetEntity should be equal to the parent (probably abstract) class. The temporary solution is here depending to your class hierarchy: https://hibernate.atlassian.net/browse/HHH-4975
您可以在@ManyToOne 上使用targetEntity。targetEntity 应该等于父类(可能是抽象类)。临时解决方案在这里取决于您的类层次结构:https: //hibernate.atlassian.net/browse/HHH-4975