【问题标题】:Spring data Jpa Entity not managed Exception when calling refreshSpring data Jpa Entity not managed 调用刷新时出现异常
【发布时间】:2017-06-14 21:09:23
【问题描述】:

我有一个数据库代码 jar,我在不同的应用程序中使用它来访问数据库。我正在使用spring data jpa。我需要调用 refresh 来检查来自其他应用程序的 db 中的行更改。在这里我如何实现它。 我的StudentRepository界面:

public interface StudentRepository extends JpaRepository<StudentEntity, Integer>, StudentRepositoryCustom {}

我的StudentRespositoryCustom界面

public interface StudentRepositoryCustom {
    void detach(StudentEntity studentEntity);
    void refresh(StudentEntity studentEntity);}

我的StudentRepositoryCustomImpl 班级

public class StudentRepositoryImpl implements StudentRepositoryCustom {

@PersistenceContext
EntityManager entityManager;

@Override
@Transactional
public void detach(StudentEntity studentEntity) {
    entityManager.detach(studentEntity);
}

@Override
@Transactional
public void refresh(StudentEntity studentEntity) {
    entityManager.refresh(studentEntity);
}}

我的测试

@Test
public void refreshTest(){
    StudentEntity studentEntity = studentRepository.findOne(6);
    studentRepository.refresh(studentEntity);
}

但它会抛出这个异常:

org.springframework.dao.InvalidDataAccessApiUsageException: Entity not managed; nested exception is java.lang.IllegalArgumentException: Entity not managed

at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:384)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:492)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)

hibernate-core-5.2.1.finalSessionImpl 类中的这一行返回 null

EntityEntry entry = persistenceContext.getEntry( object );

我认为它应该返回实体。

我的persistence.xml 文件是

<persistence-unit name="testPersitanceUnit" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <class>com.sample.dao.gen.StudentEntity</class>
    <properties>
        <property name="hibernate.archive.autodetection" value="class"/>
        <property name="hibernate.show_sql" value="true"/>
        <property name="hibernate.format_sql" value="true"/>
        <property name="hbm2ddl.auto" value="update"/>
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
        <property name="hibernate.enable_lazy_load_no_trans" value="true" />
    </properties>
</persistence-unit>

我的 spring db 配置文件是

 <jpa:repositories base-package="com.sample.dao.repos"
                  entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="transactionManager"/>

<!-- Enable the component scan (auto wiring etc) for the following package -->
<context:component-scan base-package="com.sample.dao" />

<!-- Make sure the following is specified to enable transaction  -->
<tx:annotation-driven />
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<!--  This defines the entity manager factory with some custom properties -->
<bean id='entityManagerFactory' primary="true" class='org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean'>
    <property name="persistenceUnitName" value="testPersitanceUnit"/>
    <property name='dataSource' ref='dataSource' />
    <property name="packagesToScan" value="com.sample.dao" />
enter code here

【问题讨论】:

  • 您是否忘记用@Service 注释您的StudentRepositoryCustomImpl 或者这只是一个错字?

标签: hibernate jpa spring-data spring-data-jpa


【解决方案1】:

试试

public StudentEntity refresh(StudentEntity studentEntity) {
    StudentEntity managedEntity = entityManager.find(StudentEntity.class, studentEntity.getId());
    entityManager.refresh(managedEntity);
    return managedEntity;
}}

您遇到问题的原因是在您的测试中,您的 studentEntity 在事务 (findOne) 之外传递,因此不再受管理。当它被传递到新事务(刷新)时,它不受管理,因此会引发此错误。

或者,如果原始刷新是所需的行为,您可以将整个测试包装在一个事务中,这应该维护您的测试对象的管理。

【讨论】:

    【解决方案2】:

    在重新定义之前尝试使用合并。

    public void refresh(T entity) {
            this.entityManager.refresh(this.entityManager.merge(entity));
    
      }
    

    【讨论】:

      【解决方案3】:

      实际上这是一个查询问题。该查询正在产生内部连接,因此返回空列表,因此它抛出异常。我更改了映射,以便它可以产生外连接,然后返回一行,它是成功的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-13
        • 2020-10-30
        • 1970-01-01
        • 2013-10-04
        • 1970-01-01
        相关资源
        最近更新 更多