Java 休眠没有主键或联接表的多对一关系 问题

Java 休眠没有主键或联接表的多对一关系 问题,java,hibernate,one-to-many,Java,Hibernate,One To Many,我想首先说,我意识到数据库结构非常糟糕,但我现在无法改变它 也就是说,我需要在Hibernate(4.2.1)中创建一个一对多的双向关系,该关系不涉及主键(在关系的“父”端只有一个唯一键),也不涉及联接表。表示这种关系的外键是从“子”到“父”的反向指针(见下文)。我搜索并尝试了各种不同的注释配置,但没有成功。我所要求的可能吗 数据库 全球部分 创建表“全局零件”( “全局零件ID”编号不为空, “发布”编号, 约束“全局部分主键”(“全局部分ID”), 约束“全球发布”唯一(“发布”) );

我想首先说,我意识到数据库结构非常糟糕,但我现在无法改变它

也就是说,我需要在Hibernate(4.2.1)中创建一个一对多的双向关系,该关系不涉及主键(在关系的“父”端只有一个唯一键),也不涉及联接表。表示这种关系的外键是从“子”到“父”的反向指针(见下文)。我搜索并尝试了各种不同的注释配置,但没有成功。我所要求的可能吗

数据库 全球部分

创建表“全局零件”(
“全局零件ID”编号不为空,
“发布”编号,
约束“全局部分主键”(“全局部分ID”),
约束“全球发布”唯一(“发布”)
);
零件发布

创建表“零件发布”(
“零件发布ID”编号不为空,
“集合ID”编号,
约束“PART_RELEASE_PK”主键(“PART_RELEASE_ID”),
约束“全局\部分\释放\ FK”外键(“集合\ ID”)
删除级联启用时参考“全局_部分”(“发布”)
);
参考:

PART_RELEASE                 GLOBAL_PART
-------------------          ------------
PART_RELEASE_ID (PK)         GLOBAL_PART_ID (PK)
COLLECTION_ID -------------> RELEASES (UK)
JAVA GlobalPart.java

@实体
@表(name=“全局_部分”)
@SequenceGenerator(name=“序列生成器”,sequenceName=“全局部分”)
公共类GlobalPart扩展ModelBase实现可序列化{
私有静态最终长serialVersionUID=1L;
@身份证
@列(name=“GLOBAL\u PART\u ID”,unique=true,nullable=false)
@GeneratedValue(策略=GenerationType.SEQUENCE,generator=“序列\生成器”)
私人长全局部分;
@OneToMany(fetch=FetchType.EAGER)
@JoinColumn(name=“COLLECTIONGID”)
专用集发布;
公共长getGlobalPartId(){
返回全局部分;
}
公共无效设置全局部分(长全局部分){
this.globalPartId=globalPartId;
}
公共集getReleases(){
退货放行;
}
公共无效集合释放(集合释放){
this.releases=释放;
}
}
PartRelease.java

@实体
@表(name=“零件发布”)
@SequenceGenerator(name=“序列生成器”,sequenceName=“零件发布顺序”)
公共类PartRelease扩展ModelBase实现可序列化{
私有静态最终长serialVersionUID=1L;
@身份证
@列(name=“PART\u RELEASE\u ID”,unique=true,nullable=false)
@GeneratedValue(策略=GenerationType.SEQUENCE,generator=“序列\生成器”)
私有字符串partReleaseId;
@许多酮
@JoinColumn(name=“RELEASES”)
私人环球艺术环球艺术;
公共字符串getPartReleaseId(){
返回partReleaseId;
}
public void setPartReleaseId(字符串partReleaseId){
this.partReleaseId=partReleaseId;
}
公共GlobalPart getGlobalPart(){
回归环球艺术;
}
公共无效设置GlobalPart(GlobalPart GlobalPart){
this.globalPart=globalPart;
}
}

任何帮助都将不胜感激

首先,在双向关联中,始终存在一个定义映射的所有者侧,以及一个反向侧,其标记为存在
mappedBy
属性

在OneToMany关联中,所有者方始终是多方(在您的情况下是PartRelease)

此外,默认情况下,联接列引用它引用的实体的ID。因为这不是您想要的,所以必须指定引用的列名

当然,必须映射“发布”列:

public class GlobalPart extends ModelBase implements Serializable {

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "globalPart")
    private Set<PartRelease> partReleases;

    @Column(name = "RELEASES")
    private Long releasesNumber;
}

public class PartRelease extends ModelBase implements Serializable {
    @ManyToOne
    @JoinColumn(name = "COLLECTION_ID", referencedColumnName = "RELEASES")
    private GlobalPart globalPart;

}
公共类GlobalPart扩展ModelBase实现可序列化{
@OneToMany(fetch=FetchType.EAGER,mappedBy=“globalPart”)
私人设置部分释放;
@列(name=“RELEASES”)
私人长期释放成员;
}
公共类PartRelease扩展ModelBase实现可序列化{
@许多酮
@JoinColumn(name=“COLLECTION\u ID”,referencedColumnName=“RELEASES”)
私人环球艺术环球艺术;
}

关联在中有很好的描述。您应该阅读它。

每当您需要在父端使用非主键列映射时,您必须使用
@JoinColumn
注释的
referencedColumnName
属性

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(
    name = "RELEASES", 
    referencedColumnName = "COLLECTIONGID"
)

我对
@manytone
使用了
FetchType.LAZY
,因为默认情况下使用了抓取,这对性能非常不利。

完美!非常感谢你!我本来是这样做的,但是我缺少映射到
RELEASES
列的
releaseNumber
属性。最终我说服自己我做错了(通过误读MappingException),并采用了问题中提到的方法。再次感谢!请假设我在一个双向的onetomany协会中使用了最佳实践。如您所说,使用了非主键联接列。现在我想通过id获取一个简单的manytone实体。但是hibernate日志在另一侧显示一个额外的select实体,其中带有where on referencedColumnName。为什么?当我使用主键联接列时,这个额外的选择不存在。