18
18
import com .fasterxml .jackson .databind .ser .impl .PropertySerializerMap ;
19
19
20
20
import org .hibernate .engine .spi .Mapping ;
21
+ import org .hibernate .engine .spi .SessionFactoryImplementor ;
21
22
import org .hibernate .engine .spi .SessionImplementor ;
22
23
import org .hibernate .proxy .HibernateProxy ;
23
24
import org .hibernate .proxy .LazyInitializer ;
@@ -182,10 +183,8 @@ protected Object findProxied(HibernateProxy proxy)
182
183
if (_mapping != null ) {
183
184
idName = _mapping .getIdentifierPropertyName (init .getEntityName ());
184
185
} else {
185
- final SessionImplementor session = init .getSession ();
186
- if (session != null ) {
187
- idName = session .getFactory ().getIdentifierPropertyName (init .getEntityName ());
188
- } else {
186
+ idName = ProxySessionReader .getIdentifierPropertyName (init );
187
+ if (idName == null ) {
189
188
idName = ProxyReader .getIdentifierPropertyName (init );
190
189
if (idName == null ) {
191
190
idName = init .getEntityName ();
@@ -218,7 +217,7 @@ protected static class ProxyReader {
218
217
getIdentifierMethodField = BasicLazyInitializer .class .getDeclaredField ("getIdentifierMethod" );
219
218
getIdentifierMethodField .setAccessible (true );
220
219
} catch (Exception e ) {
221
- // should never happen: the field exists in all versions of hibernate 4 and 5
220
+ // should never happen: the field exists in all versions of hibernate 4 and 5
222
221
throw new RuntimeException (e );
223
222
}
224
223
}
@@ -230,7 +229,7 @@ static String getIdentifierPropertyName(LazyInitializer init) {
230
229
try {
231
230
Method idGetter = (Method ) getIdentifierMethodField .get (init );
232
231
if (idGetter == null ) {
233
- return null ;
232
+ return null ;
234
233
}
235
234
String name = idGetter .getName ();
236
235
if (name .startsWith ("get" )) {
@@ -242,4 +241,50 @@ static String getIdentifierPropertyName(LazyInitializer init) {
242
241
}
243
242
}
244
243
}
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
+ }
245
290
}
0 commit comments