Skip to content

Commit f9c3910

Browse files
committed
Support for Hibernate ORM 5.0 Beta 2
Issue: SPR-11694
1 parent 1e04643 commit f9c3910

30 files changed

+5631
-19
lines changed

build.gradle

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,21 @@ project("spring-orm-hibernate4") {
827827
}
828828
}
829829

830+
project("spring-orm-hibernate5") {
831+
description = "Spring Object/Relational Mapping - Hibernate 5 support"
832+
merge.into = project(":spring-orm")
833+
834+
dependencies {
835+
provided(project(":spring-jdbc"))
836+
provided(project(":spring-tx"))
837+
optional(project(":spring-web"))
838+
optional("org.hibernate:hibernate-core:5.0.0.Beta2")
839+
optional("org.hibernate:hibernate-entitymanager:5.0.0.Beta2")
840+
optional("javax.servlet:javax.servlet-api:3.0.1")
841+
optional("aopalliance:aopalliance:1.0")
842+
}
843+
}
844+
830845
project("spring-webmvc") {
831846
description = "Spring Web MVC"
832847

settings.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ include "spring-jms"
1515
include "spring-messaging"
1616
include "spring-orm"
1717
include "spring-orm-hibernate4"
18+
include "spring-orm-hibernate5"
1819
include "spring-oxm"
1920
include "spring-test"
2021
include "spring-tx"
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2014 the original author or authors.
2+
* Copyright 2002-2015 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,6 +16,8 @@
1616

1717
package org.springframework.orm.jpa.vendor;
1818

19+
import java.util.ArrayList;
20+
import java.util.List;
1921
import java.util.Map;
2022
import javax.persistence.EntityManagerFactory;
2123
import javax.persistence.spi.PersistenceUnitInfo;
@@ -24,7 +26,6 @@
2426
import org.hibernate.jpa.HibernatePersistenceProvider;
2527
import org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl;
2628
import org.hibernate.jpa.boot.internal.PersistenceUnitInfoDescriptor;
27-
import org.hibernate.service.ServiceRegistry;
2829

2930
import org.springframework.orm.jpa.persistenceunit.SmartPersistenceUnitInfo;
3031

@@ -33,7 +34,7 @@
3334
* from the {@code org.hibernate.jpa} package, adding support for
3435
* {@link SmartPersistenceUnitInfo#getManagedPackages()}.
3536
*
36-
* <p>Compatible with Hibernate 4.3. {@link SpringHibernateEjbPersistenceProvider}
37+
* <p>Compatible with Hibernate 4.3-5.0. {@link SpringHibernateEjbPersistenceProvider}
3738
* is an alternative for compatibility with earlier Hibernate versions (3.6-4.2).
3839
*
3940
* @author Juergen Hoeller
@@ -45,19 +46,18 @@ class SpringHibernateJpaPersistenceProvider extends HibernatePersistenceProvider
4546

4647
@Override
4748
@SuppressWarnings("rawtypes")
48-
public EntityManagerFactory createContainerEntityManagerFactory(final PersistenceUnitInfo info, Map properties) {
49-
return new EntityManagerFactoryBuilderImpl(new PersistenceUnitInfoDescriptor(info), properties) {
50-
@Override
51-
public Configuration buildHibernateConfiguration(ServiceRegistry serviceRegistry) {
52-
Configuration configuration = super.buildHibernateConfiguration(serviceRegistry);
53-
if (info instanceof SmartPersistenceUnitInfo) {
54-
for (String managedPackage : ((SmartPersistenceUnitInfo) info).getManagedPackages()) {
55-
configuration.addPackage(managedPackage);
49+
public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map properties) {
50+
final List<String> mergedClassesAndPackages = new ArrayList<String>(info.getManagedClassNames());
51+
if (info instanceof SmartPersistenceUnitInfo) {
52+
mergedClassesAndPackages.addAll(((SmartPersistenceUnitInfo) info).getManagedPackages());
53+
}
54+
return new EntityManagerFactoryBuilderImpl(
55+
new PersistenceUnitInfoDescriptor(info) {
56+
@Override
57+
public List<String> getManagedClassNames() {
58+
return mergedClassesAndPackages;
5659
}
57-
}
58-
return configuration;
59-
}
60-
}.build();
60+
}, properties).build();
6161
}
6262

6363
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
* Copyright 2002-2015 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.orm.hibernate5;
18+
19+
import javax.transaction.Status;
20+
import javax.transaction.Synchronization;
21+
import javax.transaction.SystemException;
22+
import javax.transaction.Transaction;
23+
import javax.transaction.TransactionManager;
24+
import javax.transaction.TransactionSynchronizationRegistry;
25+
import javax.transaction.UserTransaction;
26+
27+
import org.hibernate.TransactionException;
28+
import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
29+
30+
import org.springframework.transaction.jta.UserTransactionAdapter;
31+
import org.springframework.util.Assert;
32+
33+
/**
34+
* Implementation of Hibernate 4's JtaPlatform SPI, exposing passed-in {@link TransactionManager},
35+
* {@link UserTransaction} and {@link TransactionSynchronizationRegistry} references.
36+
*
37+
* @author Juergen Hoeller
38+
* @since 4.2
39+
*/
40+
@SuppressWarnings("serial")
41+
class ConfigurableJtaPlatform implements JtaPlatform {
42+
43+
private final TransactionManager transactionManager;
44+
45+
private final UserTransaction userTransaction;
46+
47+
private final TransactionSynchronizationRegistry transactionSynchronizationRegistry;
48+
49+
50+
/**
51+
* Create a new ConfigurableJtaPlatform instance with the given
52+
* JTA TransactionManager and optionally a given UserTransaction.
53+
* @param tm the JTA TransactionManager reference (required)
54+
* @param ut the JTA UserTransaction reference (optional)
55+
* @param tsr the JTA 1.1 TransactionSynchronizationRegistry (optional)
56+
*/
57+
public ConfigurableJtaPlatform(TransactionManager tm, UserTransaction ut, TransactionSynchronizationRegistry tsr) {
58+
Assert.notNull(tm, "TransactionManager reference must not be null");
59+
this.transactionManager = tm;
60+
this.userTransaction = (ut != null ? ut : new UserTransactionAdapter(tm));
61+
this.transactionSynchronizationRegistry = tsr;
62+
}
63+
64+
65+
@Override
66+
public TransactionManager retrieveTransactionManager() {
67+
return this.transactionManager;
68+
}
69+
70+
@Override
71+
public UserTransaction retrieveUserTransaction() {
72+
return this.userTransaction;
73+
}
74+
75+
@Override
76+
public Object getTransactionIdentifier(Transaction transaction) {
77+
return transaction;
78+
}
79+
80+
@Override
81+
public boolean canRegisterSynchronization() {
82+
try {
83+
return (this.transactionManager.getStatus() == Status.STATUS_ACTIVE);
84+
}
85+
catch (SystemException ex) {
86+
throw new TransactionException("Could not determine JTA transaction status", ex);
87+
}
88+
}
89+
90+
@Override
91+
public void registerSynchronization(Synchronization synchronization) {
92+
if (this.transactionSynchronizationRegistry != null) {
93+
this.transactionSynchronizationRegistry.registerInterposedSynchronization(synchronization);
94+
}
95+
else {
96+
try {
97+
this.transactionManager.getTransaction().registerSynchronization(synchronization);
98+
}
99+
catch (Exception ex) {
100+
throw new TransactionException("Could not access JTA Transaction to register synchronization", ex);
101+
}
102+
}
103+
}
104+
105+
@Override
106+
public int getCurrentStatus() throws SystemException {
107+
return this.transactionManager.getStatus();
108+
}
109+
110+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright 2002-2015 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.orm.hibernate5;
18+
19+
import org.hibernate.HibernateException;
20+
import org.hibernate.Session;
21+
22+
/**
23+
* Callback interface for Hibernate code. To be used with {@link HibernateTemplate}'s
24+
* execution methods, often as anonymous classes within a method implementation.
25+
* A typical implementation will call {@code Session.load/find/update} to perform
26+
* some operations on persistent objects.
27+
*
28+
* @author Juergen Hoeller
29+
* @since 4.2
30+
* @see HibernateTemplate
31+
* @see HibernateTransactionManager
32+
*/
33+
public interface HibernateCallback<T> {
34+
35+
/**
36+
* Gets called by {@code HibernateTemplate.execute} with an active
37+
* Hibernate {@code Session}. Does not need to care about activating
38+
* or closing the {@code Session}, or handling transactions.
39+
*
40+
* <p>Allows for returning a result object created within the callback,
41+
* i.e. a domain object or a collection of domain objects.
42+
* A thrown custom RuntimeException is treated as an application exception:
43+
* It gets propagated to the caller of the template.
44+
*
45+
* @param session active Hibernate session
46+
* @return a result object, or {@code null} if none
47+
* @throws HibernateException if thrown by the Hibernate API
48+
* @see HibernateTemplate#execute
49+
*/
50+
T doInHibernate(Session session) throws HibernateException;
51+
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright 2002-2015 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.orm.hibernate5;
18+
19+
import org.hibernate.HibernateException;
20+
21+
import org.springframework.dao.DataAccessException;
22+
import org.springframework.dao.support.PersistenceExceptionTranslator;
23+
24+
/**
25+
* {@link PersistenceExceptionTranslator} capable of translating {@link HibernateException}
26+
* instances to Spring's {@link DataAccessException} hierarchy.
27+
*
28+
* <p>Extended by {@link LocalSessionFactoryBean}, so there is no need to declare this
29+
* translator in addition to a {@code LocalSessionFactoryBean}.
30+
*
31+
* <p>When configuring the container with {@code @Configuration} classes, a {@code @Bean}
32+
* of this type must be registered manually.
33+
*
34+
* @author Juergen Hoeller
35+
* @since 4.2
36+
* @see org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor
37+
* @see SessionFactoryUtils#convertHibernateAccessException(HibernateException)
38+
*/
39+
public class HibernateExceptionTranslator implements PersistenceExceptionTranslator {
40+
41+
@Override
42+
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
43+
if (ex instanceof HibernateException) {
44+
return convertHibernateAccessException((HibernateException) ex);
45+
}
46+
return null;
47+
}
48+
49+
/**
50+
* Convert the given HibernateException to an appropriate exception from the
51+
* {@code org.springframework.dao} hierarchy.
52+
* @param ex HibernateException that occured
53+
* @return a corresponding DataAccessException
54+
* @see SessionFactoryUtils#convertHibernateAccessException
55+
*/
56+
protected DataAccessException convertHibernateAccessException(HibernateException ex) {
57+
return SessionFactoryUtils.convertHibernateAccessException(ex);
58+
}
59+
60+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright 2002-2015 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.orm.hibernate5;
18+
19+
import java.sql.SQLException;
20+
21+
import org.hibernate.JDBCException;
22+
23+
import org.springframework.dao.UncategorizedDataAccessException;
24+
25+
/**
26+
* Hibernate-specific subclass of UncategorizedDataAccessException,
27+
* for JDBC exceptions that Hibernate wrapped.
28+
*
29+
* @author Juergen Hoeller
30+
* @since 4.2
31+
* @see SessionFactoryUtils#convertHibernateAccessException
32+
*/
33+
@SuppressWarnings("serial")
34+
public class HibernateJdbcException extends UncategorizedDataAccessException {
35+
36+
public HibernateJdbcException(JDBCException ex) {
37+
super("JDBC exception on Hibernate data access: SQLException for SQL [" + ex.getSQL() + "]; SQL state [" +
38+
ex.getSQLState() + "]; error code [" + ex.getErrorCode() + "]; " + ex.getMessage(), ex);
39+
}
40+
41+
/**
42+
* Return the underlying SQLException.
43+
*/
44+
public SQLException getSQLException() {
45+
return ((JDBCException) getCause()).getSQLException();
46+
}
47+
48+
/**
49+
* Return the SQL that led to the problem.
50+
*/
51+
public String getSql() {
52+
return ((JDBCException) getCause()).getSQL();
53+
}
54+
55+
}

0 commit comments

Comments
 (0)