JPA/Hibernate セットアップを使用した Spring MVC 3 について、2 つの部分からなる質問があります。
まず、サービス メソッドに @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 をスローする理由を知っていますか?