【问题标题】:Hibernate Zero to One unidirectional with reverse primary foreign key cascade休眠零到一单向反向主外键级联
【发布时间】:2017-06-23 09:25:45
【问题描述】:

我在 Spring Boot 中遇到了 Hibernate 问题。

我们有 2 个表,usersuser_info,具有零到一(因此可以为空的一对一)关系。 user_info 有一个指向 users.user_id 的主外键:

CREATE TABLE `users` (
  `user_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `username` varchar(45) NOT NULL,
  ...
  PRIMARY KEY (`user_id`)
) 

CREATE TABLE `users_info` (
  `user_id` bigint(20) NOT NULL,
  `name` varchar(45) NOT NULL,
  `surname` varchar(45) NOT NULL,
  `mail` varchar(45) DEFAULT NULL,
  ...
  PRIMARY KEY (`user_id`),
  KEY `fk_user_id_idx` (`user_id`),
  CONSTRAINT `fk_user_id` FOREIGN KEY (`user_id`) 
    REFERENCES `users` (`user_id`) 
    ON DELETE NO ACTION ON UPDATE NO ACTION
)

这些是模型:

@Entity
@Table(name = "users")
public class User implements UserDetails, Buildable<User.Builder> {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "user_id")
    private Long id;

    private String username;

    @Nullable
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="user_id")
    @JsonUnwrapped
    private UserInfo userInfo;


    ...
}


@Entity
@Table(name = "users_info")
public class UserInfo {
    @Id
    @Column(name = "user_id")
    private Long id;

    @Nullable
    private String name;

    @Nullable
    private String surname;

    ...
}

当我使用此配置运行 Spring 应用程序时,它会抛出一个错误:

org.hibernate.id.IdentifierGenerationException ids for this class must be manually assigned before calling save()

如果来自 User 实体的 UserInfo 实例不为空,我们如何级联持久化?

感谢您的回答!

【问题讨论】:

  • 显示你的保存方法
  • 我们使用的是自动生成的 JpaRepository 实现,以及实体管理器的 persist 方法。

标签: java mysql spring hibernate jpa


【解决方案1】:

您的映射是向后的。 UserInfo 应该引用它所附加的用户,并且是关联的所有者。而且你也应该说它的ID也是用户的外键。

@Entity
@Table(name = "users")
public class User implements UserDetails, Buildable<User.Builder> {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "user_id")
    private Long id;

    private String username;

    @Nullable
    @OneToOne(mappedBy="user", cascade = CascadeType.ALL)
    @JsonUnwrapped
    private UserInfo userInfo;


    ...
}


@Entity
@Table(name = "users_info")
public class UserInfo {
    @Id
    @Column(name = "user_id")
    private Long id;

    @Nullable
    private String name;

    @Nullable
    private String surname;

    @OneToOne
    @MapsId
    private User user;
    ...

【讨论】:

  • 尝试了您的解决方案,但它抛出:org.springframework.orm.jpa.JpaSystemException: attempted to assign id from null one-to-one property [x.y.model.UserInfo.user]; nested exception is org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property [x.y.model.UserInfo.user]
  • 你需要分配关联的双方(尤其是所有者方):userInfo.setUser(user)。
  • 您的答案是正确的,但我还必须在 UserInfo.user 上添加 @JoinColumn(name="user_id") 注释。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-23
  • 2020-10-30
  • 2012-09-21
  • 2015-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多