没有主键或连接表的休眠多对一关系 [英] Hibernate Many-To-One Relationship without Primary Key or Join Table

查看:133
本文介绍了没有主键或连接表的休眠多对一关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题



我想先说我意识到数据库结构是非常残酷的,但在这个时候我无法改变它。



这就是说,我需要在Hibernate(4.2.1)中创建一个一对多,双向的关系,它不涉及主键(只有一个唯一的键关系的父侧)并且没有连接表。代表这种关系的外键是从孩子到父母的后退指针(见下文)。我搜索并尝试了各种不同的注释配置,但没有运气。是我要求的可能吗?

数据库



GLOBAL_PART

  CREATE TABLEGLOBAL_PART(
GLOBAL_PART_IDNUMBER NOT NULL,
RELEASESNUMBER,
CONSTRAINTGLOBAL_PART_PKPRIMARY KEY(GLOBAL_PART_ID),
CONSTRAINTGLOBAL_PART_RELEASES_UKUNIQUE(RELEASES)
);

PART_RELEASE
< pre $ class =lang-sql prettyprint-override> CREATE TABLEPART_RELEASE(
PART_RELEASE_IDNUMBER NOT NULL,
COLLECTION_IDNUMBER,
CONSTRAINT PART_RELEASE_PKPRIMARY KEY(PART_RELEASE_ID),
CONSTRAINTGLOBAL_PART_RELEASE_FKFOREIGN KEY(COLLECTION_ID)
REFERENCESGLOBAL_PART(RELEASES)DELETE CASCADE ENABLE
);

参考:

  PART_RELEASE GLOBAL_PART 
------------------- ------------
PART_RELEASE_ID(PK) GLOBAL_PART_ID(PK)
COLLECTION_ID -------------> RELEASES(英国)



Java



GlobalPart.java
$ b

  @Entity 
@Table(name =GLOBAL_PART)
@SequenceGenerator(name =SEQUENCE_GENERATOR,sequenceName =GLOBAL_PART_SEQ)
public class GlobalPart extends ModelBase implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@Column(name =GLOBAL_PART_ID,unique = true,nullable = false)
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator =SEQUENCE_GENERATOR)
private long globalPartId;

@OneToMany(fetch = FetchType.EAGER)
@JoinColumn(name =COLLECTIONGID)
private Set< PartRelease>排放;

public Long getGlobalPartId(){
return globalPartId;
}

public void setGlobalPartId(Long globalPartId){
this.globalPartId = globalPartId;
}

public Set< PartRelease> getReleases(){
返回版本;
}

public void setReleases(Set< PartRelease> releases){
this.releases = releases;
}

}

PartRelease.java


$ b

@Entity
@Table(name =PART_RELEASE)
@SequenceGenerator(name =SEQUENCE_GENERATOR,sequenceName =PART_RELEASE_SEQ)
public class PartRelease extends ModelBase implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@Column(name =PART_RELEASE_ID,unique = true,nullable = false)
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator =SEQUENCE_GENERATOR)
private String partReleaseId;

@ManyToOne
@JoinColumn(name =RELEASES)
private GlobalPart globalPart;

public String getPartReleaseId(){
return partReleaseId;
}

public void setPartReleaseId(String partReleaseId){
this.partReleaseId = partReleaseId;
}

public GlobalPart getGlobalPart(){
return globalPart;
}

public void setGlobalPart(GlobalPart globalPart){
this.globalPart = globalPart;
}

}

任何帮助将不胜感激! !

解决方案

首先,在双向关联中,始终存在一个所有者侧,它定义了映射,标记为存在 mappedBy 属性。



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



此外,默认情况下,连接列会引用它引用的实体的ID。由于它不是你想要的,你必须指定引用的列名。



