Spring Data JPA分离实体传递给persist

时间:2015-05-28 02:09:02

标签: java spring hibernate jpa spring-data

我有两个实体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)

0 个答案:

没有答案