双向@OneToOne 级联问题 JPA/Hibernate/Spring-Data

Bidirectional @OneToOne cascade issue JPA/Hibernate/Spring-Data

我有以下实体:

@Entity
public class User implements Serializable {

   private String username;

   @OneToOne( optional = false, mappedBy = "user", orphanRemoval = true, fetch = FetchType.LAZY, cascade = CascadeType.ALL )
   private BankAccount bankAccount;
   //.....
}

并且:

@Entity
public class BankAccount implements Serializable {

    @OneToOne( optional = false, fetch = FetchType.LAZY )
    @JoinColumn( name = "user", unique = true, referencedColumnName = "username" )
    private User user;
    //...
}

对我来说,我希望我是对的,User 实体是父实体,因此我可以将其操作级联到 BankAccount。但是当我尝试这个时:

User user = new User();
user.setBankAccount(new BanckAccount());
userRepository.save(user);

我有这个例外:

org.hibernate.PropertyValueException: not-null property references a null or transient value : org.company.models.User.bankAccount

保存级联未传播,我必须先保存 bankAccount,然后再将其设置给用户。我错过了什么,我应该审查我的协会吗? 谢谢

您在错误的关系端指定了 mappedBy。它应该在反向(非拥有)侧指定。由于您希望用户保存帐户,因此用户必须是所有者。

您的 mappedBy 应该在您希望首先保存的子实体中。所以这里mapped by应该在BankAccount你应该在父实体中使用@JoinColumn,这样子实体的外键可以存储在父实体table中。例如:

@Entity
public class User implements Serializable {

   private String username;

   @OneToOne( optional = false, orphanRemoval = true, fetch = FetchType.LAZY, cascade = CascadeType.ALL )
   @JoinColumn(name = "bank_account_id")
   private BankAccount bankAccount;
   //.....
}

BankAccount中:

@Entity
public class BankAccount implements Serializable {

    @OneToOne( optional = false, fetch = FetchType.LAZY, mappedBy = "bankAccount")
    private User user;
    //...
}

查看类似示例here.

为了完成这个 post,从子级到父级的级联操作在这种情况下起作用 @OneToOne(optional=false,mappedBy=...)。如果我们在子端设置 optional=false,级联似乎有效(至少 Cascade.PERSIST)。