DATACMNS-1019 - Assert Hibernate 5.2 compatibility.

Improved our detection of Hibernate 5.2 in the query lookup for String based queries, general PersistenceProvider detection (due to changed interface hierarchies in Hibernate 5.2). Tweaked the setup for some integration tests to point to Hibernate 5.2 specific persistence units using the new location for the persistence provider implementation class.
This commit is contained in:
Oliver Gierke
2016-12-06 15:06:04 +01:00
parent 3ed3ecf801
commit 0e68be8a5f
6 changed files with 84 additions and 9 deletions

View File

@@ -37,21 +37,35 @@ public abstract class HibernateUtils {
"org.hibernate.ejb.HibernateQuery");
private static final Method GET_HIBERNATE_QUERY;
private static final Class<?> HIBERNATE_QUERY_INTERFACE;
private static final Method QUERY_STRING_METHOD;
private HibernateUtils() {}
static {
Class<?> type = null;
Method method = null;
ClassLoader classLoader = HibernateUtils.class.getClassLoader();
for (String typeName : TYPES) {
try {
type = ClassUtils.forName(typeName, HibernateUtils.class.getClassLoader());
type = ClassUtils.forName(typeName, classLoader);
method = type.getMethod("getHibernateQuery");
} catch (Exception o_O) {}
}
GET_HIBERNATE_QUERY = method;
Class<?> queryInterface = null;
try {
queryInterface = ClassUtils.forName("org.hibernate.query.Query", classLoader);
} catch (Exception o_O) {}
HIBERNATE_QUERY_INTERFACE = queryInterface;
QUERY_STRING_METHOD = HIBERNATE_QUERY_INTERFACE == null ? null
: ReflectionUtils.findMethod(HIBERNATE_QUERY_INTERFACE, "getQueryString");
}
/**
@@ -61,6 +75,11 @@ public abstract class HibernateUtils {
* @return
*/
public static String getHibernateQuery(Object query) {
if (HIBERNATE_QUERY_INTERFACE != null && HIBERNATE_QUERY_INTERFACE.isInstance(query)) {
return String.class.cast(ReflectionUtils.invokeMethod(QUERY_STRING_METHOD, query));
}
return ((Query) ReflectionUtils.invokeMethod(GET_HIBERNATE_QUERY, query)).getQueryString();
}
}

View File

