jackson-datatype-hibernate icon indicating copy to clipboard operation
jackson-datatype-hibernate copied to clipboard

PersistentCollection fails on detached entities with FORCE_LAZY_LOADING

Open jwgmeligmeyling opened this issue 8 years ago • 12 comments

When Feature.FORCE_LAZY_LOADING is enabled, serialising a detached entity that has an non-initialised PersistentCollection fails with a com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: ..., could not initialize proxy - no Session.

The workaround is to call Hibernate.initialize(Object) on collection before detaching the containing entity.

I can somehow imaging why this is expected behaviour, but shouldn't lazy loading be treated differently for detached entities?

jwgmeligmeyling avatar Oct 01 '16 15:10 jwgmeligmeyling

Detached entities are about JPA, not sure this module is made to handle JPA.

Otherwise you can try to use OpenSessionInViewFilter http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/orm/hibernate3/support/OpenSessionInViewFilter.html if you use spring to manage your transactions.

walfrat avatar Oct 05 '16 06:10 walfrat

No its definetly not, because I just the exact same request filter as with any other lazy loading request. So It is within a transaction, with the entity manager open and just fine, only the entity being serialized is detached.

jwgmeligmeyling avatar Oct 05 '16 06:10 jwgmeligmeyling

Hi Jan, maybe we are facing the same issue. I posted a question on stackoverflow but nobody has answered yet. I am trying to export database objects to JSON using JPA+Hibernate+Jackson. If a stored object has a List or Set attribute, it is serialized as PersistentBag or PersistentSet (hibernate objects). So when I try to deserialize the JSON it tries to load a PersistentBag and throws the same exception you have.

chupetoide avatar Nov 24 '16 00:11 chupetoide

The whole idea of this Hibernate integration is to be able to serialize persistent sets and bags and Hibernate proxies with Jackson ;) So normally this just works. That is except with both this specific feature enabled AND trying to serialize a detached entity (see entitymanager.detach documentation).

jwgmeligmeyling avatar Nov 24 '16 00:11 jwgmeligmeyling

If I detach the model before serialization it throws the same exception when trying to serialize the Set attribute:

Hibernate4Module h4m = new Hibernate4Module();
h4m.enable(Hibernate4Module.Feature.FORCE_LAZY_LOADING);
		
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(h4m);
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
mapper.enableDefaultTyping();
		
TestCar storedCar = PersistenceManager.get(TestCar.class, 1L);
PersistenceManager.getEntityManager().detach(storedCar);
String jsonContent = mapper.writeValueAsString(storedCar);

At this point I am not sure if the problem is on the serialization process (translating Set to PersistentSet) or on the deserialization process (failing to load the Set from json).

chupetoide avatar Nov 24 '16 00:11 chupetoide

Yes, you can't serialise an persistent collection from a detached entity, unless its loaded in advance. That actually makes sense, because you need a session in order to be able to fill the collection, and you just specifically asked to disconnect the entity from the session. That part makes sense, the exception could be a bit more descriptive though, and it's debatable what actually is intended behaviour for Hibernate4Module.Feature.FORCE_LAZY_LOADING on detached entities (for example failing back to serializing a null, as it would do without Hibernate4Module.Feature.FORCE_LAZY_LOADING on enabled).

Anyway, if you need to detach your entity before serialization , you can use Hibernate.initialize(storedCar.getMyCollection() prior to detaching the entity. Or you simply don't detach the entity, which is what I usually go for :wink:

jwgmeligmeyling avatar Nov 24 '16 00:11 jwgmeligmeyling

Let me explain it a bit more. I have no issues on the serialization process. It works fine and all data is serialized as well. My problem is when I try to deserialize the generated JSON because it fails instantiating the PersistentSet. This is the generated JSON I am trying to deserialize:

{
  "id" : 1,
  "name" : "Fiat",
  "parts" : [ "org.hibernate.collection.internal.PersistentSet", [ [ "com.acme.TestPart", {
    "id" : 1,
    "name" : "puerta"
  } ] ] ]
}

chupetoide avatar Nov 24 '16 00:11 chupetoide

I know it's a little bit old topic but i am facing on the same promlem with an antoher serilisation framework named kryo.

@chupetoide Let me explain it a bit more. I have no issues on the serialization process. It works fine and all data is serialized as well. My problem is when I try to deserialize the generated JSON because it fails instantiating the PersistentSet. This is the generated JSON I am trying to deserialize:

Exactly that is my situation too.

But that is a hibernate problem. Hibernate geneartes for managed relations an instance of PersistentCollection which needs a hibernate session for collection operations.

But have not a soluition for that. Maybe a DTO pattern is the only soliton for that?

suikast42 avatar Sep 08 '18 16:09 suikast42

any help about this bug, or how to map types when deserialize from org.hibernate.collection.internal.PersistentBag to java.util.ArrayList

ashraf-revo avatar May 19 '21 17:05 ashraf-revo

Its hardly a bug rather expected behaviour, and workarounds have already been suggested above.

An enhancement for this issue would obviously be nice to have but serializing detached entity completely conflicts with the idea of forcing lazy initialization during serialization anyway.

jwgmeligmeyling avatar May 19 '21 19:05 jwgmeligmeyling

it work with me when i used Hibernate5Module with enabling REPLACE_PERSISTENT_COLLECTIONS,FORCE_LAZY_LOADINGalt text

ashraf-revo avatar May 20 '21 00:05 ashraf-revo

I can load class Hibernate5Module

sharkdeng avatar Oct 24 '23 12:10 sharkdeng