双向@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
)。
我有以下实体:
@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
)。