Hibernate caching and lazy loaded associations

I got a typical association of order entities and elements. To read only orders, the default set of items is FetchType.LAZY. Layer 2 cache and requests are enabled. To read an order with related items, I use a JPQL query. Query and entities are cached by EHCache. But on the second call, when accessing the elements, a LazyInitializationException was thrown, because the elements are not initialized (they are not restored from the cache). What for? What is the best way to implement this requirement?

Order:

@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>();
  ...
}

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

Services:

@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 and Hibernate 5.2.9.Final.

, Hibernate JPA. JPA JOIN FETCH. : / .

+4
2

LazyInitializationException - HHH-12430.

, , , Hibernate HHH-12430 .

Hibernate, @Cacheable.

, concurrency:

@Entity
@org.hibernate.annotations.Cache(usage = 
    CacheConcurrencyStrategy.READ_WRITE)

, Order, items .

, :

@NamedQuery(name = Order.NQ_FIND_BY_ID_FETCH_ITEMS, query = "SELECT DISTINCT o FROM Order o WHERE o.id = :id")

:

@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private Set<Item> items = new HashSet<Item>();

Order Item :

@Entity
@org.hibernate.annotations.Cache(usage = 
    CacheConcurrencyStrategy.READ_WRITE)

.

, items :

Order order = JPAUtil.singleResultOrNull(query);
if(order != null) {
    order.getItems().size();
}
return order;

, items , , .

+1

, @Cacheable - Hibernate, Spring. @Cache Hibernate. , , JOIN FETCH, , Hibernate.initialize(...) Dao, LazyInitializationException.

0

Source: https://habr.com/ru/post/1675025/


All Articles