Skip to content

Commit bec70d6

Browse files
committed
Move the changes for hibernate 5.2 compatibility to class
ProxySessionReader
1 parent 3441edc commit bec70d6

File tree

1 file changed

+49
-33
lines changed

1 file changed

+49
-33
lines changed

hibernate5/src/main/java/com/fasterxml/jackson/datatype/hibernate5/HibernateProxySerializer.java

Lines changed: 49 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import com.fasterxml.jackson.databind.ser.impl.PropertySerializerMap;
1919

2020
import org.hibernate.engine.spi.Mapping;
21+
import org.hibernate.engine.spi.SessionFactoryImplementor;
2122
import org.hibernate.engine.spi.SessionImplementor;
2223
import org.hibernate.proxy.HibernateProxy;
2324
import org.hibernate.proxy.LazyInitializer;
@@ -45,15 +46,6 @@ public class HibernateProxySerializer
4546
protected final boolean _serializeIdentifier;
4647
protected final Mapping _mapping;
4748

48-
/**
49-
* Flag to keep track if hibernate abi running is not
50-
* compatible with hibernate jackson-datatype-hibernate5
51-
* used at build-time.
52-
* Maybe using org.hibernate.Version is a better solution
53-
* but the build time version is needed too.
54-
*/
55-
protected Boolean hibernateAbiIncompatible;
56-
5749
/**
5850
* For efficient serializer lookup, let's use this; most
5951
* of the time, there's just one type and one serializer.
@@ -191,30 +183,8 @@ protected Object findProxied(HibernateProxy proxy)
191183
if (_mapping != null) {
192184
idName = _mapping.getIdentifierPropertyName(init.getEntityName());
193185
} else {
194-
// Detect abi compatibility if not set yet
195-
if(hibernateAbiIncompatible == null){
196-
try {
197-
init.getSession();
198-
hibernateAbiIncompatible = false;
199-
} catch (NoSuchMethodError e) {
200-
hibernateAbiIncompatible = true;
201-
}
202-
}
203-
final Object sessionObj;
204-
if(!hibernateAbiIncompatible){
205-
sessionObj = init.getSession();
206-
}else{
207-
try {
208-
Method method = init.getClass().getMethod("getSession");
209-
sessionObj = method.invoke(init);
210-
} catch (Exception e1) {
211-
throw new RuntimeException(e1);
212-
}
213-
}
214-
if (sessionObj != null) {
215-
final SessionImplementor session = (org.hibernate.engine.spi.SessionImplementor) sessionObj;
216-
idName = session.getFactory().getIdentifierPropertyName(init.getEntityName());
217-
} else {
186+
idName = ProxySessionReader.getIdentifierPropertyName(init);
187+
if (idName == null) {
218188
idName = ProxyReader.getIdentifierPropertyName(init);
219189
if (idName == null) {
220190
idName = init.getEntityName();
@@ -271,4 +241,50 @@ static String getIdentifierPropertyName(LazyInitializer init) {
271241
}
272242
}
273243
}
244+
245+
/**
246+
* Hibernate 5.2 broke abi compatibility of org.hibernate.proxy.LazyInitializer.getSession()
247+
* The api contract changed
248+
* from org.hibernate.proxy.LazyInitializer.getSession()Lorg.hibernate.engine.spi.SessionImplementor;
249+
* to org.hibernate.proxy.LazyInitializer.getSession()Lorg.hibernate.engine.spi.SharedSessionContractImplementor
250+
*
251+
* On hibernate 5.2 the interface SessionImplementor extends SharedSessionContractImplementor.
252+
* And an instance of org.hibernate.internal.SessionImpl is returned from getSession().
253+
*/
254+
protected static class ProxySessionReader {
255+
256+
/**
257+
* The getSession method must be executed using reflection for compatibility purpose.
258+
* For efficiency keep the method cached.
259+
*/
260+
protected static final Method lazyInitializerGetSessionMethod;
261+
262+
static {
263+
try {
264+
lazyInitializerGetSessionMethod = LazyInitializer.class.getMethod("getSession");
265+
} catch (Exception e) {
266+
// should never happen: the class and method exists in all versions of hibernate 5
267+
throw new RuntimeException(e);
268+
}
269+
}
270+
271+
static String getIdentifierPropertyName(LazyInitializer init) {
272+
final Object session;
273+
try{
274+
session = lazyInitializerGetSessionMethod.invoke(init);
275+
} catch (Exception e) {
276+
// Should never happen
277+
throw new RuntimeException(e);
278+
}
279+
if(session instanceof SessionImplementor){
280+
SessionFactoryImplementor factory = ((SessionImplementor)session).getFactory();
281+
return factory.getIdentifierPropertyName(init.getEntityName());
282+
}else if (session != null) {
283+
// Should never happen: session should be an instance of org.hibernate.internal.SessionImpl
284+
// factory = session.getClass().getMethod("getFactory").invoke(session);
285+
throw new RuntimeException("Session is not instance of SessionImplementor");
286+
}
287+
return null;
288+
}
289+
}
274290
}

0 commit comments

Comments
 (0)