Reflectively invoke getIdentifier method (for compatibility with Hibernate 6)
Closes gh-28855
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user