8

I have a problem with the following entities: Forest, Tree, Leaf. As you can imagine a forest can have a lot of trees, and a tree has a lot of leafs.

I'd like to lazy load all the trees of a forest and to eager load all leafs of a tree. My code with hibernate annotations looks like the following:

Forest.java

@Entity
@Table(name = "Forests")
public class Forest implements Comparable<Forest> {

      @Id
      @Column(name = "forestnumber", length=10, nullable=false)
      private String number;

      @OneToMany(fetch=FetchType.LAZY, mappedBy="forest")
      private Set<Tree> trees = null;

      // some other attributes and methods

Tree.java

 @Entity
 @Table(name = "Trees")
 public class Tree implements Comparable<Tree> {

        @Id
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        @Column(name="tree_id", nullable=false)
        private int id;

        @ManyToOne(fetch = FetchType.EAGER)
        @JoinColumn(name = "forestnumber", nullable = false)
        @Fetch(FetchMode.JOIN)
        private Forest forest;

        @OneToMany(fetch=FetchType.EAGER, mappedBy="tree")
        @Fetch(FetchMode.JOIN)
        private Set<Leaf> leafs = null;

        // some other attributes and methods

Leaf.java

 @Entity
 @Table(name = "Leafs")
 public class Leaf implements Comparable<Leaf> {

        @Id
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        @Column(name="leaf_id", nullable=false)
        private int id;

        @ManyToOne(fetch = FetchType.EAGER)
        @JoinColumn(name = "tree_id", nullable = false)
        @Fetch(FetchMode.JOIN)
        private Tree tree;

        // some other attributes and methods

My problem: Loading a forest and calling the getTrees() Method results in a set of select Statements. Hibernate executes one statement to get all the trees and a second one for each tree to collect all the leafs. In my opinion hibernate should generate only one statement, using a join, to collect trees and leafs at the same time.

Can someone tell me, the reason for my problem and how I can fix it? Thanks a lot!

Bye the way: If I change the fetching strategy of the forest-trees to EAGER everything works fine, with only one statement.

Chetan Kinger
  • 15,069
  • 6
  • 45
  • 82

2 Answers2

0

You can try to initialize

Hibernate.initialize(forestInstance);

Or write a query with join providing fetch to retrieve all the children eagerly.

See also

Is there a way to change the JPA fetch type on a method?

Community
  • 1
  • 1
StanislavL
  • 56,971
  • 9
  • 68
  • 98
0

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

SanyaLuc
  • 116
  • 5
  • Thanks for you answer. The leafs should fetched eager. But instead of select statements for each tree, I'd like to have only one select with a join. As you can see I have used the @Fetch Annotation to tell hibernate to use JOINs. But this works only, if I load the forest trees eager too. Why? – Jens Fischer May 18 '15 at 11:45
  • Try to remove fetch=FetchType.EAGER from @OneToMany(fetch=FetchType.EAGER, mappedBy="tree") under leaf collection to fix your issue – SanyaLuc May 18 '15 at 12:07
  • Removing fetch=FetchType.EAGER from @OneToMany(fetch=FetchType.EAGER, mappedBy="tree") did not help – Jens Fischer May 18 '15 at 12:16