当然,RELEASES列必须映射:

  public class GlobalPart extends ModelBase implements Serializable {

@OneToMany(fetch = FetchType.EAGER,mappedBy =globalPart)
私人设置< PartRelease> partReleases;

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

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

$ b

关联在文档。你应该阅读它。


Problem

I would like to start by saying that I realize the database structure is atrocious, but I cannot change it at this point in time.

That being said, I have the need to create a one-to-many, bi-directional relationship in Hibernate (4.2.1) which involves no primary keys (only a unique key on the "parent" side of the relationship) and no join tables. The foreign key representing this relationship is a backpointer from the "child" to the "parent" (see below). I have searched and tried various different annotation configurations with no luck. Is what I'm asking for possible?

Database

GLOBAL_PART

CREATE TABLE "GLOBAL_PART" (    
    "GLOBAL_PART_ID" NUMBER NOT NULL,
    "RELEASES" NUMBER,
    CONSTRAINT "GLOBAL_PART_PK" PRIMARY KEY ("GLOBAL_PART_ID"),
    CONSTRAINT "GLOBAL_PART_RELEASES_UK" UNIQUE ("RELEASES")
);

PART_RELEASE

CREATE TABLE "PART_RELEASE" (
    "PART_RELEASE_ID" NUMBER NOT NULL,
    "COLLECTION_ID" NUMBER,
    CONSTRAINT "PART_RELEASE_PK" PRIMARY KEY ("PART_RELEASE_ID"),
    CONSTRAINT "GLOBAL_PART_RELEASE_FK" FOREIGN KEY ("COLLECTION_ID")
        REFERENCES "GLOBAL_PART" ("RELEASES") ON DELETE CASCADE ENABLE
);

Reference:

PART_RELEASE                 GLOBAL_PART
-------------------          ------------
PART_RELEASE_ID (PK)         GLOBAL_PART_ID (PK)
COLLECTION_ID -------------> RELEASES (UK)

Java

GlobalPart.java

@Entity
@Table(name = "GLOBAL_PART")
@SequenceGenerator(name = "SEQUENCE_GENERATOR", sequenceName = "GLOBAL_PART_SEQ")
public class GlobalPart extends ModelBase implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "GLOBAL_PART_ID", unique = true, nullable = false)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQUENCE_GENERATOR")
    private Long globalPartId;

    @OneToMany(fetch = FetchType.EAGER)
    @JoinColumn(name = "COLLECTIONGID")
    private Set<PartRelease> releases;

    public Long getGlobalPartId() {
        return globalPartId;
    }

    public void setGlobalPartId(Long globalPartId) {
        this.globalPartId = globalPartId;
    }

    public Set<PartRelease> getReleases() {
        return releases;
    }

    public void setReleases(Set<PartRelease> releases) {
        this.releases = releases;
    }

}

PartRelease.java

@Entity
@Table(name = "PART_RELEASE")
@SequenceGenerator(name = "SEQUENCE_GENERATOR", sequenceName = "PART_RELEASE_SEQ")
public class PartRelease extends ModelBase implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "PART_RELEASE_ID", unique = true, nullable = false)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQUENCE_GENERATOR")
    private String partReleaseId;

    @ManyToOne
    @JoinColumn(name = "RELEASES")
    private GlobalPart globalPart;

    public String getPartReleaseId() {
        return partReleaseId;
    }

    public void setPartReleaseId(String partReleaseId) {
        this.partReleaseId = partReleaseId;
    }

    public GlobalPart getGlobalPart() {
        return globalPart;
    }

    public void setGlobalPart(GlobalPart globalPart) {
        this.globalPart = globalPart;
    }

}

Any help would be greatly appreciated!!

解决方案

First of all, in a bidirectional association, there is always an owner side, which defines the mapping, and an inverse side, marked by the presence of the mappedBy attribute.

In a OneToMany association, the owner side is always the many side (PartRelease in your case).

Moreover, a join column, by default, references the ID of the entity it references. Since it's not what you want, you have to specify the referenced column name.

And of course, the RELEASES column must be mapped:

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;

}

Associations are well described in the documentation. You should read it.

这篇关于没有主键或连接表的休眠多对一关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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