|
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;
|
@@ -45,15 +46,6 @@ public class HibernateProxySerializer
|
45 | 46 | protected final boolean _serializeIdentifier;
|
46 | 47 | protected final Mapping _mapping;
|
47 | 48 |
|
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 |
| - |
57 | 49 | /**
|
58 | 50 | * For efficient serializer lookup, let's use this; most
|
59 | 51 | * of the time, there's just one type and one serializer.
|
@@ -191,30 +183,8 @@ protected Object findProxied(HibernateProxy proxy)
|
191 | 183 | if (_mapping != null) {
|
192 | 184 | idName = _mapping.getIdentifierPropertyName(init.getEntityName());
|
193 | 185 | } 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) { |
218 | 188 | idName = ProxyReader.getIdentifierPropertyName(init);
|
219 | 189 | if (idName == null) {
|
220 | 190 | idName = init.getEntityName();
|
@@ -271,4 +241,50 @@ static String getIdentifierPropertyName(LazyInitializer init) {
|
271 | 241 | }
|
272 | 242 | }
|
273 | 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 | + } |
274 | 290 | }
|
0 commit comments