41

I have a userAccount entity mapped with a country entity . The country mapping in UserAccount class is like this

@ManyToOne(fetch=FetchType.EAGER) @Fetch(FetchMode.JOIN) @JoinColumn(name="f_country_id", nullable=true, insertable=false, updatable=false) private Country country; 

Even there is fetchmode defined as Join, hibernate fires a separate SQL Select to fetch countries.

3
  • 3
    Did you solve this issue? How the accepted answer helped you? I'm facing the same problem, but the accepted answer doesn't help. Commented Apr 22, 2016 at 11:00
  • For eager its simple. Lazy will stop loading it. So answer is perfect here. Small catch is that when you have N to One relationship, it doesn't work. So we need to go with bytecode instrumentation and field properties modifier. Its a feature of hibernate though. Commented Apr 22, 2016 at 11:29
  • The problem, as title and content suggest, is Hibernate issuing SELECT statements for a @ManyToOne relation with EAGER fetch type when the requested fetch mode is JOIN. The accepted answer states to remove the fetch=FetchType.EAGER from the annotation, an action that won't change anything since EAGER is the default fetch type for the annotation; even if you interpret the answer as "change EAGER with LAZY", that doesn't explain why Hibernate issues SELECT statements when it's instructed not to do so. Commented Apr 22, 2016 at 12:48

4 Answers 4

20

Remove the fetch=FetchType.EAGER. Eager fetching triggers cascading select statements.

If you are using explicit HQL query e.g. "from User where something = someValue", Hibernate will not respect the annotated Fetch mode. You would need to specify the join in the HQL query or the fetch mode in the criteria.

Sign up to request clarification or add additional context in comments.

7 Comments

I need to have it eager. is there any way to fetch eager with join...?
Didn't solve the problem. It still firing the select statements to the database. I am using the following: @ManyToOne @Fetch(FetchMode.JOIN) @JoinColumn(name="f_country_id", nullable=true, insertable=false, updatable=false) private Country country;
If you are using explicit HQL query e.g. "from User where something = someValue", Hibernate will not respect the annotated Fetch mode. You would need to specify the join in the HQL query or the fetch mode in the criteria.
Isn't FetchType.EAGER the default for ManyToOne? I think the explicit where clause as mentioned by @SatadruBiswas might be the problem.
Why was this answer accepted? In which way it resolve the OP issue? As @JamesSelvakumar stated, FetchType.EAGER is the default value for the annotation, so removing it won't change anything.
|
15

Satadru Biswas gave the answer in a previous comment .

Hibernate 3.x ignores the FetchMode annotation when you use the Query interface (Session.createQuery) so in this case you have to add an INNER JOIN FETCH clause to the FROM part of your query.

The criteria interface however will use this interface correctly.

Comments

11

I try use @Fetch(FetchMode.JOIN) hibernate adnotation in all api (JPQL and CriteriaBuilder) but didn't work. Only this code in service class work fine:

CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<UserAccount > cq = cb.createQuery(UserAccount.class); Root<UserAccount> o = cq.from(UserAccount.class); o.fetch("country",JoinType.INNER); em.createQuery(cq.select(o)).getResultList(); 

Comments

0

I'm using the criteria query to fetch Customers.

public class PurchaseOrder { ..... ..... @ManyToOne(fetch=FetchType.EAGER, optional=true) @JoinColumn(name="ReportingCustomer_ID", nullable=true, insertable=false, updatable=false) @Fetch(FetchMode.JOIN) @NotFound(action=NotFoundAction.IGNORE) public ReportingCustomer getReportingCustomer() { return reportingCustomer; } } 

While getting PurchaseOrder it does a LEFT OUTER JOIN as below

select ... from PurchaseOrder this_ left outer join ReportingCustomer reportingc2_ on this_.ReportingCustomer_ID=reportingc2_.ReportingCustomer_ID where ... 
  1. When there is an entry in ReportingCustomer - It fires only the above query.
  2. When there is no entry for that record in ReportingCustomer - It fires a query for each PURCHASEORDER (m+1) queries.

I use "Progress" driver to connect to DB. I'm not sure why it fires m+1 queries only in scenario 2.

1 Comment

I'm experiencing the same issue: FetchMode.JOIN works since it finds one, then it starts with SELECTs. Did you find a solution?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.