@@ -54,7 +54,7 @@ import org.springframework.util.ReflectionUtils;
* @author Oliver Gierke
* @author Thomas Darimont
*/
public enum PersistenceProvider implements QueryExtractor,ProxyIdAccessor {
public enum PersistenceProvider implements QueryExtractor, ProxyIdAccessor {
/**
* Hibernate persistence provider.
@@ -65,8 +65,9 @@ public enum PersistenceProvider implements QueryExtractor,ProxyIdAccessor {
* @see DATAJPA-444
*/
HIBERNATE(//
Arrays.asList(HIBERNATE43_ENTITY_MANAGER_INTERFACE, HIBERNATE_ENTITY_MANAGER_INTERFACE), //
Arrays.asList(HIBERNATE43_JPA_METAMODEL_TYPE, HIBERNATE_JPA_METAMODEL_TYPE)) {
Arrays.asList(HIBERNATE52_ENTITY_MANAGER_INTERFACE, HIBERNATE43_ENTITY_MANAGER_INTERFACE,
HIBERNATE_ENTITY_MANAGER_INTERFACE), //
Arrays.asList(HIBERNATE52_JPA_METAMODEL_TYPE, HIBERNATE43_JPA_METAMODEL_TYPE, HIBERNATE_JPA_METAMODEL_TYPE)) {
public String extractQueryString(Query query) {
return HibernateUtils.getHibernateQuery(query);
@@ -124,8 +125,7 @@ public enum PersistenceProvider implements QueryExtractor,ProxyIdAccessor {
/**
* EclipseLink persistence provider.
*/
ECLIPSELINK(Collections.singleton(ECLIPSELINK_ENTITY_MANAGER_INTERFACE),
Collections.singleton(ECLIPSELINK_JPA_METAMODEL_TYPE)) {
ECLIPSELINK(Collections.singleton(ECLIPSELINK_ENTITY_MANAGER_INTERFACE), Collections.singleton(ECLIPSELINK_JPA_METAMODEL_TYPE)) {
public String extractQueryString(Query query) {
return ((JpaQuery<?>) query).getDatabaseQuery().getJPQLString();
@@ -263,9 +263,11 @@ public enum PersistenceProvider implements QueryExtractor,ProxyIdAccessor {
String ECLIPSELINK_ENTITY_MANAGER_INTERFACE = "org.eclipse.persistence.jpa.JpaEntityManager";
String HIBERNATE_ENTITY_MANAGER_INTERFACE = "org.hibernate.ejb.HibernateEntityManager";
String HIBERNATE43_ENTITY_MANAGER_INTERFACE = "org.hibernate.jpa.HibernateEntityManager";
String HIBERNATE52_ENTITY_MANAGER_INTERFACE = "org.hibernate.Session";
String HIBERNATE_JPA_METAMODEL_TYPE = "org.hibernate.ejb.metamodel.MetamodelImpl";
String HIBERNATE43_JPA_METAMODEL_TYPE = "org.hibernate.jpa.internal.metamodel.MetamodelImpl";
String HIBERNATE52_JPA_METAMODEL_TYPE = "org.hibernate.metamodel.internal.MetamodelImpl";
String ECLIPSELINK_JPA_METAMODEL_TYPE = "org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl";
String OPENJPA_JPA_METAMODEL_TYPE = "org.apache.openjpa.persistence.meta.MetamodelImpl";
}

View File

@@ -25,6 +25,8 @@ import java.util.List;
import javax.persistence.EntityManager;
import org.hibernate.Version;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
@@ -102,6 +104,21 @@ public class PersistenceProviderUnitTests {
assertThat(fromEntityManager(em), is(GENERIC_JPA));
}
/**
* @see DATAJPA-1019
*/
@Test
public void detectsHibernatePersistenceProviderForHibernateVersion52() throws Exception {
Assume.assumeThat(Version.getVersionString(), startsWith("5.2"));
shadowingClassLoader.excludePackage("org.hibernate");
EntityManager em = mockProviderSpecificEntityManagerInterface(HIBERNATE52_ENTITY_MANAGER_INTERFACE);
assertThat(fromEntityManager(em), is(HIBERNATE));
}
private EntityManager mockProviderSpecificEntityManagerInterface(String interfaceName) throws ClassNotFoundException {
Class<?> providerSpecificEntityManagerInterface = InterfaceGenerator.generate(interfaceName, shadowingClassLoader,

View File

@@ -21,12 +21,16 @@ import javax.enterprise.inject.Produces;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import org.hibernate.Version;
class EntityManagerFactoryProducer {
@Produces
@ApplicationScoped
public EntityManagerFactory createEntityManagerFactory() {
return Persistence.createEntityManagerFactory("cdi");
String hibernateVersion = Version.getVersionString();
return Persistence.createEntityManagerFactory(hibernateVersion.startsWith("5.2") ? "cdi-52" : "cdi");
}
public void close(@Disposes EntityManagerFactory entityManagerFactory) {

View File

@@ -35,6 +35,7 @@ import javax.persistence.Persistence;
import javax.persistence.PersistenceContext;
import javax.persistence.metamodel.Metamodel;
import org.hibernate.Version;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -333,7 +334,7 @@ public class JpaMetamodelEntityInformationIntegrationTests {
}
protected String getMetadadataPersitenceUnitName() {
return "metadata";
return Version.getVersionString().startsWith("5.2") ? "metadata-52" : "metadata";
}
@SuppressWarnings("serial")

View File

@@ -71,7 +71,26 @@
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
<persistence-unit name="cdi-52">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>org.springframework.data.jpa.domain.sample.MailMessage</class>
<class>org.springframework.data.jpa.domain.sample.MailSender</class>
<class>org.springframework.data.jpa.domain.sample.MailUser</class>
<class>org.springframework.data.jpa.domain.sample.User</class>
<class>org.springframework.data.jpa.repository.cdi.Person</class>
<class>org.springframework.data.jpa.domain.sample.Dummy</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.connection.username" value="sa" />
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
<property name="hibernate.connection.password" value="" />
<property name="hibernate.connection.url" value="jdbc:hsqldb:mem:cdi" />
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
<!-- DATAJPA-476 -->
<persistence-unit name="merchant">
<class>org.springframework.data.jpa.domain.sample.User</class>
@@ -99,6 +118,19 @@
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
</properties>
</persistence-unit>
<persistence-unit name="metadata-52">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>org.springframework.data.jpa.domain.sample.CustomAbstractPersistable</class>
<class>org.springframework.data.jpa.domain.sample.MailMessage</class>
<class>org.springframework.data.jpa.domain.sample.MailSender</class>
<class>org.springframework.data.jpa.domain.sample.MailUser</class>
<class>org.springframework.data.jpa.domain.sample.User</class>
<class>org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformationIntegrationTests$Sample</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
</properties>
</persistence-unit>
<persistence-unit name="metadata_el">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>org.springframework.data.jpa.domain.sample.CustomAbstractPersistable</class>