2

I am using Hibernate 5 & Spring Data. Inside my PartyDao, I have the following method:

@Query("from Party where id in :partyIDs")
List<PartyTO> loadByIDs(@Param("partyIDs") List<Long> partyIDs);

I am calling it like this:

partyList = partyDao.loadByIDs(userPartyIDsList));

but I am getting a list of Hibernate proxy objects (with all the fields set to null and a handler field of type org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer).

This makes no sense to me! Why is Hibernate not loading the objects FROM the query root I am specifying?

I changed it to:

@Query("select party from Party party where party.id in :partyIDs")
List<PartyTO> loadByIDs(@Param("partyIDs") List<Long> partyIDs);

to try to make it more explicit that that I want this object fetched, but it's still returning the proxy objects. Is there something I'm missing? I don't know how I would make it fetch itself.

EDIT: The proxy object actually has an attribute called target, which has all the attributes set. Why are they not placed into the object itself?

I am not getting a "lazy initialization exception", but a NullPointerException inside a Comparator that is sorting the parties by name:

...
return o1.name.compareTo(o2.name);
Daniel Gray
  • 1,697
  • 1
  • 21
  • 41

2 Answers2

2

The problem is your direct access to the name property of your object.

    ...
    return o1.name.compareTo(o2.name);

Hibernate will always return proxy objects, and the serialization of some more complex structures might lead you to issues in the future including the lazy instantiation exceptions mentioned. However, the cause of your problem is direct access of a property, if you correctly utilize your getter functions within your comparators you will not have any other problem.

The proxy object is a runtime extension of your target class, it will have the same interface as the target class, but in true OOD fashion the internals are not visible or accessible. The only guarantee is the interface contract presented, and that is what you should be coding against regardless within your objects.

Change your comparator and other code to match the following, and you won't have this issue again.

    ...
    return o1.getName().compareTo(o2.getName());
Michael Hibay
  • 522
  • 3
  • 11
1

The value will be read into the main object by calling the property method instead of the attribute itself.

The Comparator return statement must be changed to:

return o1.getName().compareTo(o2.getName());
Daniel Gray
  • 1,697
  • 1
  • 21
  • 41