【问题标题】:TransientObjectException when searching 'by entity'搜索“按实体”时出现 TransientObjectException
【发布时间】:2012-09-19 21:43:51
【问题描述】:

我有一个关于我的 Spring MVC 3 和 JPA/Hibernate 设置的两部分问题。

首先,我是否在我的服务方法上添加@Transactional 注释并不重要,它总是有效,我觉得这很奇怪。当我忘记添加 @Transactional 注释时,我习惯于抱怨他们没有事务的方法。

这是我在 application-context.xml 文件中的交易设置。

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" p:dataSource-ref="dataSource"/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" p:entityManagerFactory-ref="entityManagerFactory"/>
<tx:annotation-driven transaction-manager="transactionManager"/>

其次,当我使用服务方法获取类别时,我会得到一个类别对象。据我所知,它不是代理,而是一个真实的对象,设置了大多数属性。当我使用该类别搜索课程时,它出错了:

public List<Course> findCourses(Category category) {
    Query queryGood = entityManager.createQuery("select c from Course c join fetch c.company where c.category.id = :categoryId");
    Query queryBad = entityManager.createQuery("from Course c where c.category = :category");

    queryGood.setParameter("categoryId", category.getId());
    queryBad.setParameter("category", category);

    List<Category> categoriesGood = queryGood.getResultList(); // THIS WORKS!
    List<Category> categoriesBad = queryBad.getResultList(); // THIS THROWS AN EXCEPTION
    return null;

}

这个 queryBad 的执行导致以下异常:

org.springframework.dao.InvalidDataAccessApiUsageException:
org.hibernate.TransientObjectException: object references an unsaved 
transient instance - save the transient instance before flushing:
nl.myapp.domain.Category; nested exception  is java.lang.IllegalStateException:
org.hibernate.TransientObjectException: object references an unsaved transient instance
- save the transient instance before flushing: nl.myapp.domain.Category
org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:298)

您知道为什么 (1) 我的应用程序在不使用 @Transactional 注释的情况下获取数据,以及 2) 为什么 Hibernate 会抛出这个 TransientObjectException 吗?

【问题讨论】:

    标签: hibernate object jpa transactional transient


    【解决方案1】:

    别管这个了。 Hibernate 正在做出应有的反应。我使用了一个@Transactional 服务方法来获取Category,并将该Category 用作另一个@Transactional 服务方法的输入。当您这样做时,Hibernate 会为新的第二个服务方法调用创建一个新会话(因为它有自己的 Transactional 注释),并且无法在新会话中找到 Category。这就是它抛出 TransientObject 异常的原因。我现在只是使用 Category 的 id 作为 seciond 服务方法调用的参数,这样就可以了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-06
      • 2016-02-07
      • 2020-08-29
      • 2022-12-08
      • 2019-01-04
      • 2015-01-18
      相关资源
      最近更新 更多