当实体在它们的主键之间有关系时,必须在调用 save() 之前手动分配此类的 id

Shr*_*wat 2 hibernate nhibernate-mapping

我有 2 个实体,我想在它们之间创建一个关系,以便它们共享它们的主键。当我们提交一个实体时,另一个实体也应该使用为第一个实体生成的相同主键提交。

我的第一个实体是用户

@Entity
@Table(name = "ENDUSER")
public class User extends LongIdBase implements IActivatable, IUser {

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    @OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, targetEntity = UserLoginRecord.class)
    @PrimaryKeyJoinColumn(name = "id")
    private UserLoginRecord userLoginRecord;
Run Code Online (Sandbox Code Playgroud)

我的第二个实体是 UserLoginrecord

@Entity
@Table(name = "ENDUSER_TEMP")
public class UserLoginRecord {
    @Id
    @Column(name = "id")
    private Long id;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Column(name = "name")
    private String name;
Run Code Online (Sandbox Code Playgroud)

我希望当我保留用户时,还应该使用与用户相同的主创建 UserLoginRecord 的新行。

但是在尝试坚持的同时,我在下面收到此错误。

ids for this class must be manually assigned before calling save():
Run Code Online (Sandbox Code Playgroud)

Vla*_*cea 8

  1. 您会收到该错误,因为除非指定标识符生成器,​​否则将假定为“已分配”生成器。分配的标识符希望您手动设置 id,因此我认为您对自动生成 id 感兴趣。

    尝试将其更改为:

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    Run Code Online (Sandbox Code Playgroud)
  2. User 应该是 user/userLoginRecord 关联的所有者,因此:

    @Entity
    @Table(name = "ENDUSER")
    public class User extends LongIdBase implements IActivatable, IUser {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "id")
        private Long id;
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        @Column(name = "first_name")
        private String firstName;
    
        @Column(name = "last_name")
        private String lastName;
    
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 我认为一个用户可以有更多的 UserLoginRecords,这意味着一个用户将与 UserLoginRecord 有一对多的关联,而 UserLoginRecord 与一个用户将有一个多对一的关联。

  4. 假设您在 User 和 UserLoginRecord 之间存在一对一的关系

    UserLoginRecord 看起来像:

    @Entity
    @Table(name = "ENDUSER_TEMP")
    public class UserLoginRecord {
    
        @Id 
        @Column(name="userId", unique=true, nullable=false)
        private Long userId;
    
        @OneToOne(cascade = CascadeType.ALL)
        @JoinColumn(name="userId")
        @MapsId
        private User user;
    
    Run Code Online (Sandbox Code Playgroud)
  5. 对于双向一对一关联,用户还可以包含:

        @OneToOne(mappedBy = "user")
        private UserLoginRecord userLoginRecord;
    
    Run Code Online (Sandbox Code Playgroud)

    如果您进行双向关联,请不要忘记在保存之前设置双方:

        user.setUserLoginRecord(userLoginRecord);
        userLoginRecord.setUser(user);
    
    Run Code Online (Sandbox Code Playgroud)

    即使 userLoginRecord.user 端是这个关联的所有者,而 user.userLoginRecord 是“反向”端。