Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate : Why FetchType.LAZY-annotated collection property eagerly loading?

I tried to implement simple one-to-many association. after inspecting the item object with debugging mode, I found that List<Bid> bids already loaded. But List<Bid> bids property is annotated with FetchType.LAZY. some books and web pages claim that FetchType.LAZY is a hint JPA providers accept or reject. But I wonder on what condition JPA providers ignore FetchType.LAZY. Thank you in advance.

@Entity
@Table(name = "ITEM")
public class Item implements Serializable {

    @Id
    private Long id = null;

    private String name;
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "SELLER_ID", nullable = false)
    private User seller;

    @OneToMany(mappedBy = "item", fetch = FetchType.LAZY)
    private List<Bid> bids;

    /**
     * No-arg constructor for JavaBean tools.
     */
    public Item() {}

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public User getSeller() {
        return seller;
    }

    public void setSeller(User seller) {
        this.seller = seller;
    }

    @Override
    public String toString() {
        return "Item{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", seller=" + seller +
                ", bids=" + bids +
                '}';
    }
}
@Entity
@Table(name = "BID")
public class Bid implements Serializable {

    @Id @GeneratedValue
    @Column(name = "BID_ID")
    private Long id = null;

    @ManyToOne
    @JoinColumn(name = "ITEM_ID", nullable = false, updatable = false, insertable = false)
    private Item item;

    @ManyToOne
    @JoinColumn(name = "BIDDER_ID", nullable = false, updatable = false)
    private User bidder;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Item getItem() {
        return item;
    }

    public void setItem(Item item) {
        this.item = item;
    }

    public User getBidder() {
        return bidder;
    }

    public void setBidder(User bidder) {
        this.bidder = bidder;
    }

    @Override
    public String toString() {
        return "Bid{" +
                "id=" + id +
                ", bidder=" + bidder +
                '}';
    }
}
private static void itemSeller(EntityManager em) {

    Item item = em.find(Item.class, 1L);
    System.out.println("hello");

}

EDIT : I put break point at the statement System.out.println("hello"). I inspected the item object. See the picture : enter image description here

like image 967
inherithandle Avatar asked Nov 05 '16 11:11

inherithandle


People also ask

What is FetchType lazy why we are using FetchType lazy?

The FetchType. LAZY tells Hibernate to only fetch the related entities from the database when you use the relationship. This is a good idea in general because there's no reason to select entities you don't need for your uses case. You can see an example of a lazily fetched relationship in the following code snippets.

What is the difference between the FetchType lazy and FetchType eager?

Pros and Cons of these two fetch types. Lazy initialization improves performance by avoiding unnecessary computation and reduce memory requirements. Eager initialization takes more memory consumption and processing speed is slow. Having said that, depends on the situation either one of these initialization can be used.

What is the difference between lazy loading and eager loading in Hibernate?

Eager Loading is a design pattern in which data initialization occurs on the spot. Lazy Loading is a design pattern that we use to defer initialization of an object as long as it's possible.

Is FetchType lazy default?

Difference Between EAGER and LAZY Okay, so we talked about the fact that FetchType. LAZY is the default fetch type for all Hibernate annotation relationships. We also talked about the fact that when you use the Lazy fetch type, Hibernate won't load the relationships for that particular object instance.


1 Answers

By inspecting the object in your debugger, you're asking it to call methods of the list to display its size, content, etc. And that of course initializes the list, lazily.

Same for your toString() method, which implicitely loops through the list to print it.

like image 113
JB Nizet Avatar answered Oct 09 '22 23:10

JB Nizet