Hibernate 搜索时出现TransientObject异常';按实体划分';

Hibernate 搜索时出现TransientObject异常';按实体划分';,hibernate,object,jpa,transactional,transient,Hibernate,Object,Jpa,Transactional,Transient,关于使用JPA/Hibernate设置的SpringMVC3,我有一个分为两部分的问题 首先,不管我是否在我的服务方法上添加@Transactional注释,它总是有效的,我觉得这很奇怪。我习惯于在忘记添加@Transactional注释时抱怨它们没有事务的方法 这是我在application-context.xml文件中设置的事务 <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContain

关于使用JPA/Hibernate设置的SpringMVC3,我有一个分为两部分的问题

首先,不管我是否在我的服务方法上添加@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"/>

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

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

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

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;

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