Browse Source

Reflectively invoke getIdentifier method (for compatibility with Hibernate 6)

Closes gh-28855
pull/28964/head
Juergen Hoeller 4 years ago
parent
commit
293e296d59
  1. 6
      spring-orm/src/main/java/org/springframework/orm/ObjectOptimisticLockingFailureException.java
  2. 6
      spring-orm/src/main/java/org/springframework/orm/ObjectRetrievalFailureException.java
  3. 22
      spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateObjectRetrievalFailureException.java
  4. 4
      spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateOptimisticLockingFailureException.java
  5. 4
      spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBean.java
  6. 4
      spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java
  7. 23
      spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java
  8. 4
      spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaVendorAdapter.java

6
spring-orm/src/main/java/org/springframework/orm/ObjectOptimisticLockingFailureException.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -82,7 +82,7 @@ public class ObjectOptimisticLockingFailureException extends OptimisticLockingFa
* @param cause the source exception * @param cause the source exception
*/ */
public ObjectOptimisticLockingFailureException( public ObjectOptimisticLockingFailureException(
Class<?> persistentClass, Object identifier, String msg, @Nullable Throwable cause) { Class<?> persistentClass, @Nullable Object identifier, String msg, @Nullable Throwable cause) {
super(msg, cause); super(msg, cause);
this.persistentClass = persistentClass; this.persistentClass = persistentClass;
@ -123,7 +123,7 @@ public class ObjectOptimisticLockingFailureException extends OptimisticLockingFa
* @param cause the source exception * @param cause the source exception
*/ */
public ObjectOptimisticLockingFailureException( public ObjectOptimisticLockingFailureException(
String persistentClassName, Object identifier, String msg, @Nullable Throwable cause) { String persistentClassName, @Nullable Object identifier, String msg, @Nullable Throwable cause) {
super(msg, cause); super(msg, cause);
this.persistentClass = persistentClassName; this.persistentClass = persistentClassName;

6
spring-orm/src/main/java/org/springframework/orm/ObjectRetrievalFailureException.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -69,7 +69,7 @@ public class ObjectRetrievalFailureException extends DataRetrievalFailureExcepti
* @param cause the source exception * @param cause the source exception
*/ */
public ObjectRetrievalFailureException( public ObjectRetrievalFailureException(
Class<?> persistentClass, Object identifier, String msg, @Nullable Throwable cause) { Class<?> persistentClass, @Nullable Object identifier, String msg, @Nullable Throwable cause) {
super(msg, cause); super(msg, cause);
this.persistentClass = persistentClass; this.persistentClass = persistentClass;
@ -97,7 +97,7 @@ public class ObjectRetrievalFailureException extends DataRetrievalFailureExcepti
* @param cause the source exception * @param cause the source exception
*/ */
public ObjectRetrievalFailureException( public ObjectRetrievalFailureException(
String persistentClassName, Object identifier, String msg, @Nullable Throwable cause) { String persistentClassName, @Nullable Object identifier, String msg, @Nullable Throwable cause) {
super(msg, cause); super(msg, cause);
this.persistentClass = persistentClassName; this.persistentClass = persistentClassName;

22
spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateObjectRetrievalFailureException.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2015 the original author or authors. * Copyright 2002-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,10 +16,13 @@
package org.springframework.orm.hibernate5; package org.springframework.orm.hibernate5;
import org.hibernate.HibernateException;
import org.hibernate.UnresolvableObjectException; import org.hibernate.UnresolvableObjectException;
import org.hibernate.WrongClassException; import org.hibernate.WrongClassException;
import org.springframework.lang.Nullable;
import org.springframework.orm.ObjectRetrievalFailureException; import org.springframework.orm.ObjectRetrievalFailureException;
import org.springframework.util.ReflectionUtils;
/** /**
* Hibernate-specific subclass of ObjectRetrievalFailureException. * Hibernate-specific subclass of ObjectRetrievalFailureException.
@ -33,11 +36,24 @@ import org.springframework.orm.ObjectRetrievalFailureException;
public class HibernateObjectRetrievalFailureException extends ObjectRetrievalFailureException { public class HibernateObjectRetrievalFailureException extends ObjectRetrievalFailureException {
public HibernateObjectRetrievalFailureException(UnresolvableObjectException ex) { public HibernateObjectRetrievalFailureException(UnresolvableObjectException ex) {
super(ex.getEntityName(), ex.getIdentifier(), ex.getMessage(), ex); super(ex.getEntityName(), getIdentifier(ex), ex.getMessage(), ex);
} }
public HibernateObjectRetrievalFailureException(WrongClassException ex) { public HibernateObjectRetrievalFailureException(WrongClassException ex) {
super(ex.getEntityName(), ex.getIdentifier(), ex.getMessage(), ex); super(ex.getEntityName(), getIdentifier(ex), ex.getMessage(), ex);
}
@Nullable
static Object getIdentifier(HibernateException hibEx) {
try {
// getIdentifier declares Serializable return value on 5.x but Object on 6.x
// -> not binary compatible, let's invoke it reflectively for the time being
return ReflectionUtils.invokeMethod(hibEx.getClass().getMethod("getIdentifier"), hibEx);
}
catch (NoSuchMethodException ex) {
return null;
}
} }
} }

4
spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateOptimisticLockingFailureException.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2015 the original author or authors. * Copyright 2002-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -35,7 +35,7 @@ import org.springframework.orm.ObjectOptimisticLockingFailureException;
public class HibernateOptimisticLockingFailureException extends ObjectOptimisticLockingFailureException { public class HibernateOptimisticLockingFailureException extends ObjectOptimisticLockingFailureException {
public HibernateOptimisticLockingFailureException(StaleObjectStateException ex) { public HibernateOptimisticLockingFailureException(StaleObjectStateException ex) {
super(ex.getEntityName(), ex.getIdentifier(), ex); super(ex.getEntityName(), HibernateObjectRetrievalFailureException.getIdentifier(ex), ex.getMessage(), ex);
} }
public HibernateOptimisticLockingFailureException(StaleStateException ex) { public HibernateOptimisticLockingFailureException(StaleStateException ex) {

4
spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBean.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2021 the original author or authors. * Copyright 2002-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -57,7 +57,7 @@ import org.springframework.lang.Nullable;
* way to set up a shared Hibernate SessionFactory in a Spring application context; the * way to set up a shared Hibernate SessionFactory in a Spring application context; the
* SessionFactory can then be passed to data access objects via dependency injection. * SessionFactory can then be passed to data access objects via dependency injection.
* *
* <p>Compatible with Hibernate 5.5/5.6, as of Spring 6.0. * <p>Compatible with Hibernate ORM 5.5/5.6, as of Spring Framework 6.0.
* This Hibernate-specific {@code LocalSessionFactoryBean} can be an immediate alternative * This Hibernate-specific {@code LocalSessionFactoryBean} can be an immediate alternative
* to {@link org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean} for * to {@link org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean} for
* common JPA purposes: The Hibernate {@code SessionFactory} will natively expose the JPA * common JPA purposes: The Hibernate {@code SessionFactory} will natively expose the JPA

4
spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2021 the original author or authors. * Copyright 2002-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -78,7 +78,7 @@ import org.springframework.util.ClassUtils;
* Typically combined with {@link HibernateTransactionManager} for declarative * Typically combined with {@link HibernateTransactionManager} for declarative
* transactions against the {@code SessionFactory} and its JDBC {@code DataSource}. * transactions against the {@code SessionFactory} and its JDBC {@code DataSource}.
* *
* <p>Compatible with Hibernate 5.5/5.6, as of Spring 6.0. * <p>Compatible with Hibernate ORM 5.5/5.6, as of Spring Framework 6.0.
* This Hibernate-specific factory builder can also be a convenient way to set up * This Hibernate-specific factory builder can also be a convenient way to set up
* a JPA {@code EntityManagerFactory} since the Hibernate {@code SessionFactory} * a JPA {@code EntityManagerFactory} since the Hibernate {@code SessionFactory}
* natively exposes the JPA {@code EntityManagerFactory} interface as well now. * natively exposes the JPA {@code EntityManagerFactory} interface as well now.

23
spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java vendored

@ -70,10 +70,11 @@ import org.springframework.transaction.InvalidIsolationLevelException;
import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException; import org.springframework.transaction.TransactionException;
import org.springframework.transaction.support.ResourceTransactionDefinition; import org.springframework.transaction.support.ResourceTransactionDefinition;
import org.springframework.util.ReflectionUtils;
/** /**
* {@link org.springframework.orm.jpa.JpaDialect} implementation for * {@link org.springframework.orm.jpa.JpaDialect} implementation for Hibernate.
* Hibernate EntityManager. * Compatible with Hibernate ORM 5.5/5.6 as well as 6.0/6.1.
* *
* @author Juergen Hoeller * @author Juergen Hoeller
* @author Costin Leau * @author Costin Leau
@ -295,13 +296,13 @@ public class HibernateJpaDialect extends DefaultJpaDialect {
return new InvalidDataAccessApiUsageException(ex.getMessage(), ex); return new InvalidDataAccessApiUsageException(ex.getMessage(), ex);
} }
if (ex instanceof UnresolvableObjectException hibEx) { if (ex instanceof UnresolvableObjectException hibEx) {
return new ObjectRetrievalFailureException(hibEx.getEntityName(), hibEx.getIdentifier(), ex.getMessage(), ex); return new ObjectRetrievalFailureException(hibEx.getEntityName(), getIdentifier(hibEx), ex.getMessage(), ex);
} }
if (ex instanceof WrongClassException hibEx) { if (ex instanceof WrongClassException hibEx) {
return new ObjectRetrievalFailureException(hibEx.getEntityName(), hibEx.getIdentifier(), ex.getMessage(), ex); return new ObjectRetrievalFailureException(hibEx.getEntityName(), getIdentifier(hibEx), ex.getMessage(), ex);
} }
if (ex instanceof StaleObjectStateException hibEx) { if (ex instanceof StaleObjectStateException hibEx) {
return new ObjectOptimisticLockingFailureException(hibEx.getEntityName(), hibEx.getIdentifier(), ex); return new ObjectOptimisticLockingFailureException(hibEx.getEntityName(), getIdentifier(hibEx), ex.getMessage(), ex);
} }
if (ex instanceof StaleStateException) { if (ex instanceof StaleStateException) {
return new ObjectOptimisticLockingFailureException(ex.getMessage(), ex); return new ObjectOptimisticLockingFailureException(ex.getMessage(), ex);
@ -324,6 +325,18 @@ public class HibernateJpaDialect extends DefaultJpaDialect {
return entityManager.unwrap(SessionImplementor.class); return entityManager.unwrap(SessionImplementor.class);
} }
@Nullable
protected Object getIdentifier(HibernateException hibEx) {
try {
// getIdentifier declares Serializable return value on 5.x but Object on 6.x
// -> not binary compatible, let's invoke it reflectively for the time being
return ReflectionUtils.invokeMethod(hibEx.getClass().getMethod("getIdentifier"), hibEx);
}
catch (NoSuchMethodException ex) {
return null;
}
}
private static class SessionTransactionData { private static class SessionTransactionData {

4
spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaVendorAdapter.java vendored

@ -43,8 +43,8 @@ import org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
/** /**
* {@link org.springframework.orm.jpa.JpaVendorAdapter} implementation for Hibernate * {@link org.springframework.orm.jpa.JpaVendorAdapter} implementation for Hibernate.
* EntityManager. * Compatible with Hibernate ORM 5.5/5.6 as well as 6.0/6.1.
* *
* <p>Exposes Hibernate's persistence provider and Hibernate's Session as extended * <p>Exposes Hibernate's persistence provider and Hibernate's Session as extended
* EntityManager interface, and adapts {@link AbstractJpaVendorAdapter}'s common * EntityManager interface, and adapts {@link AbstractJpaVendorAdapter}'s common

Loading…
Cancel
Save