简体   繁体   English

具有主键(也是外键)的休眠类

[英]Hibernate class with primary key that is also a foreign key

@Entity
@Table(name = "USER_DATA")
public class UserData {
    Entity entity;

    @OneToOne(fetch = FetchType.EAGER)
    @PrimaryKeyJoinColumn(name="PK_FK_ENTITY")
    @Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE})
    public Entity getEntity() {
        return entity;
    }

    public void setEntity(Entity entity) {
        this.entity = entity;
    }
}

Error given is "No identifier specified for entity". 给出的错误是“未为实体指定标识符”。 How can I specify that the entity field is both a primary and a foreign key? 如何指定实体字段既是主键又是外键? Note that there is no class hierarchy for 'UserData' here; 注意,这里没有“ UserData”的类层次结构; it is just a single class. 它只是一个类。 It just so happens that for every 'UserData' there will only be one 'Entity', hence we want to make it both a primary and a foreign key. 碰巧的是,对于每个“ UserData”,只有一个“ Entity”,因此我们要使其成为主键和外键。

We have the same case in our application and it works with this (we annotate the properties not the getters, don't know if there is any difference): 我们的应用程序中有相同的情况,并且可以与此一起工作(我们注释属性而不是获取方法,不知道是否存在任何区别):

public class UserData {
    @Id
    @Column(name="PK_FK_ENTITY")
    private int id;

    @OneToOne
    @JoinColumn(name="PK_FK_ENTITY")
    private Entity entity;
    ...

    public UserData (Entity entity, ...) {

        this.id = entity.getId();
        ...
    }
    ...
} 

Note that in the constructor you should set the id . 请注意,在构造函数中,应设置id Neither the id nor the entity should have a setter as it cannot change. identity都不应该有setter,因为它不能更改。

Also note that we don't use cascade in this case. 另请注意,在这种情况下,我们不使用级联。 We first save the Entity that has a generated id, and then UserData . 我们首先保存具有生成ID的Entity ,然后保存UserData

For one to one bidirectional mapping, just define the @MapsId annotation at the child entity. 对于一对一的双向映射,只需在子实体处定义@MapsId批注。

@Entity
@Table(name = "USER_DATA")
public class UserData {

    @OneToOne(cascade = CascadeType.ALL, mappedBy = "userData", orphanRemoval = true)
    private Entity entity;

    public void setEntity(Entity entity) {
        this.entity = entity;
        if (null != entity && entity.getUserData() != this) {
            entity.setUserData(this);
        }
    }
}

@Entity
@Table(name = "ENTITY")
public class Entity {

    @Id
    private Long id;

    @MapsId
    @OneToOne
    @JoinColumn(name = "user_data_id")
    private UserData userData;

    public void setUserData(UserData userData) {
        this.userData = userData;
        if (null != userData && userData.getEntity() != this) {
            userData.setEntity(this);
        }
    }

}

For one to many unidirectional mapping, You have to use @ElementalCollection and @CollectionTable and annotate Entity.class with @Embeddable annotation 对于一对多单向映射,必须使用@ElementalCollection和@CollectionTable并使用@Embeddable批注对Entity.class进行批注

        @Entity
        @Table(name = "USER_DATA")
        public class UserData {

             @ElementCollection
             @CollectionTable(name = "entity", 
                              joinColumns = @JoinColumn(name = "user_data_id"), 
                              uniqueConstraints = { @UniqueConstraint(columnNames     
= { "user_data_id", "name" }) })
             private final Set<Entity> entities = new LinkedHashSet<>();

             public void setEntities(Set<Entity> entities) {
                 this.entities.clear();
                 if (null != entities) {
                     this.entities.addAll(entities);
                 }
             }
        }

        @Embeddable
        public class Entity {

            @Column
            @Access(AccessType.FIELD)
            private String name;

        }

Kindly refers to the following articles for better understanding: 请参考以下文章,以更好地理解:
1. @OneToOne with shared primary key using @PrimaryKeyJoinColumn http://vard-lokkur.blogspot.my/2011/05/onetoone-with-shared-primary-key.html . 1.使用@PrimaryKeyJoinColumn http://vard-lokkur.blogspot.my/2011/05/onetoone-with-shared-primary-key.html共享主键的@OneToOne。

  1. @OneToOne with shared primary key using @MapsId http://vard-lokkur.blogspot.my/2014/05/onetoone-with-shared-primary-key.html 使用@MapsId使用共享主键的@OneToOne http://vard-lokkur.blogspot.my/2014/05/onetoone-with-shared-primary-key.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM