我有两个实体User和 ContactDetail 。一个用户可以拥有多个 ContactDetails 。
还有一个 UserService 组件,负责持久保存新用户。它检查ContactDetail是否存在,如果存在,则将该实体附加到新的User实体,然后尝试保存它。
User.java
public class User extends Base implements Resource<UUID>, UserDetails {
private static final long serialVersionUID = 1L;
@NotBlank
private String username;
@NotBlank
@Column(name = "first_name")
private String firstName;
@NotBlank
@Column(name = "last_name")
private String lastName;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "user", cascade = { CascadeType.PERSIST, CascadeType.MERGE })
@Fetch(org.hibernate.annotations.FetchMode.SELECT)
private List<ContactDetail> contactdetails;
@Transient
public String email;
//bidirectional consistency
public void addContactDetail(ContactDetail contactDetail){
if(this.contactdetails == null){
this.contactdetails = new ArrayList<ContactDetail>();
}
if(!this.getContactDetails().contains(contactDetail)){
this.getContactDetails().add(contactDetail);
contactDetail.addUser(this);
}
}
ContactDetail.java
public class ContactDetail extends Base implements Resource<UUID> {
@Column(name = "name")
private String name;
@Column(name = "type")
@Enumerated(EnumType.STRING)
private ContactType type;
@Column(name = "value", unique = true)
private String value;
@Column(name = "verified")
private boolean isVerified;
@Column(name = "created_date")
private Date createdDate;
@Column(name = "expired")
boolean isExpired;
@ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE })
@JoinColumn(name = "user_id", referencedColumnName = "id")
protected User user;
//bidirectional consistency
public void addUser(User user) {
if (this.getUser() == null) {
this.setUser(user);
user.addContactDetail(this);
}
}
UserService.java
@RestController
@RequestMapping("/api/v1/users")
public class UserService extends AbstractRestResource<User, UUID, User.UserWrapper> {
@Transactional(TxType.REQUIRES_NEW)
protected User save(User e) {
attachedContact(e);
User savedUser = repository().save(e);
return savedUser;
}
private void attachedContact(User u) {
ContactDetail contactDetail = contactDetailsRepository.findByTypeAndValue(ContactType.PRIMARY_EMAIL, u.getEmail());
if (contactDetail == null) {
contactDetail = new ContactDetail(u.getFirstName(), ContactType.PRIMARY_EMAIL, u.getEmail());
}
u.addContactDetail(contactDetail);
}
如果ContactDetail实体不存在,则User和ContactDetail实体都按预期保存。
如果ContactDetail实体存在,我收到以下错误:
org.hibernate.PersistentObjectException: detached entity passed to persist: com.test.ContactDetail
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:139)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:801)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:794)
at org.hibernate.jpa.event.internal.core.JpaPersistEventListener$1.cascade(JpaPersistEventListener.java:97)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:350)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:293)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)