Java Spring数据JPA分离实体传递给persist

Java Spring数据JPA分离实体传递给persist,java,spring,hibernate,jpa,spring-data,Java,Spring,Hibernate,Jpa,Spring Data,我有两个实体用户和联系人详细信息。一个用户可以有多个联系人详细信息 还有一个UserService组件,负责持久化新用户。它检查ContactDetail是否存在,是否存在,并将该实体附加到新的用户实体,然后尝试保存它 User.java public class User extends Base implements Resource<UUID>, UserDetails { private static final long serialVersionUID = 1L

我有两个实体用户和联系人详细信息。一个用户可以有多个联系人详细信息

还有一个UserService组件,负责持久化新用户。它检查ContactDetail是否存在,是否存在,并将该实体附加到新的用户实体,然后尝试保存它

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);
    }
}

看起来您的事务已中断,当您在一个事务中加载、在另一个事务中更改和保存时,会发生这种情况。验证是否正在使用TransactionSynchronizationManager的事务中运行save(User)Y Nadir您是对的。TransactionSynchronizationManager.isActualTransactionActive()返回false而不是true。save(user)方法顶部的批注:@Transactional(TxType.REQUIRES_NEW)未启动事务。我该如何解决这个问题?感谢这取决于您设置交易的方式。请看(在您的情况下,我想它将是@EnableTransactionManagement),感谢最低点的问题是UserService实际上是一个控制器。声明性事务需要一个服务类来启动事务。因此,我创建了一个用户服务类,将它注入到我的控制器中,并且它工作了。
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);
    }
}
@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);
}
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)