(PersistentObjectException: отдельный объект передан для сохранения) при выборке данных - PullRequest
0 голосов
/ 05 августа 2020

У меня есть объект A, который имеет набор объектов B

@JsonManagedReference
@OneToMany(cascade = CascadeType.ALL,
           fetch = FetchType.LAZY,
           mappedBy = "a")
private Set<B> b = new HashSet<>();

и в объекте B

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "a_id", nullable = false)
@JsonBackReference
private A a;

Я знаю, как-то мы можем иметь двунаправленная согласованность проблема с неправильными аннотациями при "сохранении" данных ...

У меня нет проблем с сохранением здесь:

  • создание объекта A
  • создание объекта B
  • добавление A к B
  • добавление B в виде списка к A
  • сохранение A

I есть класс DAO для объекта B, который расширяет JpaRepository, даже если я забываю о своих пользовательских методах и вызываю findALl из org.springframework.data.jpa.repository.JpaRepository

Я получаю это исключение!

org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: com.myproject.model.B; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.myproject.model.B
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:280)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:225)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:527)
    at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
    at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:153)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:135)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
    at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke

почему это происходит во время выборки данных?

мой метод модульного тестирования:

@Test
void test(){
    A a = new A();
    B b = new B();
    b.setA(a);
    a.setB(Collections.singleton(b));
    
    aDao.save(a); //works fine
    
    specificService();
}

и мой метод обслуживания: где исключение происходит, когда я звоните bDao.findAll()

@Transactional(rollbackFor = Exception.class)
@Override
public void specificService(){
    A a = aDao.findAll(); //works fine I can see b in a
    B b = bDao.findAll(); //PersistentObjectException
}

У меня это в моем тесте конфигурации ...

spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
...