简体   繁体   中英

Hibernate n select issue with bidirectional same entity relationship

I have Item.java entity with below properties

@OneToMany(cascade=CascadeType.ALL, mappedBy="kitItem", fetch=FetchType.EAGER) 
private Set<KitItemDetails> kitItemDetails = new HashSet<KitItemDetails>(0);

.... Other properties with getter and setter

I have KitItemDetails.java entity with below properties

@ManyToOne(cascade=CascadeType.ALL)  
private Item kitItem;

In my DAO access class we are using below query to fetch all items with other related attributes as EAGER

List<Item> items = getCurrentSession().createCriteria(Item.class).addOrder(Order.asc("itemOrder"))
                .list();

But for this its firing n select queries to fecth item details as below

select kititemdet0_.kitItem_id as kitItem_2_9_0_, kititemdet0_.id as id1_12_0_, kititemdet0_.id as id1_12_1_, kititemdet0_.kitItem_id as kitItem_2_12_1_, kititemdet0_.ITEM_ID as ITEM_ID3_12_1_, item1_.id as id1_9_2_, item1_.BAR_CODE as BAR_CODE2_9_2_, item1_.COLOR_CODE as COLOR_CO3_9_2_, item1_.IS_ACTIVE as IS_ACTIV4_9_2_, item1_.ITEM_CATEGORY_ID as ITEM_CA14_9_2_, item1_.ITEM_CODE as ITEM_COD5_9_2_, item1_.ITEM_DISP_NAME as ITEM_DIS6_9_2_, item1_.ITEM_IMAGE as ITEM_IMA7_9_2_, item1_.ITEM_NAME as ITEM_NAM8_9_2_, item1_.ITEM_ORDER as ITEM_ORD9_9_2_, item1_.ITEM_PRICE as ITEM_PR10_9_2_, item1_.ITEM_PRICE_WITH_TAX as ITEM_PR11_9_2_, item1_.ITEM_SUB_CATEGORY_ID as ITEM_SU15_9_2_, item1_.ITEM_TYPE as ITEM_TY12_9_2_, item1_.TAX_ID as TAX_ID16_9_2_, item1_.TAX_CODE as TAX_COD13_9_2_, itemcatego2_.id as id1_10_3_, itemcatego2_.COLOR_CODE as COLOR_CO2_10_3_, itemcatego2_.IS_ACTIVE as IS_ACTIV3_10_3_, itemcatego2_.ITEM_CATEGORY_NAME as ITEM_CAT4_10_3_, itemcatego2_.LOCATION_ID as LOCATION6_10_3_, itemcatego2_.PRINTER_NAME as PRINTER_5_10_3_, itemsubcat3_.id as id1_11_4_, itemsubcat3_.COLOR_CODE as COLOR_CO2_11_4_, itemsubcat3_.IS_ACTIVE as IS_ACTIV3_11_4_, itemsubcat3_.ITEM_CATEGORY_ID as ITEM_CAT5_11_4_, itemsubcat3_.ITEM_SUB_CATEGORY_NAME as ITEM_SUB4_11_4_, tax4_.id as id1_21_5_, tax4_.IS_ACTIVE as IS_ACTIV2_21_5_, tax4_.LOCATION_ID as LOCATION6_21_5_, tax4_.TAX_CODE as TAX_CODE3_21_5_, tax4_.TAX_NAME as TAX_NAME4_21_5_, tax4_.TAX_PER as TAX_PER5_21_5_ from KIT_ITEM_DETAILS kititemdet0_ inner join ITEM item1_ on kititemdet0_.ITEM_ID=item1_.id left outer join ITEM_CATEGORY itemcatego2_ on item1_.ITEM_CATEGORY_ID=itemcatego2_.id left outer join ITEM_SUB_CATEGORY itemsubcat3_ on item1_.ITEM_SUB_CATEGORY_ID=itemsubcat3_.id left outer join TAX tax4_ on item1_.TAX_ID=tax4_.id where kititemdet0_.kitItem_id=?

I tried with mappedBy, JoinColumn, JoinType, FetchMode, etc but did not worked out, what could be the issue ?

In general, having a relation set as EAGER does result in the "N select queries" problem when using criteria queries. You can overcome this by explicitly instructing Hibernate to do a fetch join. See the Hibernate documentation for more details.

The documentation contains an example very similar to your scenario (tweaked to use your class names):

CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Item> query = builder.createQuery( Item.class );
Root<Item> root = query.from( Item.class );
root.fetch( "kitItemDetails", JoinType.LEFT);
query.select(root).where(
   builder.and(
     builder.equal(root.get("foo"), foo),
     builder.equal(root.get("bar"), bar)
  )
);
Item item = entityManager.createQuery( query ).getSingleResult();
// Alternatively, .getResultList() to return List<Item>

@Fetch(FetchMode.JOIN) will not work in your case because, as the documentation goes on to state in its example for FetchMode.JOIN :

The reason why we are not using a JPQL query to fetch multiple Department entities is because the FetchMode.JOIN strategy would be overridden by the query fetching directive.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM