私は、注文とアイテムの典型的なエンティティの関連付けを得ました。注文のみを読むことを可能にするために、設定される項目はデフォルトのFetchType.LAZYです。 2番目のレベルとクエリキャッシュが有効です。関連項目を含む注文を読むには、私はJPQLクエリを使用しています。クエリとエンティティはEHCacheによってキャッシュされます。しかし、アイテムにアクセスする際の2回目の呼び出しでは、アイテムが初期化されていない(キャッシュから復元されていない)ため、LazyInitializationExceptionがスローされました。どうして?この要件を実装する最良の方法は何ですか?Hibernateキャッシングとレイジーロードアソシエーション
注文:
@Entity
@Cacheable
@NamedQueries({
@NamedQuery(name = Order.NQ_FIND_BY_ID_FETCH_ITEMS, query = "SELECT DISTINCT o FROM Order o JOIN FETCH o.items WHERE o.id = :id")
})
@Table(...)
public class Order extends ... {
...
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
// @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private Set<Item> items = new HashSet<Item>();
...
}
アイテム:
@Entity
@Cacheable
@Table(...)
public class Item extends ... {
@ManyToOne
@JoinColumn(name = "order_id", nullable = false)
private Order order;
...
}
DAO:
public class OrderDaoJpaImpl extends ... {
@Override
public Catalog findByIdFetchItems(Long id) {
TypedQuery<Order> query = entityManager.createNamedQuery(Order.NQ_FIND_BY_ID_FETCH_ITEMS, Order.class);
query.setParameter("id", id);
// query.setHint(QueryHints.HINT_CACHEABLE, Boolean.TRUE);
Order order = JPAUtil.singleResultOrNull(query);
return order;
}
サービス:
@Service("orderService")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class OrderServiceImpl implements OrderService {
@Override
public Order getOrderWithItems(Long orderId) {
return orderDao.findByIdFetchItems(orderId);
}
}
persistence.xml:
<persistence ...>
<persistence-unit name="shop-persistence" transaction-type="RESOURCE_LOCAL">
<jar-file>shop-persistence.jar</jar-file>
<!-- Enable JPA 2 second level cache -->
<shared-cache-mode>ALL</shared-cache-mode>
<properties>
...
<property name="hibernate.cache.use_second_level_cache" value="true" />
<property name="hibernate.cache.use_query_cache" value="true" />
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory"/>
</properties>
</persistence-unit>
</persistence>
Spring Framework 4.3.7.RELEASEとHibernate 5.2.9.Final。
ご覧のとおり、JPAキャッシュの代わりにHibernateエンティティの注釈とキャッシュヒントを使用しようとしました。また、JOIN FETCHの代わりにJPAエンティティグラフを試しました。常に同じ:アイテムは、注文クエリの2回目の呼び出しで初期化/復元されません。
多対多関係でHibernate/JPAキャッシュを使用しているのは唯一ですか? – Titus