1

I have a JPA setup in such a way that if I do not use lazy load, almost the entire database will be loaded. I also use serializing directly on the models so sometimes I need to initialize the proxies.

I only want to use lazy load on the collections. The fact that some singular entities are fetched eagerly works just fine. But no matter how I try to setup the collections I never get a collection of proxies, I always get the fully loaded collection.

This is some example code:

@Entity
public class Thread implements Externalizable {
    @OneToMany(mappedBy = "parentThread", fetch = FetchType.LAZY)
    public List<Reply> getReplies() {
        return replies;
    }

So the problem here is that when I check the debugger, the persistantBag-list of replies are always filled with info and are the actual Reply objects instead of empty proxies which I want.

I use entityManager.find(Thread.class, "ID") when I want the thread and all collections like these are always fully loaded no matter if I have fetch = FetchType.LAZY or not.

As far as I understand, setting fetchtype lazy should work as I want it to. Also I would like the entities to be loaded when using the thread.getReplies() so that I can serialize and send them to the client. I do not know if getReplies will work with proxied entities since I never got any collection to be lazily loaded.

On a side not I use Intellij and used it to setup JPA with Hibernate. I have also asked a similar question where I want the collection to be completely empty but I am not sure if that is possible and I am therefor asking this question instead.

JPA Hibernate want lazy load to return empty collection

I have not yet seen a good answer on this seemingly basic question on stackoverflow. Please only reply with a link if the question is really answered in a pedagogical way since I am new to JPA/Hibernate and really databases as well.

Thank you very much in advance!

Community
  • 1
  • 1

1 Answers1

4

A lazy collection doesn't contain proxies. The collection itself is a lazy-loaded collection. This means that when you get a thread from the database, its list of replies won't be initialized.

Calling getReplies() will simply return this not-initialized list. Only when calling a method on the list itself (like size() or iterator()) will Hibernate initialize the list by executing a SQL query loading the state of all the replies of the thread.

Using a debugger to check what the collection contains is not a good idea, because the debugger usually calls methods on the list behind your back, which causes the list to initialize itself. You can check if a collection is initialized using the Hibernate.isInitialized(thread.getReplies()) method.

Regarding your other question: Hibernate is used to map database rows to objects. If a thread has replies, Hibernate will never tell you that it doesn't have any by returning you an empty list. That would be a serious bug. If you don't want to load the replies, simply don't call any method on the list of replies.

JB Nizet
  • 633,450
  • 80
  • 1,108
  • 1,174
  • Thank you! And sorry for forgetting to accept your answer =) I had missed that the debugger actually makes calls to the methods behind my back which caused my confusion. – Mathias Lindblom Jul 28 '15 at 11:03