Skip to content

2.8.7 NoSuchMethodError PersistentCollection.setCurrentSession #104

Open
@coladict

Description

@coladict

They changed the signature of the method in 5.2 and now instead of SessionImplementor it takes SharedSessionContractImplementor.

This fixed it.

diff --git a/hibernate5/src/main/java/com/fasterxml/jackson/datatype/hibernate5/PersistentCollectionSerializer.java b/hibernate5/src/main/java/com/fasterxml/jackson/datatype/hibernate5/PersistentCollectionSerializer.java
index 140d8b3..392eb31 100644
--- a/hibernate5/src/main/java/com/fasterxml/jackson/datatype/hibernate5/PersistentCollectionSerializer.java
+++ b/hibernate5/src/main/java/com/fasterxml/jackson/datatype/hibernate5/PersistentCollectionSerializer.java
@@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.ser.ContextualSerializer;
 import com.fasterxml.jackson.databind.ser.ResolvableSerializer;
 import com.fasterxml.jackson.databind.util.NameTransformer;
 import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module.Feature;
+import java.lang.reflect.InvocationTargetException;
 
 import org.hibernate.FlushMode;
 import org.hibernate.Hibernate;
@@ -63,6 +64,8 @@ public class PersistentCollectionSerializer
 
     protected final SessionFactory _sessionFactory;
 
+    protected final Method _collectionSessionInitMethod;
+
     /*
     /**********************************************************************
     /* Life cycle
@@ -77,6 +80,7 @@ public class PersistentCollectionSerializer
         _serializer = (JsonSerializer<Object>) serializer;
         _features = features;
         _sessionFactory = sessionFactory;
+        _collectionSessionInitMethod = initCollMetod();
     }
 
     /**
@@ -90,6 +94,22 @@ public class PersistentCollectionSerializer
         _serializer = (JsonSerializer<Object>) serializer;
         _features = base._features;
         _sessionFactory = base._sessionFactory;
+        _collectionSessionInitMethod = initCollMetod();
+    }
+
+    protected Method initCollMetod() {
+        try {
+            Class<?> cl = SessionFactory.class.getClassLoader().loadClass("org.hibernate.collection.spi.PersistentCollection");
+            for (Method m : cl.getMethods()) {
+                if (m.getName().equals("setCurrentSession")) {
+                    return m;
+                }
+            }
+        }
+        catch (ClassNotFoundException ex) {
+            throw new IllegalStateException("Hibernate version is incompatible for lazy collection serialization", ex);
+        }
+        throw new IllegalStateException("Hibernate version is incompatible for lazy collection serialization");
     }
 
     @Override
@@ -348,7 +368,13 @@ public class PersistentCollectionSerializer
             session.beginTransaction();
         }
 
-        coll.setCurrentSession(((SessionImplementor) session));
+        try {
+            _collectionSessionInitMethod.invoke(coll, session);
+        }
+        catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
+            throw new IllegalStateException("Hibernate version is incompatible for lazy collection serialization", ex);
+        }
+
         Hibernate.initialize(coll);
 
         if (!isJTA) {

If you migrated to Gradle you could actually test different provider versions in the same build.
For example, I managed to do it like this https://github.com/mopano/hibernate-json-type/blob/d25edecea9cab619207e4888c850c96bc65f10ea/build.gradle

Lines 28-32 define configurations for each provider;
Lines 50-52 define dependency for each configuration;
Lines 62-81 define new test tasks for each provider configuration.
Lines 66, 73, 80 set classpaths for each task accordingly.

That's the kind of flexibility Maven will never provide.

With this patch it managed to serialize my object that was crashing after it had just been persisted.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions