39

what is the difference in specifying lazy = "true" and using fetch = "select" or "join" ? which one is preferred over the other ?

regards jayendra

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
jayendra bhatt
  • 1,337
  • 2
  • 19
  • 41

2 Answers2

42

Let's say we have entities like this:

@Entity
@Table
public class Parent {
    @Id
    private Long id;

    @OneToMany(mappedBy="parent", fetch = FetchType.EAGER)
    @Fetch(FetchMode.JOIN)
    private List<Child> child;    
    //getter setters
}


@Entity
@Table
public class Child {    
    @Id
    private Long id;
    
    @ManyToOne(fetch = FetchType.LAZY)
    private Parent parent;

    //getter setter
}

In the example above, when getting Parent entity, hibernate will automatically load all child entities eagerly using join. On the other hand, when you fetch Child, Parent entity won't be selected unless you call it explicitly in your code child.getParent().

FetchType (Lazy/Eager) tells whether we want entity to be loaded eagerly or lazy, when there's call in code.

FetchMode (Select/Join) tells whether we want our entity to be loaded with additional select or in one query with join or subselect.

Pang
  • 9,564
  • 146
  • 81
  • 122
kamil
  • 3,482
  • 1
  • 40
  • 64
  • Found this online. Very helpful. http://www.solidsyntax.be/2013/10/17/fetching-collections-hibernate/ – Jake Feb 07 '16 at 00:40
  • Tried the same, but running multiple queries even after specifying `@Fetch(FetchMode.JOIN)`, however works in single query in case of SUBSELECT – Pankaj Garg Oct 21 '19 at 05:06
33

FetchMode : It defines how hibernate (using which strategy, e.g. Join, SubQuery etc) will fetch data from database.

FetchType : It defines whether hibernate will fetch the data or not.

UPDATES (as per suggestions from comments)

FetchMode isn't only applicable with FetchType.EAGER. The rules are as follows: a) if you don't specify FetchMode, the default is JOIN and FetchType works normal, b) if you specify FetchMode.JOIN explicitly, FetchType is ignored and a query is always eager, c) if you specify FetchMode.SELECT or FetchMode.SUBSELECT, FetchType.Type works normal

Vishal Zanzrukia
  • 4,902
  • 4
  • 38
  • 82
  • 35
    FetchMode isn't only applicable with FetchType.EAGER. The rules are as follows: a) if you don't specify FetchMode, the default is JOIN and FetchType works normal, b) if you specify FetchMode.JOIN explicitly, FetchType is ignored and a query is always eager, c) if you specify FetchMode.SELECT or FetchMode.SUBSELECT, FetchType.Type works normal. – Dawid Stępień Dec 28 '16 at 11:16
  • 2
    To add on to @DawidStępień, If you forget to `JOIN FETCH` all `EAGER` associations, `Hibernate` is going to issue a `secondary select` for each and every one of those which, in turn, can lean to `N+1 query issues`. For this reason, you should prefer `LAZY` associations. - [link](https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/chapters/fetching/Fetching.html) – jumping_monkey Dec 02 '19 at 09:19
  • @DawidStępień, please make your comment as answer so that it will be more clearly seen. Thanks! – Dexter Feb 08 '20 at 06:40
  • 1
    @DawidStępień If FetchType.LAZY is specified, will it be necessary to specify FetchMode,SELECT? What's the difference between using @Fetch(FetchMode.SELECT) and @ManyToOne(fetch = LAZY) together vs using only @ManyToOne(fetch = LAZY)? – Kawsar Ahmed Mar 05 '23 at 06:17
  • Regarding the statement below "updates": It looks like a copy&paste from a Baeldung's page. If you open the hibernate sourcecode [here](https://github.com/hibernate/hibernate-orm/blob/5.0/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java#L682) you can see that in case the fetchMode is not specified, FetchType is the driver and a FetchType = Lazy forces the FetchMode to SELECT not to JOIN. – Fabio Formosa May 16 '23 at 12:34