|
8 | 8 |
|
9 | 9 | import org.hibernate.engine.spi.Mapping;
|
10 | 10 | import org.hibernate.engine.spi.SessionFactoryImplementor;
|
11 |
| -import org.hibernate.engine.spi.SharedSessionContractImplementor; |
| 11 | +import org.hibernate.engine.spi.SessionImplementor; |
12 | 12 | import org.hibernate.proxy.HibernateProxy;
|
13 | 13 | import org.hibernate.proxy.LazyInitializer;
|
14 | 14 | import org.hibernate.proxy.pojo.BasicLazyInitializer;
|
@@ -249,7 +249,6 @@ private String getIdentifierPropertyName(final LazyInitializer init) {
|
249 | 249 | if (_mapping != null) {
|
250 | 250 | idName = _mapping.getIdentifierPropertyName(init.getEntityName());
|
251 | 251 | } else {
|
252 |
| - // no unit tests rely on this next call and Hibernate 7 does not support it |
253 | 252 | idName = ProxySessionReader.getIdentifierPropertyName(init);
|
254 | 253 | if (idName == null) {
|
255 | 254 | idName = ProxyReader.getIdentifierPropertyName(init);
|
@@ -302,12 +301,47 @@ static String getIdentifierPropertyName(LazyInitializer init) {
|
302 | 301 | }
|
303 | 302 | }
|
304 | 303 |
|
| 304 | + /** |
| 305 | + * Hibernate 5.2 broke abi compatibility of org.hibernate.proxy.LazyInitializer.getSession() |
| 306 | + * The api contract changed |
| 307 | + * from org.hibernate.proxy.LazyInitializer.getSession()Lorg.hibernate.engine.spi.SessionImplementor; |
| 308 | + * to org.hibernate.proxy.LazyInitializer.getSession()Lorg.hibernate.engine.spi.SharedSessionContractImplementor |
| 309 | + * |
| 310 | + * On hibernate 5.2 the interface SessionImplementor extends SharedSessionContractImplementor. |
| 311 | + * And an instance of org.hibernate.internal.SessionImpl is returned from getSession(). |
| 312 | + */ |
305 | 313 | protected static class ProxySessionReader {
|
| 314 | + |
| 315 | + /** |
| 316 | + * The getSession method must be executed using reflection for compatibility purpose. |
| 317 | + * For efficiency keep the method cached. |
| 318 | + */ |
| 319 | + protected static final Method lazyInitializerGetSessionMethod; |
| 320 | + |
| 321 | + static { |
| 322 | + try { |
| 323 | + lazyInitializerGetSessionMethod = LazyInitializer.class.getMethod("getSession"); |
| 324 | + } catch (Exception e) { |
| 325 | + // should never happen: the class and method exists in all versions of hibernate 5 |
| 326 | + throw new RuntimeException(e); |
| 327 | + } |
| 328 | + } |
| 329 | + |
306 | 330 | static String getIdentifierPropertyName(LazyInitializer init) {
|
307 |
| - final SharedSessionContractImplementor session = init.getSession(); |
308 |
| - if (session != null) { |
309 |
| - SessionFactoryImplementor factory = session.getFactory(); |
310 |
| - return factory.getIdentifierPropertyName(init.getEntityName()); |
| 331 | + final Object session; |
| 332 | + try{ |
| 333 | + session = lazyInitializerGetSessionMethod.invoke(init); |
| 334 | + } catch (Exception e) { |
| 335 | + // Should never happen |
| 336 | + throw new RuntimeException(e); |
| 337 | + } |
| 338 | + if(session instanceof SessionImplementor){ |
| 339 | + SessionFactoryImplementor factory = ((SessionImplementor)session).getFactory(); |
| 340 | + return factory.getIdentifierPropertyName(init.getEntityName()); |
| 341 | + }else if (session != null) { |
| 342 | + // Should never happen: session should be an instance of org.hibernate.internal.SessionImpl |
| 343 | + // factory = session.getClass().getMethod("getFactory").invoke(session); |
| 344 | + throw new RuntimeException("Session is not instance of SessionImplementor"); |
311 | 345 | }
|
312 | 346 | return null;
|
313 | 347 | }
|
|
0 commit comments