簡體   English   中英

當保存到存儲庫而不使用級聯時,Spring JPA 獲取錯誤分離實體傳遞給單向 OneToOne 關系

[英]Spring JPA get error detached entity passed to persist on unidirectional OneToOne relationship when save to repository without cascade

我有兩個實體:人和病人。 Patient 是 Person 的孩子,它將其主鍵映射到 Person 的主鍵。 這意味着是一個單向的 OneToOne 關系,所以 Person 不知道 Patient。

Person 已經在 PostgreSQL 中持久化了,但是當我嘗試持久化 Patient 時,我收到了這個錯誤:

Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: com.example.clinic.entities.Person; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.example.clinic.entities.Person
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:297) ~[spring-orm-5.3.12.jar:5.3.12]
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:233) ~[spring-orm-5.3.12.jar:5.3.12]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:551) ~[spring-orm-5.3.12.jar:5.3.12]
    at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61) ~[spring-tx-5.3.12.jar:5.3.12]
    at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242) ~[spring-tx-5.3.12.jar:5.3.12]
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:152) ~[spring-tx-5.3.12.jar:5.3.12]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.12.jar:5.3.12]
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:174) ~[spring-data-jpa-2.5.6.jar:2.5.6]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.12.jar:5.3.12]
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-5.3.12.jar:5.3.12]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.12.jar:5.3.12]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.12.jar:5.3.12]
    at jdk.proxy2/jdk.proxy2.$Proxy89.save(Unknown Source) ~[na:na]
    at com.example.clinic.ClinicApplication.lambda$demo$0(ClinicApplication.java:43) ~[classes/:na]
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:791) ~[spring-boot-2.5.6.jar:2.5.6]
    ... 5 common frames omitted

這是我的 Person 類的片段

@Entity
@Table(name = "person")
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "user_id")
    private Long userId;

    @Column(name = "first_name")
    private String firstName;
    @Column(name = "last_name")
    private String lastName;

    private String email;

    @Column(name = "created_on")
    private Date createdOn;
}

患者類:

@Entity
@Table(name = "patient")
public class Patient {
    @Id
    private Long id;

    @OneToOne
    @MapsId
    @JoinColumn(name = "user_id")
    private Person person;

    @Column(name = "last_visit")
    private Date lastVisit;
}

患者回購:

@Repository
public interface PatientRepository extends JpaRepository<Patient, Long> {
    Patient findById(long id);

    @Query("SELECT p FROM Patient p WHERE p.person.email = ?1")
    Patient findByEmail(String email);
}

編輯:

這是我試圖拯救病人的地方

Person person = new Person("patient", "pat", "patient@email.com");
personRepository.save(person);
Patient patient1 = new Patient(person);
patientRepository.save(patient1); // <---- here is the exception happen

任何的想法?

問題是該人在保存后分離,因為您顯然沒有外部事務來管理實體。

所以你必須添加一個外部事務才能在一個事務中包含它:

@Transactional
public void yourSaveMethod() {
    Person person = new Person("patient", "pat", "patient@email.com");
    personRepository.save(person);
    Patient patient1 = new Patient(person);
    patientRepository.save(patient1);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM