diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java index 33d53bf922..9db0fec7dc 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java @@ -24,11 +24,13 @@ import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Properties; import javax.validation.Configuration; import javax.validation.ConstraintValidatorFactory; import javax.validation.MessageInterpolator; +import javax.validation.ParameterNameProvider; import javax.validation.TraversableResolver; import javax.validation.Validation; import javax.validation.ValidationProviderResolver; @@ -66,14 +68,8 @@ import org.springframework.util.ReflectionUtils; * you will almost always use the default Validator anyway. This can also be injected directly * into any target dependency of type {@link org.springframework.validation.Validator}! * - *

As of Spring 4.0, this class supports Bean Validation 1.0 and 1.1, with special support - * for Hibernate Validator 4.3 and 5.x (see {@link #setValidationMessageSource}). - * - *

Note that Bean Validation 1.1's {@code #forExecutables} method isn't supported: We do not - * expect that method to be called by application code; consider {@link MethodValidationInterceptor} - * instead. If you really need programmatic {@code #forExecutables} access, inject this class as - * a {@link ValidatorFactory} and call {@link #getValidator()} on it, then {@code #forExecutables} - * on the returned native {@link Validator} reference instead of directly on this class. + *

As of Spring 5.0, this class requires Bean Validation 1.1, with special support + * for Hibernate Validator 5.x (see {@link #setValidationMessageSource}). * *

This class is also being used by Spring's MVC configuration namespace, in case of the * {@code javax.validation} API being present but no explicit Validator having been configured. @@ -88,10 +84,6 @@ import org.springframework.util.ReflectionUtils; public class LocalValidatorFactoryBean extends SpringValidatorAdapter implements ValidatorFactory, ApplicationContextAware, InitializingBean, DisposableBean { - // Bean Validation 1.1 close() method available? - private static final Method closeMethod = ClassUtils.getMethodIfAvailable(ValidatorFactory.class, "close"); - - @SuppressWarnings("rawtypes") private Class providerClass; @@ -305,55 +297,23 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter } private void configureParameterNameProviderIfPossible(Configuration configuration) { - try { - Class parameterNameProviderClass = - ClassUtils.forName("javax.validation.ParameterNameProvider", getClass().getClassLoader()); - Method parameterNameProviderMethod = - Configuration.class.getMethod("parameterNameProvider", parameterNameProviderClass); - final Object defaultProvider = ReflectionUtils.invokeMethod( - Configuration.class.getMethod("getDefaultParameterNameProvider"), configuration); - final ParameterNameDiscoverer discoverer = this.parameterNameDiscoverer; - Object parameterNameProvider = Proxy.newProxyInstance(getClass().getClassLoader(), - new Class[] {parameterNameProviderClass}, new InvocationHandler() { - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - if (method.getName().equals("getParameterNames")) { - String[] result = null; - if (args[0] instanceof Constructor) { - result = discoverer.getParameterNames((Constructor) args[0]); - } - else if (args[0] instanceof Method) { - result = discoverer.getParameterNames((Method) args[0]); - } - if (result != null) { - return Arrays.asList(result); - } - else { - try { - return method.invoke(defaultProvider, args); - } - catch (InvocationTargetException ex) { - throw ex.getTargetException(); - } - } - } - else { - // toString, equals, hashCode - try { - return method.invoke(this, args); - } - catch (InvocationTargetException ex) { - throw ex.getTargetException(); - } - } - } - }); - ReflectionUtils.invokeMethod(parameterNameProviderMethod, configuration, parameterNameProvider); - - } - catch (Exception ex) { - // Bean Validation 1.1 API not available - simply not applying the ParameterNameDiscoverer - } + // TODO: inner class + final ParameterNameDiscoverer discoverer = this.parameterNameDiscoverer; + final ParameterNameProvider defaultProvider = configuration.getDefaultParameterNameProvider(); + configuration.parameterNameProvider(new ParameterNameProvider() { + @Override + public List getParameterNames(Constructor constructor) { + String[] paramNames = discoverer.getParameterNames(constructor); + return (paramNames != null ? Arrays.asList(paramNames) : + defaultProvider.getParameterNames(constructor)); + } + @Override + public List getParameterNames(Method method) { + String[] paramNames = discoverer.getParameterNames(method); + return (paramNames != null ? Arrays.asList(paramNames) : + defaultProvider.getParameterNames(method)); + } + }); } /** @@ -397,9 +357,14 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter return this.validatorFactory.getConstraintValidatorFactory(); } + @Override + public ParameterNameProvider getParameterNameProvider() { + return this.validatorFactory.getParameterNameProvider(); + } + public void close() { - if (closeMethod != null && this.validatorFactory != null) { - ReflectionUtils.invokeMethod(closeMethod, this.validatorFactory); + if (this.validatorFactory != null) { + this.validatorFactory.close(); } } diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationInterceptor.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationInterceptor.java index 697944e69a..7edbacc1b5 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationInterceptor.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,6 @@ import javax.validation.ValidatorFactory; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; -import org.hibernate.validator.HibernateValidator; import org.springframework.core.BridgeMethodResolver; import org.springframework.core.annotation.AnnotationUtils; @@ -48,9 +47,8 @@ import org.springframework.validation.annotation.Validated; * at the type level of the containing target class, applying to all public service methods * of that class. By default, JSR-303 will validate against its default group only. * - *

As of Spring 4.0, this functionality requires either a Bean Validation 1.1 provider - * (such as Hibernate Validator 5.x) or the Bean Validation 1.0 API with Hibernate Validator - * 4.3. The actual provider will be autodetected and automatically adapted. + *

As of Spring 5.0, this functionality requires a Bean Validation 1.1 provider + * (such as Hibernate Validator 5.x). * * @author Juergen Hoeller * @since 3.1 @@ -88,8 +86,7 @@ public class MethodValidationInterceptor implements MethodInterceptor { * Create a new MethodValidationInterceptor using a default JSR-303 validator underneath. */ public MethodValidationInterceptor() { - this(forExecutablesMethod != null ? Validation.buildDefaultValidatorFactory() : - HibernateValidatorDelegate.buildValidatorFactory()); + this(Validation.buildDefaultValidatorFactory()); } /** @@ -114,43 +111,36 @@ public class MethodValidationInterceptor implements MethodInterceptor { public Object invoke(MethodInvocation invocation) throws Throwable { Class[] groups = determineValidationGroups(invocation); - if (forExecutablesMethod != null) { - // Standard Bean Validation 1.1 API - Object execVal = ReflectionUtils.invokeMethod(forExecutablesMethod, this.validator); - Method methodToValidate = invocation.getMethod(); - Set> result; + // Standard Bean Validation 1.1 API + Object execVal = ReflectionUtils.invokeMethod(forExecutablesMethod, this.validator); + Method methodToValidate = invocation.getMethod(); + Set> result; - try { - result = (Set>) ReflectionUtils.invokeMethod(validateParametersMethod, - execVal, invocation.getThis(), methodToValidate, invocation.getArguments(), groups); - } - catch (IllegalArgumentException ex) { - // Probably a generic type mismatch between interface and impl as reported in SPR-12237 / HV-1011 - // Let's try to find the bridged method on the implementation class... - methodToValidate = BridgeMethodResolver.findBridgedMethod( - ClassUtils.getMostSpecificMethod(invocation.getMethod(), invocation.getThis().getClass())); - result = (Set>) ReflectionUtils.invokeMethod(validateParametersMethod, - execVal, invocation.getThis(), methodToValidate, invocation.getArguments(), groups); - } - if (!result.isEmpty()) { - throw new ConstraintViolationException(result); - } - - Object returnValue = invocation.proceed(); - - result = (Set>) ReflectionUtils.invokeMethod(validateReturnValueMethod, - execVal, invocation.getThis(), methodToValidate, returnValue, groups); - if (!result.isEmpty()) { - throw new ConstraintViolationException(result); - } - - return returnValue; + try { + result = (Set>) ReflectionUtils.invokeMethod(validateParametersMethod, + execVal, invocation.getThis(), methodToValidate, invocation.getArguments(), groups); + } + catch (IllegalArgumentException ex) { + // Probably a generic type mismatch between interface and impl as reported in SPR-12237 / HV-1011 + // Let's try to find the bridged method on the implementation class... + methodToValidate = BridgeMethodResolver.findBridgedMethod( + ClassUtils.getMostSpecificMethod(invocation.getMethod(), invocation.getThis().getClass())); + result = (Set>) ReflectionUtils.invokeMethod(validateParametersMethod, + execVal, invocation.getThis(), methodToValidate, invocation.getArguments(), groups); + } + if (!result.isEmpty()) { + throw new ConstraintViolationException(result); } - else { - // Hibernate Validator 4.3's native API - return HibernateValidatorDelegate.invokeWithinValidation(invocation, this.validator, groups); + Object returnValue = invocation.proceed(); + + result = (Set>) ReflectionUtils.invokeMethod(validateReturnValueMethod, + execVal, invocation.getThis(), methodToValidate, returnValue, groups); + if (!result.isEmpty()) { + throw new ConstraintViolationException(result); } + + return returnValue; } /** @@ -168,36 +158,4 @@ public class MethodValidationInterceptor implements MethodInterceptor { return (validatedAnn != null ? validatedAnn.value() : new Class[0]); } - - /** - * Inner class to avoid a hard-coded Hibernate Validator 4.3 dependency. - */ - private static class HibernateValidatorDelegate { - - public static ValidatorFactory buildValidatorFactory() { - return Validation.byProvider(HibernateValidator.class).configure().buildValidatorFactory(); - } - - @SuppressWarnings("deprecation") - public static Object invokeWithinValidation(MethodInvocation invocation, Validator validator, Class[] groups) - throws Throwable { - - org.hibernate.validator.method.MethodValidator methodValidator = - validator.unwrap(org.hibernate.validator.method.MethodValidator.class); - Set> result = - methodValidator.validateAllParameters( - invocation.getThis(), invocation.getMethod(), invocation.getArguments(), groups); - if (!result.isEmpty()) { - throw new org.hibernate.validator.method.MethodConstraintViolationException(result); - } - Object returnValue = invocation.proceed(); - result = methodValidator.validateReturnValue( - invocation.getThis(), invocation.getMethod(), returnValue, groups); - if (!result.isEmpty()) { - throw new org.hibernate.validator.method.MethodConstraintViolationException(result); - } - return returnValue; - } - } - } diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java index 6d46113d83..7640c52c63 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java @@ -24,6 +24,7 @@ import java.util.Map; import java.util.Set; import java.util.TreeMap; import javax.validation.ConstraintViolation; +import javax.validation.executable.ExecutableValidator; import javax.validation.metadata.BeanDescriptor; import javax.validation.metadata.ConstraintDescriptor; @@ -299,6 +300,11 @@ public class SpringValidatorAdapter implements SmartValidator, javax.validation. return (type != null ? this.targetValidator.unwrap(type) : (T) this.targetValidator); } + @Override + public ExecutableValidator forExecutables() { + return this.targetValidator.forExecutables(); + } + /** * Wrapper for a String attribute which can be resolved via a {@code MessageSource}, diff --git a/spring-context/src/test/java/org/springframework/validation/beanvalidation/BeanValidationPostProcessorTests.java b/spring-context/src/test/java/org/springframework/validation/beanvalidation/BeanValidationPostProcessorTests.java index bfe908f88d..6ebc2a0474 100644 --- a/spring-context/src/test/java/org/springframework/validation/beanvalidation/BeanValidationPostProcessorTests.java +++ b/spring-context/src/test/java/org/springframework/validation/beanvalidation/BeanValidationPostProcessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,10 +31,9 @@ import org.springframework.tests.sample.beans.TestBean; import static org.junit.Assert.*; /** - * Tested against Hibernate Validator 4.3, as of Spring 4.0. + * Tested against Hibernate Validator 5.x. * * @author Juergen Hoeller - * @since 3.0 */ public class BeanValidationPostProcessorTests { @@ -52,6 +51,7 @@ public class BeanValidationPostProcessorTests { assertTrue(ex.getRootCause().getMessage().contains("testBean")); assertTrue(ex.getRootCause().getMessage().contains("invalid")); } + ac.close(); } @Test @@ -63,6 +63,7 @@ public class BeanValidationPostProcessorTests { bd.getPropertyValues().add("testBean", new TestBean()); ac.registerBeanDefinition("bean", bd); ac.refresh(); + ac.close(); } @Test @@ -74,6 +75,7 @@ public class BeanValidationPostProcessorTests { ac.registerBeanDefinition("capp", new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class)); ac.registerBeanDefinition("bean", new RootBeanDefinition(AfterInitConstraintBean.class)); ac.refresh(); + ac.close(); } @Test @@ -92,6 +94,7 @@ public class BeanValidationPostProcessorTests { assertTrue(ex.getRootCause().getMessage().contains("stringValue")); assertTrue(ex.getRootCause().getMessage().contains("invalid")); } + ac.close(); } @Test @@ -103,6 +106,7 @@ public class BeanValidationPostProcessorTests { bd.getPropertyValues().add("stringValue", "ss"); ac.registerBeanDefinition("bean", bd); ac.refresh(); + ac.close(); } diff --git a/spring-context/src/test/java/org/springframework/validation/beanvalidation/MethodValidationTests.java b/spring-context/src/test/java/org/springframework/validation/beanvalidation/MethodValidationTests.java index 812b1d9ae1..a383d81b16 100644 --- a/spring-context/src/test/java/org/springframework/validation/beanvalidation/MethodValidationTests.java +++ b/spring-context/src/test/java/org/springframework/validation/beanvalidation/MethodValidationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,11 +35,11 @@ import org.springframework.validation.annotation.Validated; import static org.junit.Assert.*; /** - * Tested against Hibernate Validator 4.3, as of Spring 4.0. + * Tests against Hibernate Validator 5.x. * * @author Juergen Hoeller - * @since 3.1 */ +@SuppressWarnings("rawtypes") public class MethodValidationTests { @Test @@ -65,6 +65,7 @@ public class MethodValidationTests { } + @SuppressWarnings("unchecked") private void doTestProxyValidation(MyValidInterface proxy) { assertNotNull(proxy.myValidMethod("value", 5)); try { diff --git a/spring-context/src/test/java/org/springframework/validation/beanvalidation/ValidatorFactoryTests.java b/spring-context/src/test/java/org/springframework/validation/beanvalidation/ValidatorFactoryTests.java index 26138af537..144c6fd98f 100644 --- a/spring-context/src/test/java/org/springframework/validation/beanvalidation/ValidatorFactoryTests.java +++ b/spring-context/src/test/java/org/springframework/validation/beanvalidation/ValidatorFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,6 +38,10 @@ import javax.validation.constraints.NotNull; import org.hibernate.validator.HibernateValidator; import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.core.env.Environment; import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.validation.Errors; import org.springframework.validation.FieldError; @@ -47,10 +51,9 @@ import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; /** - * Tested against Hibernate Validator 4.3, as of Spring 4.0. + * Tests against Hibernate Validator 5.x. * * @author Juergen Hoeller - * @since 3.0 */ public class ValidatorFactoryTests { @@ -58,6 +61,7 @@ public class ValidatorFactoryTests { public void testSimpleValidation() throws Exception { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); Set> result = validator.validate(person); assertEquals(2, result.size()); @@ -78,6 +82,7 @@ public class ValidatorFactoryTests { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.setProviderClass(HibernateValidator.class); validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); Set> result = validator.validate(person); assertEquals(2, result.size()); @@ -112,6 +117,7 @@ public class ValidatorFactoryTests { public void testSpringValidationFieldType() throws Exception { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); person.setName("Phil"); person.getAddress().setStreet("Phil's Street"); @@ -126,6 +132,7 @@ public class ValidatorFactoryTests { public void testSpringValidation() throws Exception { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); validator.validate(person, result); @@ -153,6 +160,7 @@ public class ValidatorFactoryTests { public void testSpringValidationWithClassLevel() throws Exception { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); person.setName("Juergen"); person.getAddress().setStreet("Juergen's Street"); @@ -166,10 +174,32 @@ public class ValidatorFactoryTests { assertTrue(errorCodes.contains("NameAddressValid")); } + @Test + public void testSpringValidationWithAutowiredValidator() throws Exception { + ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext( + LocalValidatorFactoryBean.class); + LocalValidatorFactoryBean validator = ctx.getBean(LocalValidatorFactoryBean.class); + + ValidPerson person = new ValidPerson(); + person.expectsAutowiredValidator = true; + person.setName("Juergen"); + person.getAddress().setStreet("Juergen's Street"); + BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); + validator.validate(person, result); + assertEquals(1, result.getErrorCount()); + ObjectError globalError = result.getGlobalError(); + List errorCodes = Arrays.asList(globalError.getCodes()); + assertEquals(2, errorCodes.size()); + assertTrue(errorCodes.contains("NameAddressValid.person")); + assertTrue(errorCodes.contains("NameAddressValid")); + ctx.close(); + } + @Test public void testSpringValidationWithErrorInListElement() throws Exception { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); person.getAddressList().add(new ValidAddress()); BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); @@ -187,6 +217,7 @@ public class ValidatorFactoryTests { public void testSpringValidationWithErrorInSetElement() throws Exception { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); person.getAddressSet().add(new ValidAddress()); BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); @@ -240,6 +271,8 @@ public class ValidatorFactoryTests { @Valid private Set addressSet = new LinkedHashSet(); + public boolean expectsAutowiredValidator = false; + public String getName() { return name; } @@ -304,16 +337,22 @@ public class ValidatorFactoryTests { public static class NameAddressValidator implements ConstraintValidator { + @Autowired + private Environment environment; + @Override public void initialize(NameAddressValid constraintAnnotation) { } @Override public boolean isValid(ValidPerson value, ConstraintValidatorContext context) { + if (value.expectsAutowiredValidator) { + assertNotNull(this.environment); + } boolean valid = (value.name == null || !value.address.street.contains(value.name)); if (!valid && "Phil".equals(value.name)) { context.buildConstraintViolationWithTemplate( - context.getDefaultConstraintMessageTemplate()).addNode("address").addConstraintViolation().disableDefaultConstraintViolation(); + context.getDefaultConstraintMessageTemplate()).addPropertyNode("address").addConstraintViolation().disableDefaultConstraintViolation(); } return valid; } @@ -378,7 +417,7 @@ public class ValidatorFactoryTests { public boolean isValid(InnerBean bean, ConstraintValidatorContext context) { context.disableDefaultConstraintViolation(); if (bean.getValue() == null) { - context.buildConstraintViolationWithTemplate("NULL"). addNode("value").addConstraintViolation(); + context.buildConstraintViolationWithTemplate("NULL").addPropertyNode("value").addConstraintViolation(); return false; } return true; diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/ConfigurableJtaPlatform.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/ConfigurableJtaPlatform.java deleted file mode 100644 index 7942e65a3f..0000000000 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/ConfigurableJtaPlatform.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate4; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import javax.transaction.Status; -import javax.transaction.Synchronization; -import javax.transaction.SystemException; -import javax.transaction.Transaction; -import javax.transaction.TransactionManager; -import javax.transaction.TransactionSynchronizationRegistry; -import javax.transaction.UserTransaction; - -import org.hibernate.TransactionException; -import org.hibernate.service.Service; - -import org.springframework.transaction.jta.UserTransactionAdapter; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; - -/** - * Implementation of Hibernate 4's JtaPlatform SPI (which has a different package - * location in Hibernate 4.0-4.2 vs 4.3), exposing passed-in {@link TransactionManager}, - * {@link UserTransaction} and {@link TransactionSynchronizationRegistry} references. - * - * @author Juergen Hoeller - * @since 3.1.2 - */ -@SuppressWarnings({"serial", "unchecked"}) -class ConfigurableJtaPlatform implements InvocationHandler { - - static final Class jtaPlatformClass; - - static { - Class jpClass; - try { - // Try Hibernate 4.0-4.2 JtaPlatform variant - jpClass = ClassUtils.forName("org.hibernate.service.jta.platform.spi.JtaPlatform", - ConfigurableJtaPlatform.class.getClassLoader()); - } - catch (ClassNotFoundException ex) { - try { - // Try Hibernate 4.3 JtaPlatform variant - jpClass = ClassUtils.forName("org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform", - ConfigurableJtaPlatform.class.getClassLoader()); - } - catch (ClassNotFoundException ex2) { - throw new IllegalStateException("Neither Hibernate 4.0-4.2 nor 4.3 variant of JtaPlatform found"); - } - } - jtaPlatformClass = (Class) jpClass; - } - - static String getJtaPlatformBasePackage() { - String className = jtaPlatformClass.getName(); - return className.substring(0, className.length() - "spi.JtaPlatform".length()); - } - - - private final TransactionManager transactionManager; - - private final UserTransaction userTransaction; - - private final TransactionSynchronizationRegistry transactionSynchronizationRegistry; - - - /** - * Create a new ConfigurableJtaPlatform instance with the given - * JTA TransactionManager and optionally a given UserTransaction. - * @param tm the JTA TransactionManager reference (required) - * @param ut the JTA UserTransaction reference (optional) - * @param tsr the JTA 1.1 TransactionSynchronizationRegistry (optional) - */ - public ConfigurableJtaPlatform(TransactionManager tm, UserTransaction ut, TransactionSynchronizationRegistry tsr) { - Assert.notNull(tm, "TransactionManager reference must not be null"); - this.transactionManager = tm; - this.userTransaction = (ut != null ? ut : new UserTransactionAdapter(tm)); - this.transactionSynchronizationRegistry = tsr; - } - - - public TransactionManager retrieveTransactionManager() { - return this.transactionManager; - } - - public UserTransaction retrieveUserTransaction() { - return this.userTransaction; - } - - public Object getTransactionIdentifier(Transaction transaction) { - return transaction; - } - - public boolean canRegisterSynchronization() { - try { - return (this.transactionManager.getStatus() == Status.STATUS_ACTIVE); - } - catch (SystemException ex) { - throw new TransactionException("Could not determine JTA transaction status", ex); - } - } - - public void registerSynchronization(Synchronization synchronization) { - if (this.transactionSynchronizationRegistry != null) { - this.transactionSynchronizationRegistry.registerInterposedSynchronization(synchronization); - } - else { - try { - this.transactionManager.getTransaction().registerSynchronization(synchronization); - } - catch (Exception ex) { - throw new TransactionException("Could not access JTA Transaction to register synchronization", ex); - } - } - } - - public int getCurrentStatus() throws SystemException { - return this.transactionManager.getStatus(); - } - - - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - try { - return getClass().getMethod(method.getName(), method.getParameterTypes()).invoke(this, args); - } - catch (InvocationTargetException ex) { - throw ex.getTargetException(); - } - catch (Throwable ex) { - throw new IllegalStateException("Failed to delegate to corresponding implementation method", ex); - } - } - - /** - * Obtain a proxy that implements the current Hibernate version's JtaPlatform interface - * in the right package location, delegating all invocations to the same-named methods - * on this ConfigurableJtaPlatform class itself. - */ - public Object getJtaPlatformProxy() { - return Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] {jtaPlatformClass}, this); - } - -} diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateCallback.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateCallback.java deleted file mode 100644 index 66f78d6678..0000000000 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateCallback.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2002-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate4; - -import org.hibernate.HibernateException; -import org.hibernate.Session; - -/** - * Callback interface for Hibernate code. To be used with {@link HibernateTemplate}'s - * execution methods, often as anonymous classes within a method implementation. - * A typical implementation will call {@code Session.load/find/update} to perform - * some operations on persistent objects. - * - * @author Juergen Hoeller - * @since 4.0.1 - * @see HibernateTemplate - * @see HibernateTransactionManager - */ -public interface HibernateCallback { - - /** - * Gets called by {@code HibernateTemplate.execute} with an active - * Hibernate {@code Session}. Does not need to care about activating - * or closing the {@code Session}, or handling transactions. - *

Allows for returning a result object created within the callback, - * i.e. a domain object or a collection of domain objects. - * A thrown custom RuntimeException is treated as an application exception: - * It gets propagated to the caller of the template. - * @param session active Hibernate session - * @return a result object, or {@code null} if none - * @throws HibernateException if thrown by the Hibernate API - * @see HibernateTemplate#execute - */ - T doInHibernate(Session session) throws HibernateException; - -} diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateExceptionTranslator.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateExceptionTranslator.java deleted file mode 100644 index 7223e8d7da..0000000000 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateExceptionTranslator.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate4; - -import org.hibernate.HibernateException; - -import org.springframework.dao.DataAccessException; -import org.springframework.dao.support.PersistenceExceptionTranslator; - -/** - * {@link PersistenceExceptionTranslator} capable of translating {@link HibernateException} - * instances to Spring's {@link DataAccessException} hierarchy. - * - *

Extended by {@link LocalSessionFactoryBean}, so there is no need to declare this - * translator in addition to a {@code LocalSessionFactoryBean}. - * - *

When configuring the container with {@code @Configuration} classes, a {@code @Bean} - * of this type must be registered manually. - * - * @author Juergen Hoeller - * @since 3.1 - * @see org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor - * @see SessionFactoryUtils#convertHibernateAccessException(HibernateException) - */ -public class HibernateExceptionTranslator implements PersistenceExceptionTranslator { - - @Override - public DataAccessException translateExceptionIfPossible(RuntimeException ex) { - if (ex instanceof HibernateException) { - return convertHibernateAccessException((HibernateException) ex); - } - return null; - } - - /** - * Convert the given HibernateException to an appropriate exception from the - * {@code org.springframework.dao} hierarchy. - * @param ex HibernateException that occured - * @return a corresponding DataAccessException - * @see SessionFactoryUtils#convertHibernateAccessException - */ - protected DataAccessException convertHibernateAccessException(HibernateException ex) { - return SessionFactoryUtils.convertHibernateAccessException(ex); - } - -} diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateJdbcException.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateJdbcException.java deleted file mode 100644 index 96c1a5f4b2..0000000000 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateJdbcException.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate4; - -import java.sql.SQLException; - -import org.hibernate.JDBCException; - -import org.springframework.dao.UncategorizedDataAccessException; - -/** - * Hibernate-specific subclass of UncategorizedDataAccessException, - * for JDBC exceptions that Hibernate wrapped. - * - * @author Juergen Hoeller - * @since 3.1 - * @see SessionFactoryUtils#convertHibernateAccessException - */ -@SuppressWarnings("serial") -public class HibernateJdbcException extends UncategorizedDataAccessException { - - public HibernateJdbcException(JDBCException ex) { - super("JDBC exception on Hibernate data access: SQLException for SQL [" + ex.getSQL() + "]; SQL state [" + - ex.getSQLState() + "]; error code [" + ex.getErrorCode() + "]; " + ex.getMessage(), ex); - } - - /** - * Return the underlying SQLException. - */ - public SQLException getSQLException() { - return ((JDBCException) getCause()).getSQLException(); - } - - /** - * Return the SQL that led to the problem. - */ - public String getSql() { - return ((JDBCException) getCause()).getSQL(); - } - -} diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateObjectRetrievalFailureException.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateObjectRetrievalFailureException.java deleted file mode 100644 index ce496de76d..0000000000 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateObjectRetrievalFailureException.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate4; - -import org.hibernate.UnresolvableObjectException; -import org.hibernate.WrongClassException; - -import org.springframework.orm.ObjectRetrievalFailureException; - -/** - * Hibernate-specific subclass of ObjectRetrievalFailureException. - * Converts Hibernate's UnresolvableObjectException and WrongClassException. - * - * @author Juergen Hoeller - * @since 3.1 - * @see SessionFactoryUtils#convertHibernateAccessException - */ -@SuppressWarnings("serial") -public class HibernateObjectRetrievalFailureException extends ObjectRetrievalFailureException { - - public HibernateObjectRetrievalFailureException(UnresolvableObjectException ex) { - super(ex.getEntityName(), ex.getIdentifier(), ex.getMessage(), ex); - } - - public HibernateObjectRetrievalFailureException(WrongClassException ex) { - super(ex.getEntityName(), ex.getIdentifier(), ex.getMessage(), ex); - } - -} diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateOperations.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateOperations.java deleted file mode 100644 index a4858909a8..0000000000 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateOperations.java +++ /dev/null @@ -1,795 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate4; - -import java.io.Serializable; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; - -import org.hibernate.Filter; -import org.hibernate.LockMode; -import org.hibernate.ReplicationMode; -import org.hibernate.criterion.DetachedCriteria; - -import org.springframework.dao.DataAccessException; - -/** - * Interface that specifies a basic set of Hibernate operations, - * implemented by {@link HibernateTemplate}. Not often used, but a useful - * option to enhance testability, as it can easily be mocked or stubbed. - * - *

Defines {@code HibernateTemplate}'s data access methods that - * mirror various {@link org.hibernate.Session} methods. Users are - * strongly encouraged to read the Hibernate {@code Session} javadocs - * for details on the semantics of those methods. - * - * @author Juergen Hoeller - * @since 4.0.1 - * @see HibernateTemplate - * @see org.hibernate.Session - * @see HibernateTransactionManager - */ -public interface HibernateOperations { - - /** - * Execute the action specified by the given action object within a - * {@link org.hibernate.Session}. - *

Application exceptions thrown by the action object get propagated - * to the caller (can only be unchecked). Hibernate exceptions are - * transformed into appropriate DAO ones. Allows for returning a result - * object, that is a domain object or a collection of domain objects. - *

Note: Callback code is not supposed to handle transactions itself! - * Use an appropriate transaction manager like - * {@link HibernateTransactionManager}. Generally, callback code must not - * touch any {@code Session} lifecycle methods, like close, - * disconnect, or reconnect, to let the template do its work. - * @param action callback object that specifies the Hibernate action - * @return a result object returned by the action, or {@code null} - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see HibernateTransactionManager - * @see org.hibernate.Session - */ - T execute(HibernateCallback action) throws DataAccessException; - - - //------------------------------------------------------------------------- - // Convenience methods for loading individual objects - //------------------------------------------------------------------------- - - /** - * Return the persistent instance of the given entity class - * with the given identifier, or {@code null} if not found. - *

This method is a thin wrapper around - * {@link org.hibernate.Session#get(Class, java.io.Serializable)} for convenience. - * For an explanation of the exact semantics of this method, please do refer to - * the Hibernate API documentation in the first instance. - * @param entityClass a persistent class - * @param id the identifier of the persistent instance - * @return the persistent instance, or {@code null} if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#get(Class, java.io.Serializable) - */ - T get(Class entityClass, Serializable id) throws DataAccessException; - - /** - * Return the persistent instance of the given entity class - * with the given identifier, or {@code null} if not found. - *

Obtains the specified lock mode if the instance exists. - *

This method is a thin wrapper around - * {@link org.hibernate.Session#get(Class, java.io.Serializable, LockMode)} for convenience. - * For an explanation of the exact semantics of this method, please do refer to - * the Hibernate API documentation in the first instance. - * @param entityClass a persistent class - * @param id the identifier of the persistent instance - * @param lockMode the lock mode to obtain - * @return the persistent instance, or {@code null} if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#get(Class, java.io.Serializable, org.hibernate.LockMode) - */ - T get(Class entityClass, Serializable id, LockMode lockMode) throws DataAccessException; - - /** - * Return the persistent instance of the given entity class - * with the given identifier, or {@code null} if not found. - *

This method is a thin wrapper around - * {@link org.hibernate.Session#get(String, java.io.Serializable)} for convenience. - * For an explanation of the exact semantics of this method, please do refer to - * the Hibernate API documentation in the first instance. - * @param entityName the name of the persistent entity - * @param id the identifier of the persistent instance - * @return the persistent instance, or {@code null} if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#get(Class, java.io.Serializable) - */ - Object get(String entityName, Serializable id) throws DataAccessException; - - /** - * Return the persistent instance of the given entity class - * with the given identifier, or {@code null} if not found. - * Obtains the specified lock mode if the instance exists. - *

This method is a thin wrapper around - * {@link org.hibernate.Session#get(String, java.io.Serializable, LockMode)} for convenience. - * For an explanation of the exact semantics of this method, please do refer to - * the Hibernate API documentation in the first instance. - * @param entityName the name of the persistent entity - * @param id the identifier of the persistent instance - * @param lockMode the lock mode to obtain - * @return the persistent instance, or {@code null} if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#get(Class, java.io.Serializable, org.hibernate.LockMode) - */ - Object get(String entityName, Serializable id, LockMode lockMode) throws DataAccessException; - - /** - * Return the persistent instance of the given entity class - * with the given identifier, throwing an exception if not found. - *

This method is a thin wrapper around - * {@link org.hibernate.Session#load(Class, java.io.Serializable)} for convenience. - * For an explanation of the exact semantics of this method, please do refer to - * the Hibernate API documentation in the first instance. - * @param entityClass a persistent class - * @param id the identifier of the persistent instance - * @return the persistent instance - * @throws org.springframework.orm.ObjectRetrievalFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#load(Class, java.io.Serializable) - */ - T load(Class entityClass, Serializable id) throws DataAccessException; - - /** - * Return the persistent instance of the given entity class - * with the given identifier, throwing an exception if not found. - * Obtains the specified lock mode if the instance exists. - *

This method is a thin wrapper around - * {@link org.hibernate.Session#load(Class, java.io.Serializable, LockMode)} for convenience. - * For an explanation of the exact semantics of this method, please do refer to - * the Hibernate API documentation in the first instance. - * @param entityClass a persistent class - * @param id the identifier of the persistent instance - * @param lockMode the lock mode to obtain - * @return the persistent instance - * @throws org.springframework.orm.ObjectRetrievalFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#load(Class, java.io.Serializable) - */ - T load(Class entityClass, Serializable id, LockMode lockMode) throws DataAccessException; - - /** - * Return the persistent instance of the given entity class - * with the given identifier, throwing an exception if not found. - *

This method is a thin wrapper around - * {@link org.hibernate.Session#load(String, java.io.Serializable)} for convenience. - * For an explanation of the exact semantics of this method, please do refer to - * the Hibernate API documentation in the first instance. - * @param entityName the name of the persistent entity - * @param id the identifier of the persistent instance - * @return the persistent instance - * @throws org.springframework.orm.ObjectRetrievalFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#load(Class, java.io.Serializable) - */ - Object load(String entityName, Serializable id) throws DataAccessException; - - /** - * Return the persistent instance of the given entity class - * with the given identifier, throwing an exception if not found. - *

Obtains the specified lock mode if the instance exists. - *

This method is a thin wrapper around - * {@link org.hibernate.Session#load(String, java.io.Serializable, LockMode)} for convenience. - * For an explanation of the exact semantics of this method, please do refer to - * the Hibernate API documentation in the first instance. - * @param entityName the name of the persistent entity - * @param id the identifier of the persistent instance - * @param lockMode the lock mode to obtain - * @return the persistent instance - * @throws org.springframework.orm.ObjectRetrievalFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#load(Class, java.io.Serializable) - */ - Object load(String entityName, Serializable id, LockMode lockMode) throws DataAccessException; - - /** - * Return all persistent instances of the given entity class. - * Note: Use queries or criteria for retrieving a specific subset. - * @param entityClass a persistent class - * @return a {@link List} containing 0 or more persistent instances - * @throws org.springframework.dao.DataAccessException if there is a Hibernate error - * @see org.hibernate.Session#createCriteria - */ - List loadAll(Class entityClass) throws DataAccessException; - - /** - * Load the persistent instance with the given identifier - * into the given object, throwing an exception if not found. - *

This method is a thin wrapper around - * {@link org.hibernate.Session#load(Object, java.io.Serializable)} for convenience. - * For an explanation of the exact semantics of this method, please do refer to - * the Hibernate API documentation in the first instance. - * @param entity the object (of the target class) to load into - * @param id the identifier of the persistent instance - * @throws org.springframework.orm.ObjectRetrievalFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#load(Object, java.io.Serializable) - */ - void load(Object entity, Serializable id) throws DataAccessException; - - /** - * Re-read the state of the given persistent instance. - * @param entity the persistent instance to re-read - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#refresh(Object) - */ - void refresh(Object entity) throws DataAccessException; - - /** - * Re-read the state of the given persistent instance. - * Obtains the specified lock mode for the instance. - * @param entity the persistent instance to re-read - * @param lockMode the lock mode to obtain - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#refresh(Object, org.hibernate.LockMode) - */ - void refresh(Object entity, LockMode lockMode) throws DataAccessException; - - /** - * Check whether the given object is in the Session cache. - * @param entity the persistence instance to check - * @return whether the given object is in the Session cache - * @throws org.springframework.dao.DataAccessException if there is a Hibernate error - * @see org.hibernate.Session#contains - */ - boolean contains(Object entity) throws DataAccessException; - - /** - * Remove the given object from the {@link org.hibernate.Session} cache. - * @param entity the persistent instance to evict - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#evict - */ - void evict(Object entity) throws DataAccessException; - - /** - * Force initialization of a Hibernate proxy or persistent collection. - * @param proxy a proxy for a persistent object or a persistent collection - * @throws DataAccessException if we can't initialize the proxy, for example - * because it is not associated with an active Session - * @see org.hibernate.Hibernate#initialize - */ - void initialize(Object proxy) throws DataAccessException; - - /** - * Return an enabled Hibernate {@link Filter} for the given filter name. - * The returned {@code Filter} instance can be used to set filter parameters. - * @param filterName the name of the filter - * @return the enabled Hibernate {@code Filter} (either already - * enabled or enabled on the fly by this operation) - * @throws IllegalStateException if we are not running within a - * transactional Session (in which case this operation does not make sense) - */ - Filter enableFilter(String filterName) throws IllegalStateException; - - - //------------------------------------------------------------------------- - // Convenience methods for storing individual objects - //------------------------------------------------------------------------- - - /** - * Obtain the specified lock level upon the given object, implicitly - * checking whether the corresponding database entry still exists. - * @param entity the persistent instance to lock - * @param lockMode the lock mode to obtain - * @throws org.springframework.orm.ObjectOptimisticLockingFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#lock(Object, org.hibernate.LockMode) - */ - void lock(Object entity, LockMode lockMode) throws DataAccessException; - - /** - * Obtain the specified lock level upon the given object, implicitly - * checking whether the corresponding database entry still exists. - * @param entityName the name of the persistent entity - * @param entity the persistent instance to lock - * @param lockMode the lock mode to obtain - * @throws org.springframework.orm.ObjectOptimisticLockingFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#lock(String, Object, org.hibernate.LockMode) - */ - void lock(String entityName, Object entity, LockMode lockMode) throws DataAccessException; - - /** - * Persist the given transient instance. - * @param entity the transient instance to persist - * @return the generated identifier - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#save(Object) - */ - Serializable save(Object entity) throws DataAccessException; - - /** - * Persist the given transient instance. - * @param entityName the name of the persistent entity - * @param entity the transient instance to persist - * @return the generated identifier - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#save(String, Object) - */ - Serializable save(String entityName, Object entity) throws DataAccessException; - - /** - * Update the given persistent instance, - * associating it with the current Hibernate {@link org.hibernate.Session}. - * @param entity the persistent instance to update - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#update(Object) - */ - void update(Object entity) throws DataAccessException; - - /** - * Update the given persistent instance, - * associating it with the current Hibernate {@link org.hibernate.Session}. - *

Obtains the specified lock mode if the instance exists, implicitly - * checking whether the corresponding database entry still exists. - * @param entity the persistent instance to update - * @param lockMode the lock mode to obtain - * @throws org.springframework.orm.ObjectOptimisticLockingFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#update(Object) - */ - void update(Object entity, LockMode lockMode) throws DataAccessException; - - /** - * Update the given persistent instance, - * associating it with the current Hibernate {@link org.hibernate.Session}. - * @param entityName the name of the persistent entity - * @param entity the persistent instance to update - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#update(String, Object) - */ - void update(String entityName, Object entity) throws DataAccessException; - - /** - * Update the given persistent instance, - * associating it with the current Hibernate {@link org.hibernate.Session}. - *

Obtains the specified lock mode if the instance exists, implicitly - * checking whether the corresponding database entry still exists. - * @param entityName the name of the persistent entity - * @param entity the persistent instance to update - * @param lockMode the lock mode to obtain - * @throws org.springframework.orm.ObjectOptimisticLockingFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#update(String, Object) - */ - void update(String entityName, Object entity, LockMode lockMode) throws DataAccessException; - - /** - * Save or update the given persistent instance, - * according to its id (matching the configured "unsaved-value"?). - * Associates the instance with the current Hibernate {@link org.hibernate.Session}. - * @param entity the persistent instance to save or update - * (to be associated with the Hibernate {@code Session}) - * @throws DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#saveOrUpdate(Object) - */ - void saveOrUpdate(Object entity) throws DataAccessException; - - /** - * Save or update the given persistent instance, - * according to its id (matching the configured "unsaved-value"?). - * Associates the instance with the current Hibernate {@code Session}. - * @param entityName the name of the persistent entity - * @param entity the persistent instance to save or update - * (to be associated with the Hibernate {@code Session}) - * @throws DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#saveOrUpdate(String, Object) - */ - void saveOrUpdate(String entityName, Object entity) throws DataAccessException; - - /** - * Persist the state of the given detached instance according to the - * given replication mode, reusing the current identifier value. - * @param entity the persistent object to replicate - * @param replicationMode the Hibernate ReplicationMode - * @throws DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#replicate(Object, org.hibernate.ReplicationMode) - */ - void replicate(Object entity, ReplicationMode replicationMode) throws DataAccessException; - - /** - * Persist the state of the given detached instance according to the - * given replication mode, reusing the current identifier value. - * @param entityName the name of the persistent entity - * @param entity the persistent object to replicate - * @param replicationMode the Hibernate ReplicationMode - * @throws DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#replicate(String, Object, org.hibernate.ReplicationMode) - */ - void replicate(String entityName, Object entity, ReplicationMode replicationMode) throws DataAccessException; - - /** - * Persist the given transient instance. Follows JSR-220 semantics. - *

Similar to {@code save}, associating the given object - * with the current Hibernate {@link org.hibernate.Session}. - * @param entity the persistent instance to persist - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#persist(Object) - * @see #save - */ - void persist(Object entity) throws DataAccessException; - - /** - * Persist the given transient instance. Follows JSR-220 semantics. - *

Similar to {@code save}, associating the given object - * with the current Hibernate {@link org.hibernate.Session}. - * @param entityName the name of the persistent entity - * @param entity the persistent instance to persist - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#persist(String, Object) - * @see #save - */ - void persist(String entityName, Object entity) throws DataAccessException; - - /** - * Copy the state of the given object onto the persistent object - * with the same identifier. Follows JSR-220 semantics. - *

Similar to {@code saveOrUpdate}, but never associates the given - * object with the current Hibernate Session. In case of a new entity, - * the state will be copied over as well. - *

Note that {@code merge} will not update the identifiers - * in the passed-in object graph (in contrast to TopLink)! Consider - * registering Spring's {@code IdTransferringMergeEventListener} if - * you would like to have newly assigned ids transferred to the original - * object graph too. - * @param entity the object to merge with the corresponding persistence instance - * @return the updated, registered persistent instance - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#merge(Object) - * @see #saveOrUpdate - */ - T merge(T entity) throws DataAccessException; - - /** - * Copy the state of the given object onto the persistent object - * with the same identifier. Follows JSR-220 semantics. - *

Similar to {@code saveOrUpdate}, but never associates the given - * object with the current Hibernate {@link org.hibernate.Session}. In - * the case of a new entity, the state will be copied over as well. - *

Note that {@code merge} will not update the identifiers - * in the passed-in object graph (in contrast to TopLink)! Consider - * registering Spring's {@code IdTransferringMergeEventListener} - * if you would like to have newly assigned ids transferred to the - * original object graph too. - * @param entityName the name of the persistent entity - * @param entity the object to merge with the corresponding persistence instance - * @return the updated, registered persistent instance - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#merge(String, Object) - * @see #saveOrUpdate - */ - T merge(String entityName, T entity) throws DataAccessException; - - /** - * Delete the given persistent instance. - * @param entity the persistent instance to delete - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#delete(Object) - */ - void delete(Object entity) throws DataAccessException; - - /** - * Delete the given persistent instance. - *

Obtains the specified lock mode if the instance exists, implicitly - * checking whether the corresponding database entry still exists. - * @param entity the persistent instance to delete - * @param lockMode the lock mode to obtain - * @throws org.springframework.orm.ObjectOptimisticLockingFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#delete(Object) - */ - void delete(Object entity, LockMode lockMode) throws DataAccessException; - - /** - * Delete the given persistent instance. - * @param entityName the name of the persistent entity - * @param entity the persistent instance to delete - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#delete(Object) - */ - void delete(String entityName, Object entity) throws DataAccessException; - - /** - * Delete the given persistent instance. - *

Obtains the specified lock mode if the instance exists, implicitly - * checking whether the corresponding database entry still exists. - * @param entityName the name of the persistent entity - * @param entity the persistent instance to delete - * @param lockMode the lock mode to obtain - * @throws org.springframework.orm.ObjectOptimisticLockingFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#delete(Object) - */ - void delete(String entityName, Object entity, LockMode lockMode) throws DataAccessException; - - /** - * Delete all given persistent instances. - *

This can be combined with any of the find methods to delete by query - * in two lines of code. - * @param entities the persistent instances to delete - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#delete(Object) - */ - void deleteAll(Collection entities) throws DataAccessException; - - /** - * Flush all pending saves, updates and deletes to the database. - *

Only invoke this for selective eager flushing, for example when - * JDBC code needs to see certain changes within the same transaction. - * Else, it is preferable to rely on auto-flushing at transaction - * completion. - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#flush - */ - void flush() throws DataAccessException; - - /** - * Remove all objects from the {@link org.hibernate.Session} cache, and - * cancel all pending saves, updates and deletes. - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#clear - */ - void clear() throws DataAccessException; - - - //------------------------------------------------------------------------- - // Convenience finder methods for HQL strings - //------------------------------------------------------------------------- - - /** - * Execute an HQL query, binding a number of values to "?" parameters - * in the query string. - * @param queryString a query expressed in Hibernate's query language - * @param values the values of the parameters - * @return a {@link List} containing the results of the query execution - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#createQuery - */ - List find(String queryString, Object... values) throws DataAccessException; - - /** - * Execute an HQL query, binding one value to a ":" named parameter - * in the query string. - * @param queryString a query expressed in Hibernate's query language - * @param paramName the name of the parameter - * @param value the value of the parameter - * @return a {@link List} containing the results of the query execution - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#getNamedQuery(String) - */ - List findByNamedParam(String queryString, String paramName, Object value) throws DataAccessException; - - /** - * Execute an HQL query, binding a number of values to ":" named - * parameters in the query string. - * @param queryString a query expressed in Hibernate's query language - * @param paramNames the names of the parameters - * @param values the values of the parameters - * @return a {@link List} containing the results of the query execution - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#getNamedQuery(String) - */ - List findByNamedParam(String queryString, String[] paramNames, Object[] values) throws DataAccessException; - - /** - * Execute an HQL query, binding the properties of the given bean to - * named parameters in the query string. - * @param queryString a query expressed in Hibernate's query language - * @param valueBean the values of the parameters - * @return a {@link List} containing the results of the query execution - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Query#setProperties - * @see org.hibernate.Session#createQuery - */ - List findByValueBean(String queryString, Object valueBean) throws DataAccessException; - - - //------------------------------------------------------------------------- - // Convenience finder methods for named queries - //------------------------------------------------------------------------- - - /** - * Execute a named query binding a number of values to "?" parameters - * in the query string. - *

A named query is defined in a Hibernate mapping file. - * @param queryName the name of a Hibernate query in a mapping file - * @param values the values of the parameters - * @return a {@link List} containing the results of the query execution - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#getNamedQuery(String) - */ - List findByNamedQuery(String queryName, Object... values) throws DataAccessException; - - /** - * Execute a named query, binding one value to a ":" named parameter - * in the query string. - *

A named query is defined in a Hibernate mapping file. - * @param queryName the name of a Hibernate query in a mapping file - * @param paramName the name of parameter - * @param value the value of the parameter - * @return a {@link List} containing the results of the query execution - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#getNamedQuery(String) - */ - List findByNamedQueryAndNamedParam(String queryName, String paramName, Object value) - throws DataAccessException; - - /** - * Execute a named query, binding a number of values to ":" named - * parameters in the query string. - *

A named query is defined in a Hibernate mapping file. - * @param queryName the name of a Hibernate query in a mapping file - * @param paramNames the names of the parameters - * @param values the values of the parameters - * @return a {@link List} containing the results of the query execution - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#getNamedQuery(String) - */ - List findByNamedQueryAndNamedParam(String queryName, String[] paramNames, Object[] values) - throws DataAccessException; - - /** - * Execute a named query, binding the properties of the given bean to - * ":" named parameters in the query string. - *

A named query is defined in a Hibernate mapping file. - * @param queryName the name of a Hibernate query in a mapping file - * @param valueBean the values of the parameters - * @return a {@link List} containing the results of the query execution - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Query#setProperties - * @see org.hibernate.Session#getNamedQuery(String) - */ - List findByNamedQueryAndValueBean(String queryName, Object valueBean) throws DataAccessException; - - - //------------------------------------------------------------------------- - // Convenience finder methods for detached criteria - //------------------------------------------------------------------------- - - /** - * Execute a query based on a given Hibernate criteria object. - * @param criteria the detached Hibernate criteria object. - * Note: Do not reuse criteria objects! They need to recreated per execution, - * due to the suboptimal design of Hibernate's criteria facility. - * @return a {@link List} containing 0 or more persistent instances - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.criterion.DetachedCriteria#getExecutableCriteria(org.hibernate.Session) - */ - List findByCriteria(DetachedCriteria criteria) throws DataAccessException; - - /** - * Execute a query based on the given Hibernate criteria object. - * @param criteria the detached Hibernate criteria object. - * Note: Do not reuse criteria objects! They need to recreated per execution, - * due to the suboptimal design of Hibernate's criteria facility. - * @param firstResult the index of the first result object to be retrieved - * (numbered from 0) - * @param maxResults the maximum number of result objects to retrieve - * (or <=0 for no limit) - * @return a {@link List} containing 0 or more persistent instances - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.criterion.DetachedCriteria#getExecutableCriteria(org.hibernate.Session) - * @see org.hibernate.Criteria#setFirstResult(int) - * @see org.hibernate.Criteria#setMaxResults(int) - */ - List findByCriteria(DetachedCriteria criteria, int firstResult, int maxResults) throws DataAccessException; - - /** - * Execute a query based on the given example entity object. - * @param exampleEntity an instance of the desired entity, - * serving as example for "query-by-example" - * @return a {@link List} containing 0 or more persistent instances - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.criterion.Example#create(Object) - */ - List findByExample(T exampleEntity) throws DataAccessException; - - /** - * Execute a query based on the given example entity object. - * @param entityName the name of the persistent entity - * @param exampleEntity an instance of the desired entity, - * serving as example for "query-by-example" - * @return a {@link List} containing 0 or more persistent instances - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.criterion.Example#create(Object) - */ - List findByExample(String entityName, T exampleEntity) throws DataAccessException; - - /** - * Execute a query based on a given example entity object. - * @param exampleEntity an instance of the desired entity, - * serving as example for "query-by-example" - * @param firstResult the index of the first result object to be retrieved - * (numbered from 0) - * @param maxResults the maximum number of result objects to retrieve - * (or <=0 for no limit) - * @return a {@link List} containing 0 or more persistent instances - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.criterion.Example#create(Object) - * @see org.hibernate.Criteria#setFirstResult(int) - * @see org.hibernate.Criteria#setMaxResults(int) - */ - List findByExample(T exampleEntity, int firstResult, int maxResults) throws DataAccessException; - - /** - * Execute a query based on a given example entity object. - * @param entityName the name of the persistent entity - * @param exampleEntity an instance of the desired entity, - * serving as example for "query-by-example" - * @param firstResult the index of the first result object to be retrieved - * (numbered from 0) - * @param maxResults the maximum number of result objects to retrieve - * (or <=0 for no limit) - * @return a {@link List} containing 0 or more persistent instances - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.criterion.Example#create(Object) - * @see org.hibernate.Criteria#setFirstResult(int) - * @see org.hibernate.Criteria#setMaxResults(int) - */ - List findByExample(String entityName, T exampleEntity, int firstResult, int maxResults) - throws DataAccessException; - - - //------------------------------------------------------------------------- - // Convenience query methods for iteration and bulk updates/deletes - //------------------------------------------------------------------------- - - /** - * Execute a query for persistent instances, binding a number of - * values to "?" parameters in the query string. - *

Returns the results as an {@link Iterator}. Entities returned are - * initialized on demand. See the Hibernate API documentation for details. - * @param queryString a query expressed in Hibernate's query language - * @param values the values of the parameters - * @return an {@link Iterator} containing 0 or more persistent instances - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#createQuery - * @see org.hibernate.Query#iterate - */ - Iterator iterate(String queryString, Object... values) throws DataAccessException; - - /** - * Immediately close an {@link Iterator} created by any of the various - * {@code iterate(..)} operations, instead of waiting until the - * session is closed or disconnected. - * @param it the {@code Iterator} to close - * @throws DataAccessException if the {@code Iterator} could not be closed - * @see org.hibernate.Hibernate#close - */ - void closeIterator(Iterator it) throws DataAccessException; - - /** - * Update/delete all objects according to the given query, binding a number of - * values to "?" parameters in the query string. - * @param queryString an update/delete query expressed in Hibernate's query language - * @param values the values of the parameters - * @return the number of instances updated/deleted - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#createQuery - * @see org.hibernate.Query#executeUpdate - */ - int bulkUpdate(String queryString, Object... values) throws DataAccessException; - -} diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateOptimisticLockingFailureException.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateOptimisticLockingFailureException.java deleted file mode 100644 index 4447aa9644..0000000000 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateOptimisticLockingFailureException.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate4; - -import org.hibernate.StaleObjectStateException; -import org.hibernate.StaleStateException; -import org.hibernate.dialect.lock.OptimisticEntityLockException; - -import org.springframework.orm.ObjectOptimisticLockingFailureException; - -/** - * Hibernate-specific subclass of ObjectOptimisticLockingFailureException. - * Converts Hibernate's StaleObjectStateException, StaleStateException - * and OptimisticEntityLockException. - * - * @author Juergen Hoeller - * @since 3.1 - * @see SessionFactoryUtils#convertHibernateAccessException - */ -@SuppressWarnings("serial") -public class HibernateOptimisticLockingFailureException extends ObjectOptimisticLockingFailureException { - - public HibernateOptimisticLockingFailureException(StaleObjectStateException ex) { - super(ex.getEntityName(), ex.getIdentifier(), ex); - } - - public HibernateOptimisticLockingFailureException(StaleStateException ex) { - super(ex.getMessage(), ex); - } - - public HibernateOptimisticLockingFailureException(OptimisticEntityLockException ex) { - super(ex.getMessage(), ex); - } - -} diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateQueryException.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateQueryException.java deleted file mode 100644 index b9d6516127..0000000000 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateQueryException.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate4; - -import org.hibernate.QueryException; - -import org.springframework.dao.InvalidDataAccessResourceUsageException; - -/** - * Hibernate-specific subclass of InvalidDataAccessResourceUsageException, - * thrown on invalid HQL query syntax. - * - * @author Juergen Hoeller - * @since 3.1 - * @see SessionFactoryUtils#convertHibernateAccessException - */ -@SuppressWarnings("serial") -public class HibernateQueryException extends InvalidDataAccessResourceUsageException { - - public HibernateQueryException(QueryException ex) { - super(ex.getMessage(), ex); - } - - /** - * Return the HQL query string that was invalid. - */ - public String getQueryString() { - return ((QueryException) getCause()).getQueryString(); - } - -} diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateSystemException.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateSystemException.java deleted file mode 100644 index 358aa72a2c..0000000000 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateSystemException.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate4; - -import org.hibernate.HibernateException; - -import org.springframework.dao.UncategorizedDataAccessException; - -/** - * Hibernate-specific subclass of UncategorizedDataAccessException, - * for Hibernate system errors that do not match any concrete - * {@code org.springframework.dao} exceptions. - * - * @author Juergen Hoeller - * @since 3.1 - * @see SessionFactoryUtils#convertHibernateAccessException - */ -@SuppressWarnings("serial") -public class HibernateSystemException extends UncategorizedDataAccessException { - - /** - * Create a new HibernateSystemException, - * wrapping an arbitrary HibernateException. - * @param cause the HibernateException thrown - */ - public HibernateSystemException(HibernateException cause) { - super(cause != null ? cause.getMessage() : null, cause); - } - -} diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateTemplate.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateTemplate.java deleted file mode 100644 index f05bd73276..0000000000 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateTemplate.java +++ /dev/null @@ -1,1263 +0,0 @@ -/* - * Copyright 2002-2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate4; - -import java.io.Serializable; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.hibernate.Criteria; -import org.hibernate.Filter; -import org.hibernate.FlushMode; -import org.hibernate.Hibernate; -import org.hibernate.HibernateException; -import org.hibernate.LockMode; -import org.hibernate.LockOptions; -import org.hibernate.Query; -import org.hibernate.ReplicationMode; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.criterion.DetachedCriteria; -import org.hibernate.criterion.Example; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.dao.DataAccessException; -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.transaction.support.TransactionSynchronizationManager; -import org.springframework.util.Assert; - -/** - * Helper class that simplifies Hibernate data access code. Automatically - * converts HibernateExceptions into DataAccessExceptions, following the - * {@code org.springframework.dao} exception hierarchy. - * - *

The central method is {@code execute}, supporting Hibernate access code - * implementing the {@link HibernateCallback} interface. It provides Hibernate Session - * handling such that neither the HibernateCallback implementation nor the calling - * code needs to explicitly care about retrieving/closing Hibernate Sessions, - * or handling Session lifecycle exceptions. For typical single step actions, - * there are various convenience methods (find, load, saveOrUpdate, delete). - * - *

Can be used within a service implementation via direct instantiation - * with a SessionFactory reference, or get prepared in an application context - * and given to services as bean reference. Note: The SessionFactory should - * always be configured as bean in the application context, in the first case - * given to the service directly, in the second case to the prepared template. - * - *

NOTE: Hibernate access code can also be coded in plain Hibernate style. - * Hence, for newly started projects, consider adopting the standard Hibernate - * style of coding data access objects instead, based on - * {@link org.hibernate.SessionFactory#getCurrentSession()}. - * This HibernateTemplate primarily exists as a migration helper for Hibernate 3 - * based data access code, to benefit from bug fixes in Hibernate 4.x. - * - * @author Juergen Hoeller - * @since 4.0.1 - * @see #setSessionFactory - * @see HibernateCallback - * @see org.hibernate.Session - * @see LocalSessionFactoryBean - * @see HibernateTransactionManager - * @see org.springframework.orm.hibernate4.support.OpenSessionInViewFilter - * @see org.springframework.orm.hibernate4.support.OpenSessionInViewInterceptor - */ -public class HibernateTemplate implements HibernateOperations, InitializingBean { - - protected final Log logger = LogFactory.getLog(getClass()); - - private SessionFactory sessionFactory; - - private String[] filterNames; - - private boolean exposeNativeSession = false; - - private boolean checkWriteOperations = true; - - private boolean cacheQueries = false; - - private String queryCacheRegion; - - private int fetchSize = 0; - - private int maxResults = 0; - - - /** - * Create a new HibernateTemplate instance. - */ - public HibernateTemplate() { - } - - /** - * Create a new HibernateTemplate instance. - * @param sessionFactory the SessionFactory to create Sessions with - */ - public HibernateTemplate(SessionFactory sessionFactory) { - setSessionFactory(sessionFactory); - afterPropertiesSet(); - } - - - /** - * Set the Hibernate SessionFactory that should be used to create - * Hibernate Sessions. - */ - public void setSessionFactory(SessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; - } - - /** - * Return the Hibernate SessionFactory that should be used to create - * Hibernate Sessions. - */ - public SessionFactory getSessionFactory() { - return this.sessionFactory; - } - - /** - * Set one or more names of Hibernate filters to be activated for all - * Sessions that this accessor works with. - *

Each of those filters will be enabled at the beginning of each - * operation and correspondingly disabled at the end of the operation. - * This will work for newly opened Sessions as well as for existing - * Sessions (for example, within a transaction). - * @see #enableFilters(org.hibernate.Session) - * @see org.hibernate.Session#enableFilter(String) - */ - public void setFilterNames(String... filterNames) { - this.filterNames = filterNames; - } - - /** - * Return the names of Hibernate filters to be activated, if any. - */ - public String[] getFilterNames() { - return this.filterNames; - } - - /** - * Set whether to expose the native Hibernate Session to - * HibernateCallback code. - *

Default is "false": a Session proxy will be returned, suppressing - * {@code close} calls and automatically applying query cache - * settings and transaction timeouts. - * @see HibernateCallback - * @see org.hibernate.Session - * @see #setCacheQueries - * @see #setQueryCacheRegion - * @see #prepareQuery - * @see #prepareCriteria - */ - public void setExposeNativeSession(boolean exposeNativeSession) { - this.exposeNativeSession = exposeNativeSession; - } - - /** - * Return whether to expose the native Hibernate Session to - * HibernateCallback code, or rather a Session proxy. - */ - public boolean isExposeNativeSession() { - return this.exposeNativeSession; - } - - /** - * Set whether to check that the Hibernate Session is not in read-only mode - * in case of write operations (save/update/delete). - *

Default is "true", for fail-fast behavior when attempting write operations - * within a read-only transaction. Turn this off to allow save/update/delete - * on a Session with flush mode MANUAL. - * @see #checkWriteOperationAllowed - * @see org.springframework.transaction.TransactionDefinition#isReadOnly - */ - public void setCheckWriteOperations(boolean checkWriteOperations) { - this.checkWriteOperations = checkWriteOperations; - } - - /** - * Return whether to check that the Hibernate Session is not in read-only - * mode in case of write operations (save/update/delete). - */ - public boolean isCheckWriteOperations() { - return this.checkWriteOperations; - } - - /** - * Set whether to cache all queries executed by this template. - *

If this is "true", all Query and Criteria objects created by - * this template will be marked as cacheable (including all - * queries through find methods). - *

To specify the query region to be used for queries cached - * by this template, set the "queryCacheRegion" property. - * @see #setQueryCacheRegion - * @see org.hibernate.Query#setCacheable - * @see org.hibernate.Criteria#setCacheable - */ - public void setCacheQueries(boolean cacheQueries) { - this.cacheQueries = cacheQueries; - } - - /** - * Return whether to cache all queries executed by this template. - */ - public boolean isCacheQueries() { - return this.cacheQueries; - } - - /** - * Set the name of the cache region for queries executed by this template. - *

If this is specified, it will be applied to all Query and Criteria objects - * created by this template (including all queries through find methods). - *

The cache region will not take effect unless queries created by this - * template are configured to be cached via the "cacheQueries" property. - * @see #setCacheQueries - * @see org.hibernate.Query#setCacheRegion - * @see org.hibernate.Criteria#setCacheRegion - */ - public void setQueryCacheRegion(String queryCacheRegion) { - this.queryCacheRegion = queryCacheRegion; - } - - /** - * Return the name of the cache region for queries executed by this template. - */ - public String getQueryCacheRegion() { - return this.queryCacheRegion; - } - - /** - * Set the fetch size for this HibernateTemplate. This is important for processing - * large result sets: Setting this higher than the default value will increase - * processing speed at the cost of memory consumption; setting this lower can - * avoid transferring row data that will never be read by the application. - *

Default is 0, indicating to use the JDBC driver's default. - */ - public void setFetchSize(int fetchSize) { - this.fetchSize = fetchSize; - } - - /** - * Return the fetch size specified for this HibernateTemplate. - */ - public int getFetchSize() { - return this.fetchSize; - } - - /** - * Set the maximum number of rows for this HibernateTemplate. This is important - * for processing subsets of large result sets, avoiding to read and hold - * the entire result set in the database or in the JDBC driver if we're - * never interested in the entire result in the first place (for example, - * when performing searches that might return a large number of matches). - *

Default is 0, indicating to use the JDBC driver's default. - */ - public void setMaxResults(int maxResults) { - this.maxResults = maxResults; - } - - /** - * Return the maximum number of rows specified for this HibernateTemplate. - */ - public int getMaxResults() { - return this.maxResults; - } - - @Override - public void afterPropertiesSet() { - if (getSessionFactory() == null) { - throw new IllegalArgumentException("Property 'sessionFactory' is required"); - } - } - - - @Override - public T execute(HibernateCallback action) throws DataAccessException { - return doExecute(action, false); - } - - /** - * Execute the action specified by the given action object within a - * native {@link org.hibernate.Session}. - *

This execute variant overrides the template-wide - * {@link #isExposeNativeSession() "exposeNativeSession"} setting. - * @param action callback object that specifies the Hibernate action - * @return a result object returned by the action, or {@code null} - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - */ - public T executeWithNativeSession(HibernateCallback action) { - return doExecute(action, true); - } - - /** - * Execute the action specified by the given action object within a Session. - * @param action callback object that specifies the Hibernate action - * @param enforceNativeSession whether to enforce exposure of the native - * Hibernate Session to callback code - * @return a result object returned by the action, or {@code null} - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - */ - protected T doExecute(HibernateCallback action, boolean enforceNativeSession) throws DataAccessException { - Assert.notNull(action, "Callback object must not be null"); - - Session session = null; - boolean isNew = false; - try { - session = getSessionFactory().getCurrentSession(); - } - catch (HibernateException ex) { - logger.debug("Could not retrieve pre-bound Hibernate session", ex); - } - if (session == null) { - session = getSessionFactory().openSession(); - session.setFlushMode(FlushMode.MANUAL); - isNew = true; - } - - try { - enableFilters(session); - Session sessionToExpose = - (enforceNativeSession || isExposeNativeSession() ? session : createSessionProxy(session)); - return action.doInHibernate(sessionToExpose); - } - catch (HibernateException ex) { - throw SessionFactoryUtils.convertHibernateAccessException(ex); - } - catch (RuntimeException ex) { - // Callback code threw application exception... - throw ex; - } - finally { - if (isNew) { - SessionFactoryUtils.closeSession(session); - } - else { - disableFilters(session); - } - } - } - - /** - * Create a close-suppressing proxy for the given Hibernate Session. - * The proxy also prepares returned Query and Criteria objects. - * @param session the Hibernate Session to create a proxy for - * @return the Session proxy - * @see org.hibernate.Session#close() - * @see #prepareQuery - * @see #prepareCriteria - */ - protected Session createSessionProxy(Session session) { - return (Session) Proxy.newProxyInstance( - session.getClass().getClassLoader(), new Class[] {Session.class}, - new CloseSuppressingInvocationHandler(session)); - } - - /** - * Enable the specified filters on the given Session. - * @param session the current Hibernate Session - * @see #setFilterNames - * @see org.hibernate.Session#enableFilter(String) - */ - protected void enableFilters(Session session) { - String[] filterNames = getFilterNames(); - if (filterNames != null) { - for (String filterName : filterNames) { - session.enableFilter(filterName); - } - } - } - - /** - * Disable the specified filters on the given Session. - * @param session the current Hibernate Session - * @see #setFilterNames - * @see org.hibernate.Session#disableFilter(String) - */ - protected void disableFilters(Session session) { - String[] filterNames = getFilterNames(); - if (filterNames != null) { - for (String filterName : filterNames) { - session.disableFilter(filterName); - } - } - } - - - //------------------------------------------------------------------------- - // Convenience methods for loading individual objects - //------------------------------------------------------------------------- - - @Override - public T get(Class entityClass, Serializable id) throws DataAccessException { - return get(entityClass, id, null); - } - - @Override - public T get(final Class entityClass, final Serializable id, final LockMode lockMode) - throws DataAccessException { - - return executeWithNativeSession(new HibernateCallback() { - @Override - @SuppressWarnings("unchecked") - public T doInHibernate(Session session) throws HibernateException { - if (lockMode != null) { - return (T) session.get(entityClass, id, new LockOptions(lockMode)); - } - else { - return (T) session.get(entityClass, id); - } - } - }); - } - - @Override - public Object get(String entityName, Serializable id) throws DataAccessException { - return get(entityName, id, null); - } - - @Override - public Object get(final String entityName, final Serializable id, final LockMode lockMode) - throws DataAccessException { - - return executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - if (lockMode != null) { - return session.get(entityName, id, new LockOptions(lockMode)); - } - else { - return session.get(entityName, id); - } - } - }); - } - - @Override - public T load(Class entityClass, Serializable id) throws DataAccessException { - return load(entityClass, id, null); - } - - @Override - public T load(final Class entityClass, final Serializable id, final LockMode lockMode) - throws DataAccessException { - - return executeWithNativeSession(new HibernateCallback() { - @Override - @SuppressWarnings("unchecked") - public T doInHibernate(Session session) throws HibernateException { - if (lockMode != null) { - return (T) session.load(entityClass, id, new LockOptions(lockMode)); - } - else { - return (T) session.load(entityClass, id); - } - } - }); - } - - @Override - public Object load(String entityName, Serializable id) throws DataAccessException { - return load(entityName, id, null); - } - - @Override - public Object load(final String entityName, final Serializable id, final LockMode lockMode) - throws DataAccessException { - - return executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - if (lockMode != null) { - return session.load(entityName, id, new LockOptions(lockMode)); - } - else { - return session.load(entityName, id); - } - } - }); - } - - @Override - public List loadAll(final Class entityClass) throws DataAccessException { - return executeWithNativeSession(new HibernateCallback>() { - @Override - @SuppressWarnings("unchecked") - public List doInHibernate(Session session) throws HibernateException { - Criteria criteria = session.createCriteria(entityClass); - criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); - prepareCriteria(criteria); - return criteria.list(); - } - }); - } - - @Override - public void load(final Object entity, final Serializable id) throws DataAccessException { - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - session.load(entity, id); - return null; - } - }); - } - - @Override - public void refresh(final Object entity) throws DataAccessException { - refresh(entity, null); - } - - @Override - public void refresh(final Object entity, final LockMode lockMode) throws DataAccessException { - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - if (lockMode != null) { - session.refresh(entity, new LockOptions(lockMode)); - } - else { - session.refresh(entity); - } - return null; - } - }); - } - - @Override - public boolean contains(final Object entity) throws DataAccessException { - return executeWithNativeSession(new HibernateCallback() { - @Override - public Boolean doInHibernate(Session session) { - return session.contains(entity); - } - }); - } - - @Override - public void evict(final Object entity) throws DataAccessException { - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - session.evict(entity); - return null; - } - }); - } - - @Override - public void initialize(Object proxy) throws DataAccessException { - try { - Hibernate.initialize(proxy); - } - catch (HibernateException ex) { - throw SessionFactoryUtils.convertHibernateAccessException(ex); - } - } - - @Override - public Filter enableFilter(String filterName) throws IllegalStateException { - Session session = getSessionFactory().getCurrentSession(); - Filter filter = session.getEnabledFilter(filterName); - if (filter == null) { - filter = session.enableFilter(filterName); - } - return filter; - } - - - //------------------------------------------------------------------------- - // Convenience methods for storing individual objects - //------------------------------------------------------------------------- - - @Override - public void lock(final Object entity, final LockMode lockMode) throws DataAccessException { - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - session.buildLockRequest(new LockOptions(lockMode)).lock(entity); - return null; - } - }); - } - - @Override - public void lock(final String entityName, final Object entity, final LockMode lockMode) - throws DataAccessException { - - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - session.buildLockRequest(new LockOptions(lockMode)).lock(entityName, entity); - return null; - } - }); - } - - @Override - public Serializable save(final Object entity) throws DataAccessException { - return executeWithNativeSession(new HibernateCallback() { - @Override - public Serializable doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - return session.save(entity); - } - }); - } - - @Override - public Serializable save(final String entityName, final Object entity) throws DataAccessException { - return executeWithNativeSession(new HibernateCallback() { - @Override - public Serializable doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - return session.save(entityName, entity); - } - }); - } - - @Override - public void update(Object entity) throws DataAccessException { - update(entity, null); - } - - @Override - public void update(final Object entity, final LockMode lockMode) throws DataAccessException { - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - session.update(entity); - if (lockMode != null) { - session.buildLockRequest(new LockOptions(lockMode)).lock(entity); - } - return null; - } - }); - } - - @Override - public void update(String entityName, Object entity) throws DataAccessException { - update(entityName, entity, null); - } - - @Override - public void update(final String entityName, final Object entity, final LockMode lockMode) - throws DataAccessException { - - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - session.update(entityName, entity); - if (lockMode != null) { - session.buildLockRequest(new LockOptions(lockMode)).lock(entityName, entity); - } - return null; - } - }); - } - - @Override - public void saveOrUpdate(final Object entity) throws DataAccessException { - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - session.saveOrUpdate(entity); - return null; - } - }); - } - - @Override - public void saveOrUpdate(final String entityName, final Object entity) throws DataAccessException { - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - session.saveOrUpdate(entityName, entity); - return null; - } - }); - } - - @Override - public void replicate(final Object entity, final ReplicationMode replicationMode) - throws DataAccessException { - - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - session.replicate(entity, replicationMode); - return null; - } - }); - } - - @Override - public void replicate(final String entityName, final Object entity, final ReplicationMode replicationMode) - throws DataAccessException { - - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - session.replicate(entityName, entity, replicationMode); - return null; - } - }); - } - - @Override - public void persist(final Object entity) throws DataAccessException { - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - session.persist(entity); - return null; - } - }); - } - - @Override - public void persist(final String entityName, final Object entity) throws DataAccessException { - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - session.persist(entityName, entity); - return null; - } - }); - } - - @Override - public T merge(final T entity) throws DataAccessException { - return executeWithNativeSession(new HibernateCallback() { - @Override - @SuppressWarnings("unchecked") - public T doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - return (T) session.merge(entity); - } - }); - } - - @Override - public T merge(final String entityName, final T entity) throws DataAccessException { - return executeWithNativeSession(new HibernateCallback() { - @Override - @SuppressWarnings("unchecked") - public T doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - return (T) session.merge(entityName, entity); - } - }); - } - - @Override - public void delete(Object entity) throws DataAccessException { - delete(entity, null); - } - - @Override - public void delete(final Object entity, final LockMode lockMode) throws DataAccessException { - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - if (lockMode != null) { - session.buildLockRequest(new LockOptions(lockMode)).lock(entity); - } - session.delete(entity); - return null; - } - }); - } - - @Override - public void delete(String entityName, Object entity) throws DataAccessException { - delete(entityName, entity, null); - } - - @Override - public void delete(final String entityName, final Object entity, final LockMode lockMode) - throws DataAccessException { - - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - if (lockMode != null) { - session.buildLockRequest(new LockOptions(lockMode)).lock(entityName, entity); - } - session.delete(entityName, entity); - return null; - } - }); - } - - @Override - public void deleteAll(final Collection entities) throws DataAccessException { - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - for (Object entity : entities) { - session.delete(entity); - } - return null; - } - }); - } - - @Override - public void flush() throws DataAccessException { - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - session.flush(); - return null; - } - }); - } - - @Override - public void clear() throws DataAccessException { - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) { - session.clear(); - return null; - } - }); - } - - - //------------------------------------------------------------------------- - // Convenience finder methods for HQL strings - //------------------------------------------------------------------------- - - @Override - public List find(final String queryString, final Object... values) throws DataAccessException { - return executeWithNativeSession(new HibernateCallback>() { - @Override - public List doInHibernate(Session session) throws HibernateException { - Query queryObject = session.createQuery(queryString); - prepareQuery(queryObject); - if (values != null) { - for (int i = 0; i < values.length; i++) { - queryObject.setParameter(i, values[i]); - } - } - return queryObject.list(); - } - }); - } - - @Override - public List findByNamedParam(String queryString, String paramName, Object value) - throws DataAccessException { - - return findByNamedParam(queryString, new String[] {paramName}, new Object[] {value}); - } - - @Override - public List findByNamedParam(final String queryString, final String[] paramNames, final Object[] values) - throws DataAccessException { - - if (paramNames.length != values.length) { - throw new IllegalArgumentException("Length of paramNames array must match length of values array"); - } - return executeWithNativeSession(new HibernateCallback>() { - @Override - public List doInHibernate(Session session) throws HibernateException { - Query queryObject = session.createQuery(queryString); - prepareQuery(queryObject); - if (values != null) { - for (int i = 0; i < values.length; i++) { - applyNamedParameterToQuery(queryObject, paramNames[i], values[i]); - } - } - return queryObject.list(); - } - }); - } - - @Override - public List findByValueBean(final String queryString, final Object valueBean) - throws DataAccessException { - - return executeWithNativeSession(new HibernateCallback>() { - @Override - public List doInHibernate(Session session) throws HibernateException { - Query queryObject = session.createQuery(queryString); - prepareQuery(queryObject); - queryObject.setProperties(valueBean); - return queryObject.list(); - } - }); - } - - - //------------------------------------------------------------------------- - // Convenience finder methods for named queries - //------------------------------------------------------------------------- - - @Override - public List findByNamedQuery(final String queryName, final Object... values) throws DataAccessException { - return executeWithNativeSession(new HibernateCallback>() { - @Override - public List doInHibernate(Session session) throws HibernateException { - Query queryObject = session.getNamedQuery(queryName); - prepareQuery(queryObject); - if (values != null) { - for (int i = 0; i < values.length; i++) { - queryObject.setParameter(i, values[i]); - } - } - return queryObject.list(); - } - }); - } - - @Override - public List findByNamedQueryAndNamedParam(String queryName, String paramName, Object value) - throws DataAccessException { - - return findByNamedQueryAndNamedParam(queryName, new String[] {paramName}, new Object[] {value}); - } - - @Override - public List findByNamedQueryAndNamedParam( - final String queryName, final String[] paramNames, final Object[] values) - throws DataAccessException { - - if (values != null && (paramNames == null || paramNames.length != values.length)) { - throw new IllegalArgumentException("Length of paramNames array must match length of values array"); - } - return executeWithNativeSession(new HibernateCallback>() { - @Override - public List doInHibernate(Session session) throws HibernateException { - Query queryObject = session.getNamedQuery(queryName); - prepareQuery(queryObject); - if (values != null) { - for (int i = 0; i < values.length; i++) { - applyNamedParameterToQuery(queryObject, paramNames[i], values[i]); - } - } - return queryObject.list(); - } - }); - } - - @Override - public List findByNamedQueryAndValueBean(final String queryName, final Object valueBean) - throws DataAccessException { - - return executeWithNativeSession(new HibernateCallback>() { - @Override - public List doInHibernate(Session session) throws HibernateException { - Query queryObject = session.getNamedQuery(queryName); - prepareQuery(queryObject); - queryObject.setProperties(valueBean); - return queryObject.list(); - } - }); - } - - - //------------------------------------------------------------------------- - // Convenience finder methods for detached criteria - //------------------------------------------------------------------------- - - @Override - public List findByCriteria(DetachedCriteria criteria) throws DataAccessException { - return findByCriteria(criteria, -1, -1); - } - - @Override - public List findByCriteria(final DetachedCriteria criteria, final int firstResult, final int maxResults) - throws DataAccessException { - - Assert.notNull(criteria, "DetachedCriteria must not be null"); - return executeWithNativeSession(new HibernateCallback>() { - @Override - public List doInHibernate(Session session) throws HibernateException { - Criteria executableCriteria = criteria.getExecutableCriteria(session); - prepareCriteria(executableCriteria); - if (firstResult >= 0) { - executableCriteria.setFirstResult(firstResult); - } - if (maxResults > 0) { - executableCriteria.setMaxResults(maxResults); - } - return executableCriteria.list(); - } - }); - } - - @Override - public List findByExample(T exampleEntity) throws DataAccessException { - return findByExample(null, exampleEntity, -1, -1); - } - - @Override - public List findByExample(String entityName, T exampleEntity) throws DataAccessException { - return findByExample(entityName, exampleEntity, -1, -1); - } - - @Override - public List findByExample(T exampleEntity, int firstResult, int maxResults) throws DataAccessException { - return findByExample(null, exampleEntity, firstResult, maxResults); - } - - @Override - public List findByExample( - final String entityName, final T exampleEntity, final int firstResult, final int maxResults) - throws DataAccessException { - - Assert.notNull(exampleEntity, "Example entity must not be null"); - return executeWithNativeSession(new HibernateCallback>() { - @Override - @SuppressWarnings("unchecked") - public List doInHibernate(Session session) throws HibernateException { - Criteria executableCriteria = (entityName != null ? - session.createCriteria(entityName) : session.createCriteria(exampleEntity.getClass())); - executableCriteria.add(Example.create(exampleEntity)); - prepareCriteria(executableCriteria); - if (firstResult >= 0) { - executableCriteria.setFirstResult(firstResult); - } - if (maxResults > 0) { - executableCriteria.setMaxResults(maxResults); - } - return executableCriteria.list(); - } - }); - } - - - //------------------------------------------------------------------------- - // Convenience query methods for iteration and bulk updates/deletes - //------------------------------------------------------------------------- - - @Override - public Iterator iterate(final String queryString, final Object... values) throws DataAccessException { - return executeWithNativeSession(new HibernateCallback>() { - @Override - public Iterator doInHibernate(Session session) throws HibernateException { - Query queryObject = session.createQuery(queryString); - prepareQuery(queryObject); - if (values != null) { - for (int i = 0; i < values.length; i++) { - queryObject.setParameter(i, values[i]); - } - } - return queryObject.iterate(); - } - }); - } - - @Override - public void closeIterator(Iterator it) throws DataAccessException { - try { - Hibernate.close(it); - } - catch (HibernateException ex) { - throw SessionFactoryUtils.convertHibernateAccessException(ex); - } - } - - @Override - public int bulkUpdate(final String queryString, final Object... values) throws DataAccessException { - return executeWithNativeSession(new HibernateCallback() { - @Override - public Integer doInHibernate(Session session) throws HibernateException { - Query queryObject = session.createQuery(queryString); - prepareQuery(queryObject); - if (values != null) { - for (int i = 0; i < values.length; i++) { - queryObject.setParameter(i, values[i]); - } - } - return queryObject.executeUpdate(); - } - }); - } - - - //------------------------------------------------------------------------- - // Helper methods used by the operations above - //------------------------------------------------------------------------- - - /** - * Check whether write operations are allowed on the given Session. - *

Default implementation throws an InvalidDataAccessApiUsageException in - * case of {@code FlushMode.MANUAL}. Can be overridden in subclasses. - * @param session current Hibernate Session - * @throws InvalidDataAccessApiUsageException if write operations are not allowed - * @see #setCheckWriteOperations - * @see org.hibernate.Session#getFlushMode() - * @see org.hibernate.FlushMode#MANUAL - */ - protected void checkWriteOperationAllowed(Session session) throws InvalidDataAccessApiUsageException { - if (isCheckWriteOperations() && session.getFlushMode().lessThan(FlushMode.COMMIT)) { - throw new InvalidDataAccessApiUsageException( - "Write operations are not allowed in read-only mode (FlushMode.MANUAL): "+ - "Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition."); - } - } - - /** - * Prepare the given Query object, applying cache settings and/or - * a transaction timeout. - * @param queryObject the Query object to prepare - * @see #setCacheQueries - * @see #setQueryCacheRegion - */ - protected void prepareQuery(Query queryObject) { - if (isCacheQueries()) { - queryObject.setCacheable(true); - if (getQueryCacheRegion() != null) { - queryObject.setCacheRegion(getQueryCacheRegion()); - } - } - if (getFetchSize() > 0) { - queryObject.setFetchSize(getFetchSize()); - } - if (getMaxResults() > 0) { - queryObject.setMaxResults(getMaxResults()); - } - - SessionHolder sessionHolder = - (SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory()); - if (sessionHolder != null && sessionHolder.hasTimeout()) { - queryObject.setTimeout(sessionHolder.getTimeToLiveInSeconds()); - } - } - - /** - * Prepare the given Criteria object, applying cache settings and/or - * a transaction timeout. - * @param criteria the Criteria object to prepare - * @see #setCacheQueries - * @see #setQueryCacheRegion - */ - protected void prepareCriteria(Criteria criteria) { - if (isCacheQueries()) { - criteria.setCacheable(true); - if (getQueryCacheRegion() != null) { - criteria.setCacheRegion(getQueryCacheRegion()); - } - } - if (getFetchSize() > 0) { - criteria.setFetchSize(getFetchSize()); - } - if (getMaxResults() > 0) { - criteria.setMaxResults(getMaxResults()); - } - - SessionHolder sessionHolder = - (SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory()); - if (sessionHolder != null && sessionHolder.hasTimeout()) { - criteria.setTimeout(sessionHolder.getTimeToLiveInSeconds()); - } - } - - /** - * Apply the given name parameter to the given Query object. - * @param queryObject the Query object - * @param paramName the name of the parameter - * @param value the value of the parameter - * @throws HibernateException if thrown by the Query object - */ - protected void applyNamedParameterToQuery(Query queryObject, String paramName, Object value) - throws HibernateException { - - if (value instanceof Collection) { - queryObject.setParameterList(paramName, (Collection) value); - } - else if (value instanceof Object[]) { - queryObject.setParameterList(paramName, (Object[]) value); - } - else { - queryObject.setParameter(paramName, value); - } - } - - - /** - * Invocation handler that suppresses close calls on Hibernate Sessions. - * Also prepares returned Query and Criteria objects. - * @see org.hibernate.Session#close - */ - private class CloseSuppressingInvocationHandler implements InvocationHandler { - - private final Session target; - - public CloseSuppressingInvocationHandler(Session target) { - this.target = target; - } - - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - // Invocation on Session interface coming in... - - if (method.getName().equals("equals")) { - // Only consider equal when proxies are identical. - return (proxy == args[0]); - } - else if (method.getName().equals("hashCode")) { - // Use hashCode of Session proxy. - return System.identityHashCode(proxy); - } - else if (method.getName().equals("close")) { - // Handle close method: suppress, not valid. - return null; - } - - // Invoke method on target Session. - try { - Object retVal = method.invoke(this.target, args); - - // If return value is a Query or Criteria, apply transaction timeout. - // Applies to createQuery, getNamedQuery, createCriteria. - if (retVal instanceof Query) { - prepareQuery(((Query) retVal)); - } - if (retVal instanceof Criteria) { - prepareCriteria(((Criteria) retVal)); - } - - return retVal; - } - catch (InvocationTargetException ex) { - throw ex.getTargetException(); - } - } - } - -} diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateTransactionManager.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateTransactionManager.java deleted file mode 100644 index c9ac33332c..0000000000 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateTransactionManager.java +++ /dev/null @@ -1,843 +0,0 @@ -/* - * Copyright 2002-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate4; - -import java.sql.Connection; -import java.sql.ResultSet; -import javax.sql.DataSource; - -import org.hibernate.ConnectionReleaseMode; -import org.hibernate.FlushMode; -import org.hibernate.HibernateException; -import org.hibernate.Interceptor; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.Transaction; -import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.engine.transaction.spi.TransactionContext; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.dao.DataAccessException; -import org.springframework.dao.DataAccessResourceFailureException; -import org.springframework.jdbc.datasource.ConnectionHolder; -import org.springframework.jdbc.datasource.DataSourceUtils; -import org.springframework.jdbc.datasource.JdbcTransactionObjectSupport; -import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy; -import org.springframework.transaction.CannotCreateTransactionException; -import org.springframework.transaction.IllegalTransactionStateException; -import org.springframework.transaction.InvalidIsolationLevelException; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.TransactionSystemException; -import org.springframework.transaction.support.AbstractPlatformTransactionManager; -import org.springframework.transaction.support.DefaultTransactionStatus; -import org.springframework.transaction.support.ResourceTransactionManager; -import org.springframework.transaction.support.TransactionSynchronizationManager; - -/** - * {@link org.springframework.transaction.PlatformTransactionManager} - * implementation for a single Hibernate {@link org.hibernate.SessionFactory}. - * Binds a Hibernate Session from the specified factory to the thread, - * potentially allowing for one thread-bound Session per factory. - * {@code SessionFactory.getCurrentSession()} is required for Hibernate - * access code that needs to support this transaction handling mechanism, - * with the SessionFactory being configured with {@link SpringSessionContext}. - * - *

Supports custom isolation levels, and timeouts that get applied as - * Hibernate transaction timeouts. - * - *

This transaction manager is appropriate for applications that use a single - * Hibernate SessionFactory for transactional data access, but it also supports - * direct DataSource access within a transaction (i.e. plain JDBC code working - * with the same DataSource). This allows for mixing services which access Hibernate - * and services which use plain JDBC (without being aware of Hibernate)! - * Application code needs to stick to the same simple Connection lookup pattern as - * with {@link org.springframework.jdbc.datasource.DataSourceTransactionManager} - * (i.e. {@link org.springframework.jdbc.datasource.DataSourceUtils#getConnection} - * or going through a - * {@link org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy}). - * - *

Note: To be able to register a DataSource's Connection for plain JDBC code, - * this instance needs to be aware of the DataSource ({@link #setDataSource}). - * The given DataSource should obviously match the one used by the given SessionFactory. - * - *

JTA (usually through {@link org.springframework.transaction.jta.JtaTransactionManager}) - * is necessary for accessing multiple transactional resources within the same - * transaction. The DataSource that Hibernate uses needs to be JTA-enabled in - * such a scenario (see container setup). - * - *

This transaction manager supports nested transactions via JDBC 3.0 Savepoints. - * The {@link #setNestedTransactionAllowed} "nestedTransactionAllowed"} flag defaults - * to "false", though, as nested transactions will just apply to the JDBC Connection, - * not to the Hibernate Session and its cached entity objects and related context. - * You can manually set the flag to "true" if you want to use nested transactions - * for JDBC access code which participates in Hibernate transactions (provided that - * your JDBC driver supports Savepoints). Note that Hibernate itself does not - * support nested transactions! Hence, do not expect Hibernate access code to - * semantically participate in a nested transaction. - * - *

NOTE: Hibernate 4.2+ is strongly recommended for efficient transaction - * management with Spring, in particular for transactional Spring JDBC access. - * - * @author Juergen Hoeller - * @since 3.1 - * @see #setSessionFactory - * @see #setDataSource - * @see org.hibernate.SessionFactory#getCurrentSession() - * @see org.springframework.jdbc.datasource.DataSourceUtils#getConnection - * @see org.springframework.jdbc.datasource.DataSourceUtils#releaseConnection - * @see org.springframework.jdbc.core.JdbcTemplate - * @see org.springframework.jdbc.datasource.DataSourceTransactionManager - * @see org.springframework.transaction.jta.JtaTransactionManager - */ -@SuppressWarnings("serial") -public class HibernateTransactionManager extends AbstractPlatformTransactionManager - implements ResourceTransactionManager, BeanFactoryAware, InitializingBean { - - private SessionFactory sessionFactory; - - private DataSource dataSource; - - private boolean autodetectDataSource = true; - - private boolean prepareConnection = true; - - private boolean allowResultAccessAfterCompletion = false; - - private boolean hibernateManagedSession = false; - - private Object entityInterceptor; - - /** - * Just needed for entityInterceptorBeanName. - * @see #setEntityInterceptorBeanName - */ - private BeanFactory beanFactory; - - - /** - * Create a new HibernateTransactionManager instance. - * A SessionFactory has to be set to be able to use it. - * @see #setSessionFactory - */ - public HibernateTransactionManager() { - } - - /** - * Create a new HibernateTransactionManager instance. - * @param sessionFactory SessionFactory to manage transactions for - */ - public HibernateTransactionManager(SessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; - afterPropertiesSet(); - } - - - /** - * Set the SessionFactory that this instance should manage transactions for. - */ - public void setSessionFactory(SessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; - } - - /** - * Return the SessionFactory that this instance should manage transactions for. - */ - public SessionFactory getSessionFactory() { - return this.sessionFactory; - } - - /** - * Set the JDBC DataSource that this instance should manage transactions for. - * The DataSource should match the one used by the Hibernate SessionFactory: - * for example, you could specify the same JNDI DataSource for both. - *

If the SessionFactory was configured with LocalDataSourceConnectionProvider, - * i.e. by Spring's LocalSessionFactoryBean with a specified "dataSource", - * the DataSource will be auto-detected: You can still explicitly specify the - * DataSource, but you don't need to in this case. - *

A transactional JDBC Connection for this DataSource will be provided to - * application code accessing this DataSource directly via DataSourceUtils - * or JdbcTemplate. The Connection will be taken from the Hibernate Session. - *

The DataSource specified here should be the target DataSource to manage - * transactions for, not a TransactionAwareDataSourceProxy. Only data access - * code may work with TransactionAwareDataSourceProxy, while the transaction - * manager needs to work on the underlying target DataSource. If there's - * nevertheless a TransactionAwareDataSourceProxy passed in, it will be - * unwrapped to extract its target DataSource. - * @see #setAutodetectDataSource - * @see org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy - * @see org.springframework.jdbc.datasource.DataSourceUtils - * @see org.springframework.jdbc.core.JdbcTemplate - */ - public void setDataSource(DataSource dataSource) { - if (dataSource instanceof TransactionAwareDataSourceProxy) { - // If we got a TransactionAwareDataSourceProxy, we need to perform transactions - // for its underlying target DataSource, else data access code won't see - // properly exposed transactions (i.e. transactions for the target DataSource). - this.dataSource = ((TransactionAwareDataSourceProxy) dataSource).getTargetDataSource(); - } - else { - this.dataSource = dataSource; - } - } - - /** - * Return the JDBC DataSource that this instance manages transactions for. - */ - public DataSource getDataSource() { - return this.dataSource; - } - - /** - * Set whether to autodetect a JDBC DataSource used by the Hibernate SessionFactory, - * if set via LocalSessionFactoryBean's {@code setDataSource}. Default is "true". - *

Can be turned off to deliberately ignore an available DataSource, in order - * to not expose Hibernate transactions as JDBC transactions for that DataSource. - * @see #setDataSource - */ - public void setAutodetectDataSource(boolean autodetectDataSource) { - this.autodetectDataSource = autodetectDataSource; - } - - /** - * Set whether to prepare the underlying JDBC Connection of a transactional - * Hibernate Session, that is, whether to apply a transaction-specific - * isolation level and/or the transaction's read-only flag to the underlying - * JDBC Connection. - *

Default is "true". If you turn this flag off, the transaction manager - * will not support per-transaction isolation levels anymore. It will not - * call {@code Connection.setReadOnly(true)} for read-only transactions - * anymore either. If this flag is turned off, no cleanup of a JDBC Connection - * is required after a transaction, since no Connection settings will get modified. - * @see java.sql.Connection#setTransactionIsolation - * @see java.sql.Connection#setReadOnly - */ - public void setPrepareConnection(boolean prepareConnection) { - this.prepareConnection = prepareConnection; - } - - /** - * Set whether to allow result access after completion, typically via Hibernate's - * ScrollableResults mechanism. - *

Default is "false". Turning this flag on enforces over-commit holdability on the - * underlying JDBC Connection (if {@link #prepareConnection "prepareConnection"} is on) - * and skips the disconnect-on-completion step. - * @since 4.1.2 - * @see java.sql.Connection#setHoldability - * @see ResultSet#HOLD_CURSORS_OVER_COMMIT - * @see #disconnectOnCompletion(Session) - */ - public void setAllowResultAccessAfterCompletion(boolean allowResultAccessAfterCompletion) { - this.allowResultAccessAfterCompletion = allowResultAccessAfterCompletion; - } - - /** - * Set whether to operate on a Hibernate-managed Session instead of a - * Spring-managed Session, that is, whether to obtain the Session through - * Hibernate's {@link org.hibernate.SessionFactory#getCurrentSession()} - * instead of {@link org.hibernate.SessionFactory#openSession()} (with a Spring - * {@link org.springframework.transaction.support.TransactionSynchronizationManager} - * check preceding it). - *

Default is "false", i.e. using a Spring-managed Session: taking the current - * thread-bound Session if available (e.g. in an Open-Session-in-View scenario), - * creating a new Session for the current transaction otherwise. - *

Switch this flag to "true" in order to enforce use of a Hibernate-managed Session. - * Note that this requires {@link org.hibernate.SessionFactory#getCurrentSession()} - * to always return a proper Session when called for a Spring-managed transaction; - * transaction begin will fail if the {@code getCurrentSession()} call fails. - *

This mode will typically be used in combination with a custom Hibernate - * {@link org.hibernate.context.spi.CurrentSessionContext} implementation that stores - * Sessions in a place other than Spring's TransactionSynchronizationManager. - * It may also be used in combination with Spring's Open-Session-in-View support - * (using Spring's default {@link SpringSessionContext}), in which case it subtly - * differs from the Spring-managed Session mode: The pre-bound Session will not - * receive a {@code clear()} call (on rollback) or a {@code disconnect()} - * call (on transaction completion) in such a scenario; this is rather left up - * to a custom CurrentSessionContext implementation (if desired). - */ - public void setHibernateManagedSession(boolean hibernateManagedSession) { - this.hibernateManagedSession = hibernateManagedSession; - } - - /** - * Set the bean name of a Hibernate entity interceptor that allows to inspect - * and change property values before writing to and reading from the database. - * Will get applied to any new Session created by this transaction manager. - *

Requires the bean factory to be known, to be able to resolve the bean - * name to an interceptor instance on session creation. Typically used for - * prototype interceptors, i.e. a new interceptor instance per session. - *

Can also be used for shared interceptor instances, but it is recommended - * to set the interceptor reference directly in such a scenario. - * @param entityInterceptorBeanName the name of the entity interceptor in - * the bean factory - * @see #setBeanFactory - * @see #setEntityInterceptor - */ - public void setEntityInterceptorBeanName(String entityInterceptorBeanName) { - this.entityInterceptor = entityInterceptorBeanName; - } - - /** - * Set a Hibernate entity interceptor that allows to inspect and change - * property values before writing to and reading from the database. - * Will get applied to any new Session created by this transaction manager. - *

Such an interceptor can either be set at the SessionFactory level, - * i.e. on LocalSessionFactoryBean, or at the Session level, i.e. on - * HibernateTransactionManager. - * @see LocalSessionFactoryBean#setEntityInterceptor - */ - public void setEntityInterceptor(Interceptor entityInterceptor) { - this.entityInterceptor = entityInterceptor; - } - - /** - * Return the current Hibernate entity interceptor, or {@code null} if none. - * Resolves an entity interceptor bean name via the bean factory, - * if necessary. - * @throws IllegalStateException if bean name specified but no bean factory set - * @throws BeansException if bean name resolution via the bean factory failed - * @see #setEntityInterceptor - * @see #setEntityInterceptorBeanName - * @see #setBeanFactory - */ - public Interceptor getEntityInterceptor() throws IllegalStateException, BeansException { - if (this.entityInterceptor instanceof Interceptor) { - return (Interceptor) entityInterceptor; - } - else if (this.entityInterceptor instanceof String) { - if (this.beanFactory == null) { - throw new IllegalStateException("Cannot get entity interceptor via bean name if no bean factory set"); - } - String beanName = (String) this.entityInterceptor; - return this.beanFactory.getBean(beanName, Interceptor.class); - } - else { - return null; - } - } - - /** - * The bean factory just needs to be known for resolving entity interceptor - * bean names. It does not need to be set for any other mode of operation. - * @see #setEntityInterceptorBeanName - */ - @Override - public void setBeanFactory(BeanFactory beanFactory) { - this.beanFactory = beanFactory; - } - - @Override - public void afterPropertiesSet() { - if (getSessionFactory() == null) { - throw new IllegalArgumentException("Property 'sessionFactory' is required"); - } - if (this.entityInterceptor instanceof String && this.beanFactory == null) { - throw new IllegalArgumentException("Property 'beanFactory' is required for 'entityInterceptorBeanName'"); - } - - // Check for SessionFactory's DataSource. - if (this.autodetectDataSource && getDataSource() == null) { - DataSource sfds = SessionFactoryUtils.getDataSource(getSessionFactory()); - if (sfds != null) { - // Use the SessionFactory's DataSource for exposing transactions to JDBC code. - if (logger.isInfoEnabled()) { - logger.info("Using DataSource [" + sfds + - "] of Hibernate SessionFactory for HibernateTransactionManager"); - } - setDataSource(sfds); - } - } - } - - - @Override - public Object getResourceFactory() { - return getSessionFactory(); - } - - @Override - protected Object doGetTransaction() { - HibernateTransactionObject txObject = new HibernateTransactionObject(); - txObject.setSavepointAllowed(isNestedTransactionAllowed()); - - SessionHolder sessionHolder = - (SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory()); - if (sessionHolder != null) { - if (logger.isDebugEnabled()) { - logger.debug("Found thread-bound Session [" + sessionHolder.getSession() + "] for Hibernate transaction"); - } - txObject.setSessionHolder(sessionHolder); - } - else if (this.hibernateManagedSession) { - try { - Session session = this.sessionFactory.getCurrentSession(); - if (logger.isDebugEnabled()) { - logger.debug("Found Hibernate-managed Session [" + session + "] for Spring-managed transaction"); - } - txObject.setExistingSession(session); - } - catch (HibernateException ex) { - throw new DataAccessResourceFailureException( - "Could not obtain Hibernate-managed Session for Spring-managed transaction", ex); - } - } - - if (getDataSource() != null) { - ConnectionHolder conHolder = (ConnectionHolder) - TransactionSynchronizationManager.getResource(getDataSource()); - txObject.setConnectionHolder(conHolder); - } - - return txObject; - } - - @Override - protected boolean isExistingTransaction(Object transaction) { - HibernateTransactionObject txObject = (HibernateTransactionObject) transaction; - return (txObject.hasSpringManagedTransaction() || - (this.hibernateManagedSession && txObject.hasHibernateManagedTransaction())); - } - - @Override - protected void doBegin(Object transaction, TransactionDefinition definition) { - HibernateTransactionObject txObject = (HibernateTransactionObject) transaction; - - if (txObject.hasConnectionHolder() && !txObject.getConnectionHolder().isSynchronizedWithTransaction()) { - throw new IllegalTransactionStateException( - "Pre-bound JDBC Connection found! HibernateTransactionManager does not support " + - "running within DataSourceTransactionManager if told to manage the DataSource itself. " + - "It is recommended to use a single HibernateTransactionManager for all transactions " + - "on a single DataSource, no matter whether Hibernate or JDBC access."); - } - - Session session = null; - - try { - if (txObject.getSessionHolder() == null || txObject.getSessionHolder().isSynchronizedWithTransaction()) { - Interceptor entityInterceptor = getEntityInterceptor(); - Session newSession = (entityInterceptor != null ? - getSessionFactory().withOptions().interceptor(entityInterceptor).openSession() : - getSessionFactory().openSession()); - if (logger.isDebugEnabled()) { - logger.debug("Opened new Session [" + newSession + "] for Hibernate transaction"); - } - txObject.setSession(newSession); - } - - session = txObject.getSessionHolder().getSession(); - - if (this.prepareConnection && isSameConnectionForEntireSession(session)) { - // We're allowed to change the transaction settings of the JDBC Connection. - if (logger.isDebugEnabled()) { - logger.debug("Preparing JDBC Connection of Hibernate Session [" + session + "]"); - } - Connection con = ((SessionImplementor) session).connection(); - Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition); - txObject.setPreviousIsolationLevel(previousIsolationLevel); - if (this.allowResultAccessAfterCompletion && !txObject.isNewSession()) { - int currentHoldability = con.getHoldability(); - if (currentHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT) { - txObject.setPreviousHoldability(currentHoldability); - con.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT); - } - } - } - else { - // Not allowed to change the transaction settings of the JDBC Connection. - if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) { - // We should set a specific isolation level but are not allowed to... - throw new InvalidIsolationLevelException( - "HibernateTransactionManager is not allowed to support custom isolation levels: " + - "make sure that its 'prepareConnection' flag is on (the default) and that the " + - "Hibernate connection release mode is set to 'on_close' (the default for JDBC)."); - } - if (logger.isDebugEnabled()) { - logger.debug("Not preparing JDBC Connection of Hibernate Session [" + session + "]"); - } - } - - if (definition.isReadOnly() && txObject.isNewSession()) { - // Just set to MANUAL in case of a new Session for this transaction. - session.setFlushMode(FlushMode.MANUAL); - } - - if (!definition.isReadOnly() && !txObject.isNewSession()) { - // We need AUTO or COMMIT for a non-read-only transaction. - FlushMode flushMode = session.getFlushMode(); - if (FlushMode.MANUAL.equals(flushMode)) { - session.setFlushMode(FlushMode.AUTO); - txObject.getSessionHolder().setPreviousFlushMode(flushMode); - } - } - - Transaction hibTx; - - // Register transaction timeout. - int timeout = determineTimeout(definition); - if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) { - // Use Hibernate's own transaction timeout mechanism on Hibernate 3.1+ - // Applies to all statements, also to inserts, updates and deletes! - hibTx = session.getTransaction(); - hibTx.setTimeout(timeout); - hibTx.begin(); - } - else { - // Open a plain Hibernate transaction without specified timeout. - hibTx = session.beginTransaction(); - } - - // Add the Hibernate transaction to the session holder. - txObject.getSessionHolder().setTransaction(hibTx); - - // Register the Hibernate Session's JDBC Connection for the DataSource, if set. - if (getDataSource() != null) { - Connection con = ((SessionImplementor) session).connection(); - ConnectionHolder conHolder = new ConnectionHolder(con); - if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) { - conHolder.setTimeoutInSeconds(timeout); - } - if (logger.isDebugEnabled()) { - logger.debug("Exposing Hibernate transaction as JDBC transaction [" + con + "]"); - } - TransactionSynchronizationManager.bindResource(getDataSource(), conHolder); - txObject.setConnectionHolder(conHolder); - } - - // Bind the session holder to the thread. - if (txObject.isNewSessionHolder()) { - TransactionSynchronizationManager.bindResource(getSessionFactory(), txObject.getSessionHolder()); - } - txObject.getSessionHolder().setSynchronizedWithTransaction(true); - } - - catch (Throwable ex) { - if (txObject.isNewSession()) { - try { - if (session.getTransaction().isActive()) { - session.getTransaction().rollback(); - } - } - catch (Throwable ex2) { - logger.debug("Could not rollback Session after failed transaction begin", ex); - } - finally { - SessionFactoryUtils.closeSession(session); - txObject.setSessionHolder(null); - } - } - throw new CannotCreateTransactionException("Could not open Hibernate Session for transaction", ex); - } - } - - @Override - protected Object doSuspend(Object transaction) { - HibernateTransactionObject txObject = (HibernateTransactionObject) transaction; - txObject.setSessionHolder(null); - SessionHolder sessionHolder = - (SessionHolder) TransactionSynchronizationManager.unbindResource(getSessionFactory()); - txObject.setConnectionHolder(null); - ConnectionHolder connectionHolder = null; - if (getDataSource() != null) { - connectionHolder = (ConnectionHolder) TransactionSynchronizationManager.unbindResource(getDataSource()); - } - return new SuspendedResourcesHolder(sessionHolder, connectionHolder); - } - - @Override - protected void doResume(Object transaction, Object suspendedResources) { - SuspendedResourcesHolder resourcesHolder = (SuspendedResourcesHolder) suspendedResources; - if (TransactionSynchronizationManager.hasResource(getSessionFactory())) { - // From non-transactional code running in active transaction synchronization - // -> can be safely removed, will be closed on transaction completion. - TransactionSynchronizationManager.unbindResource(getSessionFactory()); - } - TransactionSynchronizationManager.bindResource(getSessionFactory(), resourcesHolder.getSessionHolder()); - if (getDataSource() != null) { - TransactionSynchronizationManager.bindResource(getDataSource(), resourcesHolder.getConnectionHolder()); - } - } - - @Override - protected void doCommit(DefaultTransactionStatus status) { - HibernateTransactionObject txObject = (HibernateTransactionObject) status.getTransaction(); - if (status.isDebug()) { - logger.debug("Committing Hibernate transaction on Session [" + - txObject.getSessionHolder().getSession() + "]"); - } - try { - txObject.getSessionHolder().getTransaction().commit(); - } - catch (org.hibernate.TransactionException ex) { - // assumably from commit call to the underlying JDBC connection - throw new TransactionSystemException("Could not commit Hibernate transaction", ex); - } - catch (HibernateException ex) { - // assumably failed to flush changes to database - throw convertHibernateAccessException(ex); - } - } - - @Override - protected void doRollback(DefaultTransactionStatus status) { - HibernateTransactionObject txObject = (HibernateTransactionObject) status.getTransaction(); - if (status.isDebug()) { - logger.debug("Rolling back Hibernate transaction on Session [" + - txObject.getSessionHolder().getSession() + "]"); - } - try { - txObject.getSessionHolder().getTransaction().rollback(); - } - catch (org.hibernate.TransactionException ex) { - throw new TransactionSystemException("Could not roll back Hibernate transaction", ex); - } - catch (HibernateException ex) { - // Shouldn't really happen, as a rollback doesn't cause a flush. - throw convertHibernateAccessException(ex); - } - finally { - if (!txObject.isNewSession() && !this.hibernateManagedSession) { - // Clear all pending inserts/updates/deletes in the Session. - // Necessary for pre-bound Sessions, to avoid inconsistent state. - txObject.getSessionHolder().getSession().clear(); - } - } - } - - @Override - protected void doSetRollbackOnly(DefaultTransactionStatus status) { - HibernateTransactionObject txObject = (HibernateTransactionObject) status.getTransaction(); - if (status.isDebug()) { - logger.debug("Setting Hibernate transaction on Session [" + - txObject.getSessionHolder().getSession() + "] rollback-only"); - } - txObject.setRollbackOnly(); - } - - @Override - protected void doCleanupAfterCompletion(Object transaction) { - HibernateTransactionObject txObject = (HibernateTransactionObject) transaction; - - // Remove the session holder from the thread. - if (txObject.isNewSessionHolder()) { - TransactionSynchronizationManager.unbindResource(getSessionFactory()); - } - - // Remove the JDBC connection holder from the thread, if exposed. - if (getDataSource() != null) { - TransactionSynchronizationManager.unbindResource(getDataSource()); - } - - Session session = txObject.getSessionHolder().getSession(); - if (this.prepareConnection && session.isConnected() && isSameConnectionForEntireSession(session)) { - // We're running with connection release mode "on_close": We're able to reset - // the isolation level and/or read-only flag of the JDBC Connection here. - // Else, we need to rely on the connection pool to perform proper cleanup. - try { - Connection con = ((SessionImplementor) session).connection(); - Integer previousHoldability = txObject.getPreviousHoldability(); - if (previousHoldability != null) { - con.setHoldability(previousHoldability); - } - DataSourceUtils.resetConnectionAfterTransaction(con, txObject.getPreviousIsolationLevel()); - } - catch (HibernateException ex) { - logger.debug("Could not access JDBC Connection of Hibernate Session", ex); - } - catch (Throwable ex) { - logger.debug("Could not reset JDBC Connection after transaction", ex); - } - } - - if (txObject.isNewSession()) { - if (logger.isDebugEnabled()) { - logger.debug("Closing Hibernate Session [" + session + "] after transaction"); - } - SessionFactoryUtils.closeSession(session); - } - else { - if (logger.isDebugEnabled()) { - logger.debug("Not closing pre-bound Hibernate Session [" + session + "] after transaction"); - } - if (txObject.getSessionHolder().getPreviousFlushMode() != null) { - session.setFlushMode(txObject.getSessionHolder().getPreviousFlushMode()); - } - if (!this.allowResultAccessAfterCompletion && !this.hibernateManagedSession) { - disconnectOnCompletion(session); - } - } - txObject.getSessionHolder().clear(); - } - - /** - * Disconnect a pre-existing Hibernate Session on transaction completion, - * returning its database connection but preserving its entity state. - *

The default implementation simply calls {@link Session#disconnect()}. - * Subclasses may override this with a no-op or with fine-tuned disconnection logic. - * @param session the Hibernate Session to disconnect - * @since 4.1.2 - * @see org.hibernate.Session#disconnect() - */ - protected void disconnectOnCompletion(Session session) { - session.disconnect(); - } - - /** - * Return whether the given Hibernate Session will always hold the same - * JDBC Connection. This is used to check whether the transaction manager - * can safely prepare and clean up the JDBC Connection used for a transaction. - *

The default implementation checks the Session's connection release mode - * to be "on_close". - * @param session the Hibernate Session to check - * @see org.hibernate.engine.transaction.spi.TransactionContext#getConnectionReleaseMode() - * @see org.hibernate.ConnectionReleaseMode#ON_CLOSE - */ - protected boolean isSameConnectionForEntireSession(Session session) { - if (!(session instanceof TransactionContext)) { - // The best we can do is to assume we're safe. - return true; - } - ConnectionReleaseMode releaseMode = ((TransactionContext) session).getConnectionReleaseMode(); - return ConnectionReleaseMode.ON_CLOSE.equals(releaseMode); - } - - - /** - * Convert the given HibernateException to an appropriate exception - * from the {@code org.springframework.dao} hierarchy. - *

Will automatically apply a specified SQLExceptionTranslator to a - * Hibernate JDBCException, else rely on Hibernate's default translation. - * @param ex HibernateException that occurred - * @return a corresponding DataAccessException - * @see SessionFactoryUtils#convertHibernateAccessException - */ - protected DataAccessException convertHibernateAccessException(HibernateException ex) { - return SessionFactoryUtils.convertHibernateAccessException(ex); - } - - - /** - * Hibernate transaction object, representing a SessionHolder. - * Used as transaction object by HibernateTransactionManager. - */ - private class HibernateTransactionObject extends JdbcTransactionObjectSupport { - - private SessionHolder sessionHolder; - - private boolean newSessionHolder; - - private boolean newSession; - - private Integer previousHoldability; - - public void setSession(Session session) { - this.sessionHolder = new SessionHolder(session); - this.newSessionHolder = true; - this.newSession = true; - } - - public void setExistingSession(Session session) { - this.sessionHolder = new SessionHolder(session); - this.newSessionHolder = true; - this.newSession = false; - } - - public void setSessionHolder(SessionHolder sessionHolder) { - this.sessionHolder = sessionHolder; - this.newSessionHolder = false; - this.newSession = false; - } - - public SessionHolder getSessionHolder() { - return this.sessionHolder; - } - - public boolean isNewSessionHolder() { - return this.newSessionHolder; - } - - public boolean isNewSession() { - return this.newSession; - } - - public void setPreviousHoldability(Integer previousHoldability) { - this.previousHoldability = previousHoldability; - } - - public Integer getPreviousHoldability() { - return this.previousHoldability; - } - - public boolean hasSpringManagedTransaction() { - return (this.sessionHolder != null && this.sessionHolder.getTransaction() != null); - } - - public boolean hasHibernateManagedTransaction() { - return (this.sessionHolder != null && this.sessionHolder.getSession().getTransaction().isActive()); - } - - public void setRollbackOnly() { - this.sessionHolder.setRollbackOnly(); - if (hasConnectionHolder()) { - getConnectionHolder().setRollbackOnly(); - } - } - - @Override - public boolean isRollbackOnly() { - return this.sessionHolder.isRollbackOnly() || - (hasConnectionHolder() && getConnectionHolder().isRollbackOnly()); - } - - @Override - public void flush() { - try { - this.sessionHolder.getSession().flush(); - } - catch (HibernateException ex) { - throw convertHibernateAccessException(ex); - } - } - } - - - /** - * Holder for suspended resources. - * Used internally by {@code doSuspend} and {@code doResume}. - */ - private static class SuspendedResourcesHolder { - - private final SessionHolder sessionHolder; - - private final ConnectionHolder connectionHolder; - - private SuspendedResourcesHolder(SessionHolder sessionHolder, ConnectionHolder conHolder) { - this.sessionHolder = sessionHolder; - this.connectionHolder = conHolder; - } - - private SessionHolder getSessionHolder() { - return this.sessionHolder; - } - - private ConnectionHolder getConnectionHolder() { - return this.connectionHolder; - } - } - -} diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBean.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBean.java deleted file mode 100644 index 7a42e295d6..0000000000 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBean.java +++ /dev/null @@ -1,491 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate4; - -import java.io.File; -import java.io.IOException; -import java.util.Properties; -import javax.sql.DataSource; - -import org.hibernate.Interceptor; -import org.hibernate.SessionFactory; -import org.hibernate.cache.spi.RegionFactory; -import org.hibernate.cfg.Configuration; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.context.ResourceLoaderAware; -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; -import org.springframework.core.io.ResourceLoader; -import org.springframework.core.io.support.PathMatchingResourcePatternResolver; -import org.springframework.core.io.support.ResourcePatternResolver; -import org.springframework.core.io.support.ResourcePatternUtils; -import org.springframework.core.type.filter.TypeFilter; - -/** - * {@link org.springframework.beans.factory.FactoryBean} that creates a Hibernate - * {@link org.hibernate.SessionFactory}. This is the usual way to set up a shared - * Hibernate SessionFactory in a Spring application context; the SessionFactory can - * then be passed to Hibernate-based data access objects via dependency injection. - * - *

This variant of LocalSessionFactoryBean requires Hibernate 4.0 or higher. - * As of Spring 4.0, it is compatible with (the quite refactored) Hibernate 4.3 as well. - * We recommend using the latest Hibernate 4.2.x or 4.3.x version, depending on whether - * you need to remain JPA 2.0 compatible at runtime (Hibernate 4.2) or can upgrade to - * JPA 2.1 (Hibernate 4.3). - * - *

This class is similar in role to the same-named class in the {@code orm.hibernate3} - * package. However, in practice, it is closer to {@code AnnotationSessionFactoryBean} - * since its core purpose is to bootstrap a {@code SessionFactory} from package scanning. - * - *

NOTE: To set up Hibernate 4 for Spring-driven JTA transactions, make - * sure to either specify the {@link #setJtaTransactionManager "jtaTransactionManager"} - * bean property or to set the "hibernate.transaction.factory_class" property to - * {@link org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory}. - * Otherwise, Hibernate's smart flushing mechanism won't work properly. - * - * @author Juergen Hoeller - * @since 3.1 - * @see #setDataSource - * @see #setPackagesToScan - * @see LocalSessionFactoryBuilder - */ -public class LocalSessionFactoryBean extends HibernateExceptionTranslator - implements FactoryBean, ResourceLoaderAware, InitializingBean, DisposableBean { - - private DataSource dataSource; - - private Resource[] configLocations; - - private String[] mappingResources; - - private Resource[] mappingLocations; - - private Resource[] cacheableMappingLocations; - - private Resource[] mappingJarLocations; - - private Resource[] mappingDirectoryLocations; - - private Interceptor entityInterceptor; - - @SuppressWarnings("deprecation") - private org.hibernate.cfg.NamingStrategy namingStrategy; - - private Object jtaTransactionManager; - - private Object multiTenantConnectionProvider; - - private Object currentTenantIdentifierResolver; - - private RegionFactory cacheRegionFactory; - - private TypeFilter[] entityTypeFilters; - - private Properties hibernateProperties; - - private Class[] annotatedClasses; - - private String[] annotatedPackages; - - private String[] packagesToScan; - - private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver(); - - private Configuration configuration; - - private SessionFactory sessionFactory; - - - /** - * Set the DataSource to be used by the SessionFactory. - * If set, this will override corresponding settings in Hibernate properties. - *

If this is set, the Hibernate settings should not define - * a connection provider to avoid meaningless double configuration. - */ - public void setDataSource(DataSource dataSource) { - this.dataSource = dataSource; - } - - /** - * Set the location of a single Hibernate XML config file, for example as - * classpath resource "classpath:hibernate.cfg.xml". - *

Note: Can be omitted when all necessary properties and mapping - * resources are specified locally via this bean. - * @see org.hibernate.cfg.Configuration#configure(java.net.URL) - */ - public void setConfigLocation(Resource configLocation) { - this.configLocations = new Resource[] {configLocation}; - } - - /** - * Set the locations of multiple Hibernate XML config files, for example as - * classpath resources "classpath:hibernate.cfg.xml,classpath:extension.cfg.xml". - *

Note: Can be omitted when all necessary properties and mapping - * resources are specified locally via this bean. - * @see org.hibernate.cfg.Configuration#configure(java.net.URL) - */ - public void setConfigLocations(Resource... configLocations) { - this.configLocations = configLocations; - } - - /** - * Set Hibernate mapping resources to be found in the class path, - * like "example.hbm.xml" or "mypackage/example.hbm.xml". - * Analogous to mapping entries in a Hibernate XML config file. - * Alternative to the more generic setMappingLocations method. - *

Can be used to add to mappings from a Hibernate XML config file, - * or to specify all mappings locally. - * @see #setMappingLocations - * @see org.hibernate.cfg.Configuration#addResource - */ - public void setMappingResources(String... mappingResources) { - this.mappingResources = mappingResources; - } - - /** - * Set locations of Hibernate mapping files, for example as classpath - * resource "classpath:example.hbm.xml". Supports any resource location - * via Spring's resource abstraction, for example relative paths like - * "WEB-INF/mappings/example.hbm.xml" when running in an application context. - *

Can be used to add to mappings from a Hibernate XML config file, - * or to specify all mappings locally. - * @see org.hibernate.cfg.Configuration#addInputStream - */ - public void setMappingLocations(Resource... mappingLocations) { - this.mappingLocations = mappingLocations; - } - - /** - * Set locations of cacheable Hibernate mapping files, for example as web app - * resource "/WEB-INF/mapping/example.hbm.xml". Supports any resource location - * via Spring's resource abstraction, as long as the resource can be resolved - * in the file system. - *

Can be used to add to mappings from a Hibernate XML config file, - * or to specify all mappings locally. - * @see org.hibernate.cfg.Configuration#addCacheableFile(java.io.File) - */ - public void setCacheableMappingLocations(Resource... cacheableMappingLocations) { - this.cacheableMappingLocations = cacheableMappingLocations; - } - - /** - * Set locations of jar files that contain Hibernate mapping resources, - * like "WEB-INF/lib/example.hbm.jar". - *

Can be used to add to mappings from a Hibernate XML config file, - * or to specify all mappings locally. - * @see org.hibernate.cfg.Configuration#addJar(java.io.File) - */ - public void setMappingJarLocations(Resource... mappingJarLocations) { - this.mappingJarLocations = mappingJarLocations; - } - - /** - * Set locations of directories that contain Hibernate mapping resources, - * like "WEB-INF/mappings". - *

Can be used to add to mappings from a Hibernate XML config file, - * or to specify all mappings locally. - * @see org.hibernate.cfg.Configuration#addDirectory(java.io.File) - */ - public void setMappingDirectoryLocations(Resource... mappingDirectoryLocations) { - this.mappingDirectoryLocations = mappingDirectoryLocations; - } - - /** - * Set a Hibernate entity interceptor that allows to inspect and change - * property values before writing to and reading from the database. - * Will get applied to any new Session created by this factory. - * @see org.hibernate.cfg.Configuration#setInterceptor - */ - public void setEntityInterceptor(Interceptor entityInterceptor) { - this.entityInterceptor = entityInterceptor; - } - - /** - * Set a Hibernate NamingStrategy for the SessionFactory, determining the - * physical column and table names given the info in the mapping document. - * @see org.hibernate.cfg.Configuration#setNamingStrategy - */ - @SuppressWarnings("deprecation") - public void setNamingStrategy(org.hibernate.cfg.NamingStrategy namingStrategy) { - this.namingStrategy = namingStrategy; - } - - /** - * Set the Spring {@link org.springframework.transaction.jta.JtaTransactionManager} - * or the JTA {@link javax.transaction.TransactionManager} to be used with Hibernate, - * if any. Implicitly sets up {@code JtaPlatform} and {@code CMTTransactionStrategy}. - * @see LocalSessionFactoryBuilder#setJtaTransactionManager - */ - public void setJtaTransactionManager(Object jtaTransactionManager) { - this.jtaTransactionManager = jtaTransactionManager; - } - - /** - * Set a Hibernate 4.1/4.2/4.3 {@code MultiTenantConnectionProvider} to be passed - * on to the SessionFactory: as an instance, a Class, or a String class name. - *

Note that the package location of the {@code MultiTenantConnectionProvider} - * interface changed between Hibernate 4.2 and 4.3. This method accepts both variants. - * @since 4.0 - * @see LocalSessionFactoryBuilder#setMultiTenantConnectionProvider - */ - public void setMultiTenantConnectionProvider(Object multiTenantConnectionProvider) { - this.multiTenantConnectionProvider = multiTenantConnectionProvider; - } - - /** - * Set a Hibernate 4.1/4.2/4.3 {@code CurrentTenantIdentifierResolver} to be passed - * on to the SessionFactory: as an instance, a Class, or a String class name. - * @since 4.0 - * @see LocalSessionFactoryBuilder#setCurrentTenantIdentifierResolver - */ - public void setCurrentTenantIdentifierResolver(Object currentTenantIdentifierResolver) { - this.currentTenantIdentifierResolver = currentTenantIdentifierResolver; - } - - /** - * Set the Hibernate RegionFactory to use for the SessionFactory. - * Allows for using a Spring-managed RegionFactory instance. - *

Note: If this is set, the Hibernate settings should not define a - * cache provider to avoid meaningless double configuration. - * @since 4.0 - * @see org.hibernate.cache.spi.RegionFactory - * @see LocalSessionFactoryBuilder#setCacheRegionFactory - */ - public void setCacheRegionFactory(RegionFactory cacheRegionFactory) { - this.cacheRegionFactory = cacheRegionFactory; - } - - /** - * Specify custom type filters for Spring-based scanning for entity classes. - *

Default is to search all specified packages for classes annotated with - * {@code @javax.persistence.Entity}, {@code @javax.persistence.Embeddable} - * or {@code @javax.persistence.MappedSuperclass}. - * @since 4.1 - * @see #setPackagesToScan - */ - public void setEntityTypeFilters(TypeFilter... entityTypeFilters) { - this.entityTypeFilters = entityTypeFilters; - } - - /** - * Set Hibernate properties, such as "hibernate.dialect". - *

Note: Do not specify a transaction provider here when using - * Spring-driven transactions. It is also advisable to omit connection - * provider settings and use a Spring-set DataSource instead. - * @see #setDataSource - */ - public void setHibernateProperties(Properties hibernateProperties) { - this.hibernateProperties = hibernateProperties; - } - - /** - * Return the Hibernate properties, if any. Mainly available for - * configuration through property paths that specify individual keys. - */ - public Properties getHibernateProperties() { - if (this.hibernateProperties == null) { - this.hibernateProperties = new Properties(); - } - return this.hibernateProperties; - } - - /** - * Specify annotated entity classes to register with this Hibernate SessionFactory. - * @see org.hibernate.cfg.Configuration#addAnnotatedClass(Class) - */ - public void setAnnotatedClasses(Class... annotatedClasses) { - this.annotatedClasses = annotatedClasses; - } - - /** - * Specify the names of annotated packages, for which package-level - * annotation metadata will be read. - * @see org.hibernate.cfg.Configuration#addPackage(String) - */ - public void setAnnotatedPackages(String... annotatedPackages) { - this.annotatedPackages = annotatedPackages; - } - - /** - * Specify packages to search for autodetection of your entity classes in the - * classpath. This is analogous to Spring's component-scan feature - * ({@link org.springframework.context.annotation.ClassPathBeanDefinitionScanner}). - */ - public void setPackagesToScan(String... packagesToScan) { - this.packagesToScan = packagesToScan; - } - - @Override - public void setResourceLoader(ResourceLoader resourceLoader) { - this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader); - } - - - @Override - public void afterPropertiesSet() throws IOException { - LocalSessionFactoryBuilder sfb = new LocalSessionFactoryBuilder(this.dataSource, this.resourcePatternResolver); - - if (this.configLocations != null) { - for (Resource resource : this.configLocations) { - // Load Hibernate configuration from given location. - sfb.configure(resource.getURL()); - } - } - - if (this.mappingResources != null) { - // Register given Hibernate mapping definitions, contained in resource files. - for (String mapping : this.mappingResources) { - Resource mr = new ClassPathResource(mapping.trim(), this.resourcePatternResolver.getClassLoader()); - sfb.addInputStream(mr.getInputStream()); - } - } - - if (this.mappingLocations != null) { - // Register given Hibernate mapping definitions, contained in resource files. - for (Resource resource : this.mappingLocations) { - sfb.addInputStream(resource.getInputStream()); - } - } - - if (this.cacheableMappingLocations != null) { - // Register given cacheable Hibernate mapping definitions, read from the file system. - for (Resource resource : this.cacheableMappingLocations) { - sfb.addCacheableFile(resource.getFile()); - } - } - - if (this.mappingJarLocations != null) { - // Register given Hibernate mapping definitions, contained in jar files. - for (Resource resource : this.mappingJarLocations) { - sfb.addJar(resource.getFile()); - } - } - - if (this.mappingDirectoryLocations != null) { - // Register all Hibernate mapping definitions in the given directories. - for (Resource resource : this.mappingDirectoryLocations) { - File file = resource.getFile(); - if (!file.isDirectory()) { - throw new IllegalArgumentException( - "Mapping directory location [" + resource + "] does not denote a directory"); - } - sfb.addDirectory(file); - } - } - - if (this.entityInterceptor != null) { - sfb.setInterceptor(this.entityInterceptor); - } - - if (this.namingStrategy != null) { - sfb.setNamingStrategy(this.namingStrategy); - } - - if (this.jtaTransactionManager != null) { - sfb.setJtaTransactionManager(this.jtaTransactionManager); - } - - if (this.multiTenantConnectionProvider != null) { - sfb.setMultiTenantConnectionProvider(this.multiTenantConnectionProvider); - } - - if (this.currentTenantIdentifierResolver != null) { - sfb.setCurrentTenantIdentifierResolver(this.currentTenantIdentifierResolver); - } - - if (this.cacheRegionFactory != null) { - sfb.setCacheRegionFactory(this.cacheRegionFactory); - } - - if (this.entityTypeFilters != null) { - sfb.setEntityTypeFilters(this.entityTypeFilters); - } - - if (this.hibernateProperties != null) { - sfb.addProperties(this.hibernateProperties); - } - - if (this.annotatedClasses != null) { - sfb.addAnnotatedClasses(this.annotatedClasses); - } - - if (this.annotatedPackages != null) { - sfb.addPackages(this.annotatedPackages); - } - - if (this.packagesToScan != null) { - sfb.scanPackages(this.packagesToScan); - } - - // Build SessionFactory instance. - this.configuration = sfb; - this.sessionFactory = buildSessionFactory(sfb); - } - - /** - * Subclasses can override this method to perform custom initialization - * of the SessionFactory instance, creating it via the given Configuration - * object that got prepared by this LocalSessionFactoryBean. - *

The default implementation invokes LocalSessionFactoryBuilder's buildSessionFactory. - * A custom implementation could prepare the instance in a specific way (e.g. applying - * a custom ServiceRegistry) or use a custom SessionFactoryImpl subclass. - * @param sfb LocalSessionFactoryBuilder prepared by this LocalSessionFactoryBean - * @return the SessionFactory instance - * @see LocalSessionFactoryBuilder#buildSessionFactory - */ - protected SessionFactory buildSessionFactory(LocalSessionFactoryBuilder sfb) { - return sfb.buildSessionFactory(); - } - - /** - * Return the Hibernate Configuration object used to build the SessionFactory. - * Allows for access to configuration metadata stored there (rarely needed). - * @throws IllegalStateException if the Configuration object has not been initialized yet - */ - public final Configuration getConfiguration() { - if (this.configuration == null) { - throw new IllegalStateException("Configuration not initialized yet"); - } - return this.configuration; - } - - - @Override - public SessionFactory getObject() { - return this.sessionFactory; - } - - @Override - public Class getObjectType() { - return (this.sessionFactory != null ? this.sessionFactory.getClass() : SessionFactory.class); - } - - @Override - public boolean isSingleton() { - return true; - } - - - @Override - public void destroy() { - this.sessionFactory.close(); - } - -} diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBuilder.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBuilder.java deleted file mode 100644 index dcbfbdb51c..0000000000 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBuilder.java +++ /dev/null @@ -1,393 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate4; - -import java.io.IOException; -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.util.Properties; -import java.util.Set; -import java.util.TreeSet; -import javax.persistence.AttributeConverter; -import javax.persistence.Embeddable; -import javax.persistence.Entity; -import javax.persistence.MappedSuperclass; -import javax.sql.DataSource; -import javax.transaction.TransactionManager; - -import org.hibernate.HibernateException; -import org.hibernate.MappingException; -import org.hibernate.SessionFactory; -import org.hibernate.cache.spi.RegionFactory; -import org.hibernate.cfg.AvailableSettings; -import org.hibernate.cfg.Configuration; -import org.hibernate.cfg.Environment; -import org.hibernate.cfg.Settings; -import org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory; -import org.hibernate.service.ServiceRegistry; - -import org.springframework.core.io.Resource; -import org.springframework.core.io.ResourceLoader; -import org.springframework.core.io.support.PathMatchingResourcePatternResolver; -import org.springframework.core.io.support.ResourcePatternResolver; -import org.springframework.core.io.support.ResourcePatternUtils; -import org.springframework.core.type.classreading.CachingMetadataReaderFactory; -import org.springframework.core.type.classreading.MetadataReader; -import org.springframework.core.type.classreading.MetadataReaderFactory; -import org.springframework.core.type.filter.AnnotationTypeFilter; -import org.springframework.core.type.filter.TypeFilter; -import org.springframework.transaction.jta.JtaTransactionManager; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; - -/** - * A Spring-provided extension of the standard Hibernate {@link Configuration} class, - * adding {@link SpringSessionContext} as a default and providing convenient ways - * to specify a DataSource and an application class loader. - * - *

This is designed for programmatic use, e.g. in {@code @Bean} factory methods. - * Consider using {@link LocalSessionFactoryBean} for XML bean definition files. - * - *

Requires Hibernate 4.0 or higher. As of Spring 4.0, it is compatible with - * (the quite refactored) Hibernate 4.3 as well. We recommend using the latest - * Hibernate 4.2.x or 4.3.x version, depending on whether you need to remain JPA 2.0 - * compatible at runtime (Hibernate 4.2) or can upgrade to JPA 2.1 (Hibernate 4.3). - * - *

NOTE: To set up Hibernate 4 for Spring-driven JTA transactions, make - * sure to either use the {@link #setJtaTransactionManager} method or to set the - * "hibernate.transaction.factory_class" property to {@link CMTTransactionFactory}. - * Otherwise, Hibernate's smart flushing mechanism won't work properly. - * - * @author Juergen Hoeller - * @since 3.1 - * @see LocalSessionFactoryBean - */ -@SuppressWarnings("serial") -public class LocalSessionFactoryBuilder extends Configuration { - - private static final String RESOURCE_PATTERN = "/**/*.class"; - - private static final String PACKAGE_INFO_SUFFIX = ".package-info"; - - private static final TypeFilter[] DEFAULT_ENTITY_TYPE_FILTERS = new TypeFilter[] { - new AnnotationTypeFilter(Entity.class, false), - new AnnotationTypeFilter(Embeddable.class, false), - new AnnotationTypeFilter(MappedSuperclass.class, false)}; - - - private static TypeFilter converterTypeFilter; - - static { - try { - @SuppressWarnings("unchecked") - Class converterAnnotation = (Class) - ClassUtils.forName("javax.persistence.Converter", LocalSessionFactoryBuilder.class.getClassLoader()); - converterTypeFilter = new AnnotationTypeFilter(converterAnnotation, false); - } - catch (ClassNotFoundException ex) { - // JPA 2.1 API not available - Hibernate <4.3 - } - } - - - private final ResourcePatternResolver resourcePatternResolver; - - private RegionFactory cacheRegionFactory; - - private TypeFilter[] entityTypeFilters = DEFAULT_ENTITY_TYPE_FILTERS; - - - /** - * Create a new LocalSessionFactoryBuilder for the given DataSource. - * @param dataSource the JDBC DataSource that the resulting Hibernate SessionFactory should be using - * (may be {@code null}) - */ - public LocalSessionFactoryBuilder(DataSource dataSource) { - this(dataSource, new PathMatchingResourcePatternResolver()); - } - - /** - * Create a new LocalSessionFactoryBuilder for the given DataSource. - * @param dataSource the JDBC DataSource that the resulting Hibernate SessionFactory should be using - * (may be {@code null}) - * @param classLoader the ClassLoader to load application classes from - */ - public LocalSessionFactoryBuilder(DataSource dataSource, ClassLoader classLoader) { - this(dataSource, new PathMatchingResourcePatternResolver(classLoader)); - } - - /** - * Create a new LocalSessionFactoryBuilder for the given DataSource. - * @param dataSource the JDBC DataSource that the resulting Hibernate SessionFactory should be using - * (may be {@code null}) - * @param resourceLoader the ResourceLoader to load application classes from - */ - @SuppressWarnings("deprecation") // to be able to build against Hibernate 4.3 - public LocalSessionFactoryBuilder(DataSource dataSource, ResourceLoader resourceLoader) { - getProperties().put(Environment.CURRENT_SESSION_CONTEXT_CLASS, SpringSessionContext.class.getName()); - if (dataSource != null) { - getProperties().put(Environment.DATASOURCE, dataSource); - } - // APP_CLASSLOADER is deprecated as of Hibernate 4.3 but we need to remain compatible with 4.0+ - getProperties().put(AvailableSettings.APP_CLASSLOADER, resourceLoader.getClassLoader()); - this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader); - } - - - /** - * Set the Spring {@link JtaTransactionManager} or the JTA {@link TransactionManager} - * to be used with Hibernate, if any. Allows for using a Spring-managed transaction - * manager for Hibernate 4's session and cache synchronization, with the - * "hibernate.transaction.jta.platform" automatically set to it. Also sets - * "hibernate.transaction.factory_class" to {@link CMTTransactionFactory}, - * instructing Hibernate to interact with externally managed transactions. - *

A passed-in Spring {@link JtaTransactionManager} needs to contain a JTA - * {@link TransactionManager} reference to be usable here, except for the WebSphere - * case where we'll automatically set {@code WebSphereExtendedJtaPlatform} accordingly. - *

Note: If this is set, the Hibernate settings should not contain a JTA platform - * setting to avoid meaningless double configuration. - */ - public LocalSessionFactoryBuilder setJtaTransactionManager(Object jtaTransactionManager) { - Assert.notNull(jtaTransactionManager, "Transaction manager reference must not be null"); - if (jtaTransactionManager instanceof JtaTransactionManager) { - boolean webspherePresent = ClassUtils.isPresent("com.ibm.wsspi.uow.UOWManager", getClass().getClassLoader()); - if (webspherePresent) { - getProperties().put(AvailableSettings.JTA_PLATFORM, - ConfigurableJtaPlatform.getJtaPlatformBasePackage() + "internal.WebSphereExtendedJtaPlatform"); - } - else { - JtaTransactionManager jtaTm = (JtaTransactionManager) jtaTransactionManager; - if (jtaTm.getTransactionManager() == null) { - throw new IllegalArgumentException( - "Can only apply JtaTransactionManager which has a TransactionManager reference set"); - } - getProperties().put(AvailableSettings.JTA_PLATFORM, - new ConfigurableJtaPlatform(jtaTm.getTransactionManager(), jtaTm.getUserTransaction(), - jtaTm.getTransactionSynchronizationRegistry()).getJtaPlatformProxy()); - } - } - else if (jtaTransactionManager instanceof TransactionManager) { - getProperties().put(AvailableSettings.JTA_PLATFORM, - new ConfigurableJtaPlatform((TransactionManager) jtaTransactionManager, null, null).getJtaPlatformProxy()); - } - else { - throw new IllegalArgumentException( - "Unknown transaction manager type: " + jtaTransactionManager.getClass().getName()); - } - getProperties().put(AvailableSettings.TRANSACTION_STRATEGY, new CMTTransactionFactory()); - return this; - } - - /** - * Set a Hibernate 4.1/4.2/4.3 {@code MultiTenantConnectionProvider} to be passed - * on to the SessionFactory: as an instance, a Class, or a String class name. - *

Note that the package location of the {@code MultiTenantConnectionProvider} - * interface changed between Hibernate 4.2 and 4.3. This method accepts both variants. - * @since 4.0 - * @see AvailableSettings#MULTI_TENANT_CONNECTION_PROVIDER - */ - public LocalSessionFactoryBuilder setMultiTenantConnectionProvider(Object multiTenantConnectionProvider) { - getProperties().put(AvailableSettings.MULTI_TENANT_CONNECTION_PROVIDER, multiTenantConnectionProvider); - return this; - } - - /** - * Set a Hibernate 4.1/4.2/4.3 {@code CurrentTenantIdentifierResolver} to be passed - * on to the SessionFactory: as an instance, a Class, or a String class name. - * @since 4.0 - * @see AvailableSettings#MULTI_TENANT_IDENTIFIER_RESOLVER - */ - public LocalSessionFactoryBuilder setCurrentTenantIdentifierResolver(Object currentTenantIdentifierResolver) { - getProperties().put(AvailableSettings.MULTI_TENANT_IDENTIFIER_RESOLVER, currentTenantIdentifierResolver); - return this; - } - - /** - * Set the Hibernate RegionFactory to use for the SessionFactory. - * Allows for using a Spring-managed RegionFactory instance. - *

Note: If this is set, the Hibernate settings should not define a - * cache provider to avoid meaningless double configuration. - * @since 4.0 - * @see org.hibernate.cache.spi.RegionFactory - */ - public LocalSessionFactoryBuilder setCacheRegionFactory(RegionFactory cacheRegionFactory) { - this.cacheRegionFactory = cacheRegionFactory; - return this; - } - - /** - * Specify custom type filters for Spring-based scanning for entity classes. - *

Default is to search all specified packages for classes annotated with - * {@code @javax.persistence.Entity}, {@code @javax.persistence.Embeddable} - * or {@code @javax.persistence.MappedSuperclass}. - * @since 4.1 - * @see #scanPackages - */ - public LocalSessionFactoryBuilder setEntityTypeFilters(TypeFilter... entityTypeFilters) { - this.entityTypeFilters = entityTypeFilters; - return this; - } - - /** - * Add the given annotated classes in a batch. - * @see #addAnnotatedClass - * @see #scanPackages - */ - public LocalSessionFactoryBuilder addAnnotatedClasses(Class... annotatedClasses) { - for (Class annotatedClass : annotatedClasses) { - addAnnotatedClass(annotatedClass); - } - return this; - } - - /** - * Add the given annotated packages in a batch. - * @see #addPackage - * @see #scanPackages - */ - public LocalSessionFactoryBuilder addPackages(String... annotatedPackages) { - for (String annotatedPackage : annotatedPackages) { - addPackage(annotatedPackage); - } - return this; - } - - /** - * Perform Spring-based scanning for entity classes, registering them - * as annotated classes with this {@code Configuration}. - * @param packagesToScan one or more Java package names - * @throws HibernateException if scanning fails for any reason - */ - public LocalSessionFactoryBuilder scanPackages(String... packagesToScan) throws HibernateException { - Set entityClassNames = new TreeSet(); - Set converterClassNames = new TreeSet(); - Set packageNames = new TreeSet(); - try { - for (String pkg : packagesToScan) { - String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + - ClassUtils.convertClassNameToResourcePath(pkg) + RESOURCE_PATTERN; - Resource[] resources = this.resourcePatternResolver.getResources(pattern); - MetadataReaderFactory readerFactory = new CachingMetadataReaderFactory(this.resourcePatternResolver); - for (Resource resource : resources) { - if (resource.isReadable()) { - MetadataReader reader = readerFactory.getMetadataReader(resource); - String className = reader.getClassMetadata().getClassName(); - if (matchesEntityTypeFilter(reader, readerFactory)) { - entityClassNames.add(className); - } - else if (converterTypeFilter != null && converterTypeFilter.match(reader, readerFactory)) { - converterClassNames.add(className); - } - else if (className.endsWith(PACKAGE_INFO_SUFFIX)) { - packageNames.add(className.substring(0, className.length() - PACKAGE_INFO_SUFFIX.length())); - } - } - } - } - } - catch (IOException ex) { - throw new MappingException("Failed to scan classpath for unlisted classes", ex); - } - try { - ClassLoader cl = this.resourcePatternResolver.getClassLoader(); - for (String className : entityClassNames) { - addAnnotatedClass(cl.loadClass(className)); - } - for (String className : converterClassNames) { - ConverterRegistrationDelegate.registerConverter(this, cl.loadClass(className)); - } - for (String packageName : packageNames) { - addPackage(packageName); - } - } - catch (ClassNotFoundException ex) { - throw new MappingException("Failed to load annotated classes from classpath", ex); - } - return this; - } - - /** - * Check whether any of the configured entity type filters matches - * the current class descriptor contained in the metadata reader. - */ - private boolean matchesEntityTypeFilter(MetadataReader reader, MetadataReaderFactory readerFactory) throws IOException { - if (this.entityTypeFilters != null) { - for (TypeFilter filter : this.entityTypeFilters) { - if (filter.match(reader, readerFactory)) { - return true; - } - } - } - return false; - } - - - // Overridden methods from Hibernate's Configuration class - - @Override - public Settings buildSettings(Properties props, ServiceRegistry serviceRegistry) throws HibernateException { - Settings settings = super.buildSettings(props, serviceRegistry); - if (this.cacheRegionFactory != null) { - try { - Method setRegionFactory = Settings.class.getDeclaredMethod("setRegionFactory", RegionFactory.class); - setRegionFactory.setAccessible(true); - setRegionFactory.invoke(settings, this.cacheRegionFactory); - } - catch (Exception ex) { - throw new IllegalStateException("Failed to invoke Hibernate's setRegionFactory method", ex); - } - } - return settings; - } - - /** - * Build the {@code SessionFactory}. - */ - @Override - @SuppressWarnings("deprecation") - public SessionFactory buildSessionFactory() throws HibernateException { - ClassLoader appClassLoader = (ClassLoader) getProperties().get(AvailableSettings.APP_CLASSLOADER); - Thread currentThread = Thread.currentThread(); - ClassLoader threadContextClassLoader = currentThread.getContextClassLoader(); - boolean overrideClassLoader = - (appClassLoader != null && !appClassLoader.equals(threadContextClassLoader)); - if (overrideClassLoader) { - currentThread.setContextClassLoader(appClassLoader); - } - try { - return super.buildSessionFactory(); - } - finally { - if (overrideClassLoader) { - currentThread.setContextClassLoader(threadContextClassLoader); - } - } - } - - - /** - * Inner class to avoid hard dependency on JPA 2.1 / Hibernate 4.3. - */ - private static class ConverterRegistrationDelegate { - - @SuppressWarnings("unchecked") - public static void registerConverter(Configuration config, Class converterClass) { - config.addAttributeConverter((Class>) converterClass); - } - } - -} diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/SessionFactoryUtils.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/SessionFactoryUtils.java deleted file mode 100644 index 571e900023..0000000000 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/SessionFactoryUtils.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate4; - -import java.lang.reflect.Method; -import javax.sql.DataSource; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.hibernate.HibernateException; -import org.hibernate.JDBCException; -import org.hibernate.NonUniqueObjectException; -import org.hibernate.NonUniqueResultException; -import org.hibernate.ObjectDeletedException; -import org.hibernate.PersistentObjectException; -import org.hibernate.PessimisticLockException; -import org.hibernate.PropertyValueException; -import org.hibernate.QueryException; -import org.hibernate.QueryTimeoutException; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.StaleObjectStateException; -import org.hibernate.StaleStateException; -import org.hibernate.TransientObjectException; -import org.hibernate.UnresolvableObjectException; -import org.hibernate.WrongClassException; -import org.hibernate.dialect.lock.OptimisticEntityLockException; -import org.hibernate.dialect.lock.PessimisticEntityLockException; -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.exception.ConstraintViolationException; -import org.hibernate.exception.DataException; -import org.hibernate.exception.JDBCConnectionException; -import org.hibernate.exception.LockAcquisitionException; -import org.hibernate.exception.SQLGrammarException; -import org.hibernate.service.spi.Wrapped; - -import org.springframework.dao.CannotAcquireLockException; -import org.springframework.dao.DataAccessException; -import org.springframework.dao.DataAccessResourceFailureException; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.dao.DuplicateKeyException; -import org.springframework.dao.IncorrectResultSizeDataAccessException; -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.dao.InvalidDataAccessResourceUsageException; -import org.springframework.dao.PessimisticLockingFailureException; -import org.springframework.jdbc.datasource.DataSourceUtils; -import org.springframework.util.ClassUtils; -import org.springframework.util.ReflectionUtils; - -/** - * Helper class featuring methods for Hibernate Session handling. - * Also provides support for exception translation. - * - *

Used internally by {@link HibernateTransactionManager}. - * Can also be used directly in application code. - * - * @author Juergen Hoeller - * @since 3.1 - * @see HibernateExceptionTranslator - * @see HibernateTransactionManager - */ -public abstract class SessionFactoryUtils { - - /** - * Order value for TransactionSynchronization objects that clean up Hibernate Sessions. - * Returns {@code DataSourceUtils.CONNECTION_SYNCHRONIZATION_ORDER - 100} - * to execute Session cleanup before JDBC Connection cleanup, if any. - * @see org.springframework.jdbc.datasource.DataSourceUtils#CONNECTION_SYNCHRONIZATION_ORDER - */ - public static final int SESSION_SYNCHRONIZATION_ORDER = - DataSourceUtils.CONNECTION_SYNCHRONIZATION_ORDER - 100; - - static final Log logger = LogFactory.getLog(SessionFactoryUtils.class); - - /** - * Bridging between the different ConnectionProvider package location in 4.0-4.2 vs 4.3. - */ - private static final Method getConnectionProviderMethod = - ClassUtils.getMethodIfAvailable(SessionFactoryImplementor.class, "getConnectionProvider"); - - - /** - * Determine the DataSource of the given SessionFactory. - * @param sessionFactory the SessionFactory to check - * @return the DataSource, or {@code null} if none found - * @see org.hibernate.engine.spi.SessionFactoryImplementor#getConnectionProvider - */ - public static DataSource getDataSource(SessionFactory sessionFactory) { - if (getConnectionProviderMethod != null && sessionFactory instanceof SessionFactoryImplementor) { - Wrapped cp = (Wrapped) ReflectionUtils.invokeMethod(getConnectionProviderMethod, sessionFactory); - if (cp != null) { - return cp.unwrap(DataSource.class); - } - } - return null; - } - - /** - * Perform actual closing of the Hibernate Session, - * catching and logging any cleanup exceptions thrown. - * @param session the Hibernate Session to close (may be {@code null}) - * @see org.hibernate.Session#close() - */ - public static void closeSession(Session session) { - if (session != null) { - try { - session.close(); - } - catch (HibernateException ex) { - logger.debug("Could not close Hibernate Session", ex); - } - catch (Throwable ex) { - logger.debug("Unexpected exception on closing Hibernate Session", ex); - } - } - } - - /** - * Convert the given HibernateException to an appropriate exception - * from the {@code org.springframework.dao} hierarchy. - * @param ex HibernateException that occurred - * @return the corresponding DataAccessException instance - * @see HibernateExceptionTranslator#convertHibernateAccessException - * @see HibernateTransactionManager#convertHibernateAccessException - */ - public static DataAccessException convertHibernateAccessException(HibernateException ex) { - if (ex instanceof JDBCConnectionException) { - return new DataAccessResourceFailureException(ex.getMessage(), ex); - } - if (ex instanceof SQLGrammarException) { - SQLGrammarException jdbcEx = (SQLGrammarException) ex; - return new InvalidDataAccessResourceUsageException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]", ex); - } - if (ex instanceof QueryTimeoutException) { - QueryTimeoutException jdbcEx = (QueryTimeoutException) ex; - return new org.springframework.dao.QueryTimeoutException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]", ex); - } - if (ex instanceof LockAcquisitionException) { - LockAcquisitionException jdbcEx = (LockAcquisitionException) ex; - return new CannotAcquireLockException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]", ex); - } - if (ex instanceof PessimisticLockException) { - PessimisticLockException jdbcEx = (PessimisticLockException) ex; - return new PessimisticLockingFailureException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]", ex); - } - if (ex instanceof ConstraintViolationException) { - ConstraintViolationException jdbcEx = (ConstraintViolationException) ex; - return new DataIntegrityViolationException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + - "]; constraint [" + jdbcEx.getConstraintName() + "]", ex); - } - if (ex instanceof DataException) { - DataException jdbcEx = (DataException) ex; - return new DataIntegrityViolationException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]", ex); - } - if (ex instanceof JDBCException) { - return new HibernateJdbcException((JDBCException) ex); - } - // end of JDBCException (subclass) handling - - if (ex instanceof QueryException) { - return new HibernateQueryException((QueryException) ex); - } - if (ex instanceof NonUniqueResultException) { - return new IncorrectResultSizeDataAccessException(ex.getMessage(), 1, ex); - } - if (ex instanceof NonUniqueObjectException) { - return new DuplicateKeyException(ex.getMessage(), ex); - } - if (ex instanceof PropertyValueException) { - return new DataIntegrityViolationException(ex.getMessage(), ex); - } - if (ex instanceof PersistentObjectException) { - return new InvalidDataAccessApiUsageException(ex.getMessage(), ex); - } - if (ex instanceof TransientObjectException) { - return new InvalidDataAccessApiUsageException(ex.getMessage(), ex); - } - if (ex instanceof ObjectDeletedException) { - return new InvalidDataAccessApiUsageException(ex.getMessage(), ex); - } - if (ex instanceof UnresolvableObjectException) { - return new HibernateObjectRetrievalFailureException((UnresolvableObjectException) ex); - } - if (ex instanceof WrongClassException) { - return new HibernateObjectRetrievalFailureException((WrongClassException) ex); - } - if (ex instanceof StaleObjectStateException) { - return new HibernateOptimisticLockingFailureException((StaleObjectStateException) ex); - } - if (ex instanceof StaleStateException) { - return new HibernateOptimisticLockingFailureException((StaleStateException) ex); - } - if (ex instanceof OptimisticEntityLockException) { - return new HibernateOptimisticLockingFailureException((OptimisticEntityLockException) ex); - } - if (ex instanceof PessimisticEntityLockException) { - if (ex.getCause() instanceof LockAcquisitionException) { - return new CannotAcquireLockException(ex.getMessage(), ex.getCause()); - } - return new PessimisticLockingFailureException(ex.getMessage(), ex); - } - - // fallback - return new HibernateSystemException(ex); - } - -} diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/SessionHolder.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/SessionHolder.java deleted file mode 100644 index 67bb9c6339..0000000000 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/SessionHolder.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate4; - -import org.hibernate.FlushMode; -import org.hibernate.Session; -import org.hibernate.Transaction; - -import org.springframework.transaction.support.ResourceHolderSupport; -import org.springframework.util.Assert; - -/** - * Session holder, wrapping a Hibernate Session and a Hibernate Transaction. - * HibernateTransactionManager binds instances of this class to the thread, - * for a given SessionFactory. - * - *

Note: This is an SPI class, not intended to be used by applications. - * - * @author Juergen Hoeller - * @since 3.1 - * @see HibernateTransactionManager - * @see SessionFactoryUtils - */ -public class SessionHolder extends ResourceHolderSupport { - - private Session session; - - private Transaction transaction; - - private FlushMode previousFlushMode; - - - public SessionHolder(Session session) { - Assert.notNull(session, "Session must not be null"); - this.session = session; - } - - public Session getSession() { - return this.session; - } - - public void setTransaction(Transaction transaction) { - this.transaction = transaction; - } - - public Transaction getTransaction() { - return this.transaction; - } - - public void setPreviousFlushMode(FlushMode previousFlushMode) { - this.previousFlushMode = previousFlushMode; - } - - public FlushMode getPreviousFlushMode() { - return this.previousFlushMode; - } - - - @Override - public void clear() { - super.clear(); - this.transaction = null; - this.previousFlushMode = null; - } - -} diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/SpringFlushSynchronization.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/SpringFlushSynchronization.java deleted file mode 100644 index 07d8d6981e..0000000000 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/SpringFlushSynchronization.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate4; - -import org.hibernate.HibernateException; -import org.hibernate.Session; - -import org.springframework.transaction.support.TransactionSynchronizationAdapter; - -/** - * Simple synchronization adapter that propagates a {@code flush()} call - * to the underlying Hibernate Session. Used in combination with JTA. - * - * @author Juergen Hoeller - * @since 3.1 - */ -public class SpringFlushSynchronization extends TransactionSynchronizationAdapter { - - private final Session session; - - - public SpringFlushSynchronization(Session session) { - this.session = session; - } - - - @Override - public void flush() { - try { - SessionFactoryUtils.logger.debug("Flushing Hibernate Session on explicit request"); - this.session.flush(); - } - catch (HibernateException ex) { - throw SessionFactoryUtils.convertHibernateAccessException(ex); - } - } - - - @Override - public boolean equals(Object obj) { - return (obj instanceof SpringFlushSynchronization && - this.session == ((SpringFlushSynchronization) obj).session); - } - - @Override - public int hashCode() { - return this.session.hashCode(); - } - -} diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/SpringJtaSessionContext.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/SpringJtaSessionContext.java deleted file mode 100644 index 2b2ad05893..0000000000 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/SpringJtaSessionContext.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate4; - -import org.hibernate.FlushMode; -import org.hibernate.Session; -import org.hibernate.context.internal.JTASessionContext; -import org.hibernate.engine.spi.SessionFactoryImplementor; - -import org.springframework.transaction.support.TransactionSynchronizationManager; - -/** - * Spring-specific subclass of Hibernate's JTASessionContext, - * setting {@code FlushMode.MANUAL} for read-only transactions. - * - * @author Juergen Hoeller - * @since 3.1 - */ -@SuppressWarnings("serial") -public class SpringJtaSessionContext extends JTASessionContext { - - public SpringJtaSessionContext(SessionFactoryImplementor factory) { - super(factory); - } - - @Override - protected Session buildOrObtainSession() { - Session session = super.buildOrObtainSession(); - if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) { - session.setFlushMode(FlushMode.MANUAL); - } - return session; - } - -} diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/SpringSessionContext.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/SpringSessionContext.java deleted file mode 100644 index 99d6f69261..0000000000 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/SpringSessionContext.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate4; - -import java.lang.reflect.Method; -import javax.transaction.Status; -import javax.transaction.SystemException; -import javax.transaction.TransactionManager; - -import org.apache.commons.logging.LogFactory; -import org.hibernate.FlushMode; -import org.hibernate.HibernateException; -import org.hibernate.Session; -import org.hibernate.context.spi.CurrentSessionContext; -import org.hibernate.engine.spi.SessionFactoryImplementor; - -import org.springframework.transaction.support.TransactionSynchronizationManager; -import org.springframework.util.ReflectionUtils; - -/** - * Implementation of Hibernate 3.1's CurrentSessionContext interface - * that delegates to Spring's SessionFactoryUtils for providing a - * Spring-managed current Session. - * - *

This CurrentSessionContext implementation can also be specified in custom - * SessionFactory setup through the "hibernate.current_session_context_class" - * property, with the fully qualified name of this class as value. - * - * @author Juergen Hoeller - * @since 3.1 - */ -@SuppressWarnings("serial") -public class SpringSessionContext implements CurrentSessionContext { - - private final SessionFactoryImplementor sessionFactory; - - private TransactionManager transactionManager; - - private CurrentSessionContext jtaSessionContext; - - - /** - * Create a new SpringSessionContext for the given Hibernate SessionFactory. - * @param sessionFactory the SessionFactory to provide current Sessions for - */ - public SpringSessionContext(SessionFactoryImplementor sessionFactory) { - this.sessionFactory = sessionFactory; - try { - Object jtaPlatform = sessionFactory.getServiceRegistry().getService(ConfigurableJtaPlatform.jtaPlatformClass); - Method rtmMethod = ConfigurableJtaPlatform.jtaPlatformClass.getMethod("retrieveTransactionManager"); - this.transactionManager = (TransactionManager) ReflectionUtils.invokeMethod(rtmMethod, jtaPlatform); - if (this.transactionManager != null) { - this.jtaSessionContext = new SpringJtaSessionContext(sessionFactory); - } - } - catch (Exception ex) { - LogFactory.getLog(SpringSessionContext.class).warn( - "Could not introspect Hibernate JtaPlatform for SpringJtaSessionContext", ex); - } - } - - - /** - * Retrieve the Spring-managed Session for the current thread, if any. - */ - @Override - public Session currentSession() throws HibernateException { - Object value = TransactionSynchronizationManager.getResource(this.sessionFactory); - if (value instanceof Session) { - return (Session) value; - } - else if (value instanceof SessionHolder) { - SessionHolder sessionHolder = (SessionHolder) value; - Session session = sessionHolder.getSession(); - if (!sessionHolder.isSynchronizedWithTransaction() && - TransactionSynchronizationManager.isSynchronizationActive()) { - TransactionSynchronizationManager.registerSynchronization( - new SpringSessionSynchronization(sessionHolder, this.sessionFactory, false)); - sessionHolder.setSynchronizedWithTransaction(true); - // Switch to FlushMode.AUTO, as we have to assume a thread-bound Session - // with FlushMode.MANUAL, which needs to allow flushing within the transaction. - FlushMode flushMode = session.getFlushMode(); - if (flushMode.equals(FlushMode.MANUAL) && - !TransactionSynchronizationManager.isCurrentTransactionReadOnly()) { - session.setFlushMode(FlushMode.AUTO); - sessionHolder.setPreviousFlushMode(flushMode); - } - } - return session; - } - - if (this.transactionManager != null) { - try { - if (this.transactionManager.getStatus() == Status.STATUS_ACTIVE) { - Session session = this.jtaSessionContext.currentSession(); - if (TransactionSynchronizationManager.isSynchronizationActive()) { - TransactionSynchronizationManager.registerSynchronization(new SpringFlushSynchronization(session)); - } - return session; - } - } - catch (SystemException ex) { - throw new HibernateException("JTA TransactionManager found but status check failed", ex); - } - } - - if (TransactionSynchronizationManager.isSynchronizationActive()) { - Session session = this.sessionFactory.openSession(); - if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) { - session.setFlushMode(FlushMode.MANUAL); - } - SessionHolder sessionHolder = new SessionHolder(session); - TransactionSynchronizationManager.registerSynchronization( - new SpringSessionSynchronization(sessionHolder, this.sessionFactory, true)); - TransactionSynchronizationManager.bindResource(this.sessionFactory, sessionHolder); - sessionHolder.setSynchronizedWithTransaction(true); - return session; - } - else { - throw new HibernateException("Could not obtain transaction-synchronized Session for current thread"); - } - } - -} diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/SpringSessionSynchronization.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/SpringSessionSynchronization.java deleted file mode 100644 index 6eee684dfb..0000000000 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/SpringSessionSynchronization.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2002-2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate4; - -import org.hibernate.FlushMode; -import org.hibernate.HibernateException; -import org.hibernate.Session; -import org.hibernate.SessionFactory; - -import org.springframework.core.Ordered; -import org.springframework.dao.DataAccessException; -import org.springframework.transaction.support.TransactionSynchronization; -import org.springframework.transaction.support.TransactionSynchronizationManager; - -/** - * Callback for resource cleanup at the end of a Spring-managed transaction - * for a pre-bound Hibernate Session. - * - * @author Juergen Hoeller - * @since 3.1 - */ -public class SpringSessionSynchronization implements TransactionSynchronization, Ordered { - - private final SessionHolder sessionHolder; - - private final SessionFactory sessionFactory; - - private final boolean newSession; - - private boolean holderActive = true; - - - public SpringSessionSynchronization(SessionHolder sessionHolder, SessionFactory sessionFactory) { - this(sessionHolder, sessionFactory, false); - } - - public SpringSessionSynchronization(SessionHolder sessionHolder, SessionFactory sessionFactory, boolean newSession) { - this.sessionHolder = sessionHolder; - this.sessionFactory = sessionFactory; - this.newSession = newSession; - } - - - private Session getCurrentSession() { - return this.sessionHolder.getSession(); - } - - - @Override - public int getOrder() { - return SessionFactoryUtils.SESSION_SYNCHRONIZATION_ORDER; - } - - @Override - public void suspend() { - if (this.holderActive) { - TransactionSynchronizationManager.unbindResource(this.sessionFactory); - // Eagerly disconnect the Session here, to make release mode "on_close" work on JBoss. - getCurrentSession().disconnect(); - } - } - - @Override - public void resume() { - if (this.holderActive) { - TransactionSynchronizationManager.bindResource(this.sessionFactory, this.sessionHolder); - } - } - - @Override - public void flush() { - try { - SessionFactoryUtils.logger.debug("Flushing Hibernate Session on explicit request"); - getCurrentSession().flush(); - } - catch (HibernateException ex) { - throw SessionFactoryUtils.convertHibernateAccessException(ex); - } - } - - @Override - public void beforeCommit(boolean readOnly) throws DataAccessException { - if (!readOnly) { - Session session = getCurrentSession(); - // Read-write transaction -> flush the Hibernate Session. - // Further check: only flush when not FlushMode.MANUAL. - if (!session.getFlushMode().equals(FlushMode.MANUAL)) { - try { - SessionFactoryUtils.logger.debug("Flushing Hibernate Session on transaction synchronization"); - session.flush(); - } - catch (HibernateException ex) { - throw SessionFactoryUtils.convertHibernateAccessException(ex); - } - } - } - } - - @Override - public void beforeCompletion() { - try { - Session session = this.sessionHolder.getSession(); - if (this.sessionHolder.getPreviousFlushMode() != null) { - // In case of pre-bound Session, restore previous flush mode. - session.setFlushMode(this.sessionHolder.getPreviousFlushMode()); - } - // Eagerly disconnect the Session here, to make release mode "on_close" work nicely. - session.disconnect(); - } - finally { - // Unbind at this point if it's a new Session... - if (this.newSession) { - TransactionSynchronizationManager.unbindResource(this.sessionFactory); - this.holderActive = false; - } - } - } - - @Override - public void afterCommit() { - } - - @Override - public void afterCompletion(int status) { - try { - if (status != STATUS_COMMITTED) { - // Clear all pending inserts/updates/deletes in the Session. - // Necessary for pre-bound Sessions, to avoid inconsistent state. - this.sessionHolder.getSession().clear(); - } - } - finally { - this.sessionHolder.setSynchronizedWithTransaction(false); - // Call close() at this point if it's a new Session... - if (this.newSession) { - SessionFactoryUtils.closeSession(this.sessionHolder.getSession()); - } - } - } - -} diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/package-info.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/package-info.java deleted file mode 100644 index 7b2fc61903..0000000000 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/package-info.java +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Package providing integration of - * Hibernate 4.x - * with Spring concepts. - * - *

Contains an implementation of Spring's transaction SPI for local Hibernate transactions. - * This package is intentionally rather minimal, with no template classes or the like, - * in order to follow Hibernate recommendations as closely as possible. We recommend - * using Hibernate's native sessionFactory.getCurrentSession() style. - * - *

This package supports Hibernate 4.x only. - * See the {@code org.springframework.orm.hibernate3} package for Hibernate 3.x support. - * Note: Do not use HibernateTemplate or other classes from the hibernate3 package - * with Hibernate 4; this will lead to class definition exceptions at runtime. - */ -package org.springframework.orm.hibernate4; diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/AsyncRequestInterceptor.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/AsyncRequestInterceptor.java deleted file mode 100644 index 2878605d42..0000000000 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/AsyncRequestInterceptor.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2002-2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate4.support; - -import java.util.concurrent.Callable; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.hibernate.SessionFactory; - -import org.springframework.orm.hibernate4.SessionFactoryUtils; -import org.springframework.orm.hibernate4.SessionHolder; -import org.springframework.transaction.support.TransactionSynchronizationManager; -import org.springframework.web.context.request.NativeWebRequest; -import org.springframework.web.context.request.async.CallableProcessingInterceptorAdapter; -import org.springframework.web.context.request.async.DeferredResult; -import org.springframework.web.context.request.async.DeferredResultProcessingInterceptor; - -/** - * An interceptor with asynchronous web requests used in OpenSessionInViewFilter and - * OpenSessionInViewInterceptor. - * - * Ensures the following: - * 1) The session is bound/unbound when "callable processing" is started - * 2) The session is closed if an async request times out - * - * @author Rossen Stoyanchev - * @since 3.2.5 - */ -class AsyncRequestInterceptor extends CallableProcessingInterceptorAdapter implements DeferredResultProcessingInterceptor { - - private static final Log logger = LogFactory.getLog(AsyncRequestInterceptor.class); - - private final SessionFactory sessionFactory; - - private final SessionHolder sessionHolder; - - private volatile boolean timeoutInProgress; - - - public AsyncRequestInterceptor(SessionFactory sessionFactory, SessionHolder sessionHolder) { - this.sessionFactory = sessionFactory; - this.sessionHolder = sessionHolder; - } - - - @Override - public void preProcess(NativeWebRequest request, Callable task) { - bindSession(); - } - - public void bindSession() { - this.timeoutInProgress = false; - TransactionSynchronizationManager.bindResource(this.sessionFactory, this.sessionHolder); - } - - @Override - public void postProcess(NativeWebRequest request, Callable task, Object concurrentResult) { - TransactionSynchronizationManager.unbindResource(this.sessionFactory); - } - - @Override - public Object handleTimeout(NativeWebRequest request, Callable task) { - this.timeoutInProgress = true; - return RESULT_NONE; // give other interceptors a chance to handle the timeout - } - - @Override - public void afterCompletion(NativeWebRequest request, Callable task) throws Exception { - closeAfterTimeout(); - } - - private void closeAfterTimeout() { - if (this.timeoutInProgress) { - logger.debug("Closing Hibernate Session after async request timeout"); - SessionFactoryUtils.closeSession(this.sessionHolder.getSession()); - } - } - - - // Implementation of DeferredResultProcessingInterceptor methods - - @Override - public void beforeConcurrentHandling(NativeWebRequest request, DeferredResult deferredResult) { - } - - @Override - public void preProcess(NativeWebRequest request, DeferredResult deferredResult) { - } - - @Override - public void postProcess(NativeWebRequest request, DeferredResult deferredResult, Object result) { - } - - @Override - public boolean handleTimeout(NativeWebRequest request, DeferredResult deferredResult) { - this.timeoutInProgress = true; - return true; // give other interceptors a chance to handle the timeout - } - - @Override - public void afterCompletion(NativeWebRequest request, DeferredResult deferredResult) { - closeAfterTimeout(); - } - -} diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/HibernateDaoSupport.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/HibernateDaoSupport.java deleted file mode 100644 index 4d1083feba..0000000000 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/HibernateDaoSupport.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate4.support; - -import org.hibernate.Session; -import org.hibernate.SessionFactory; - -import org.springframework.dao.DataAccessResourceFailureException; -import org.springframework.dao.support.DaoSupport; -import org.springframework.orm.hibernate4.HibernateTemplate; - -/** - * Convenient super class for Hibernate-based data access objects. - * - *

Requires a {@link org.hibernate.SessionFactory} to be set, providing a - * {@link org.springframework.orm.hibernate4.HibernateTemplate} based on it to - * subclasses through the {@link #getHibernateTemplate()} method. - * Can alternatively be initialized directly with a HibernateTemplate, - * in order to reuse the latter's settings such as the SessionFactory, - * exception translator, flush mode, etc. - * - *

This class will create its own HibernateTemplate instance if a SessionFactory - * is passed in. The "allowCreate" flag on that HibernateTemplate will be "true" - * by default. A custom HibernateTemplate instance can be used through overriding - * {@link #createHibernateTemplate}. - * - *

NOTE: Hibernate access code can also be coded in plain Hibernate style. - * Hence, for newly started projects, consider adopting the standard Hibernate - * style of coding data access objects instead, based on - * {@link org.hibernate.SessionFactory#getCurrentSession()}. - * This HibernateTemplate primarily exists as a migration helper for Hibernate 3 - * based data access code, to benefit from bug fixes in Hibernate 4.x. - * - * @author Juergen Hoeller - * @since 4.0.1 - * @see #setSessionFactory - * @see #getHibernateTemplate - * @see org.springframework.orm.hibernate4.HibernateTemplate - */ -public abstract class HibernateDaoSupport extends DaoSupport { - - private HibernateTemplate hibernateTemplate; - - - /** - * Set the Hibernate SessionFactory to be used by this DAO. - * Will automatically create a HibernateTemplate for the given SessionFactory. - * @see #createHibernateTemplate - * @see #setHibernateTemplate - */ - public final void setSessionFactory(SessionFactory sessionFactory) { - if (this.hibernateTemplate == null || sessionFactory != this.hibernateTemplate.getSessionFactory()) { - this.hibernateTemplate = createHibernateTemplate(sessionFactory); - } - } - - /** - * Create a HibernateTemplate for the given SessionFactory. - * Only invoked if populating the DAO with a SessionFactory reference! - *

Can be overridden in subclasses to provide a HibernateTemplate instance - * with different configuration, or a custom HibernateTemplate subclass. - * @param sessionFactory the Hibernate SessionFactory to create a HibernateTemplate for - * @return the new HibernateTemplate instance - * @see #setSessionFactory - */ - protected HibernateTemplate createHibernateTemplate(SessionFactory sessionFactory) { - return new HibernateTemplate(sessionFactory); - } - - /** - * Return the Hibernate SessionFactory used by this DAO. - */ - public final SessionFactory getSessionFactory() { - return (this.hibernateTemplate != null ? this.hibernateTemplate.getSessionFactory() : null); - } - - /** - * Set the HibernateTemplate for this DAO explicitly, - * as an alternative to specifying a SessionFactory. - * @see #setSessionFactory - */ - public final void setHibernateTemplate(HibernateTemplate hibernateTemplate) { - this.hibernateTemplate = hibernateTemplate; - } - - /** - * Return the HibernateTemplate for this DAO, - * pre-initialized with the SessionFactory or set explicitly. - *

Note: The returned HibernateTemplate is a shared instance. - * You may introspect its configuration, but not modify the configuration - * (other than from within an {@link #initDao} implementation). - * Consider creating a custom HibernateTemplate instance via - * {@code new HibernateTemplate(getSessionFactory())}, in which case - * you're allowed to customize the settings on the resulting instance. - */ - public final HibernateTemplate getHibernateTemplate() { - return this.hibernateTemplate; - } - - @Override - protected final void checkDaoConfig() { - if (this.hibernateTemplate == null) { - throw new IllegalArgumentException("'sessionFactory' or 'hibernateTemplate' is required"); - } - } - - - /** - * Conveniently obtain the current Hibernate Session. - * @return the Hibernate Session - * @throws DataAccessResourceFailureException if the Session couldn't be created - * @see org.hibernate.SessionFactory#getCurrentSession() - */ - protected final Session currentSession() throws DataAccessResourceFailureException { - return getSessionFactory().getCurrentSession(); - } - -} diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/OpenSessionInViewFilter.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/OpenSessionInViewFilter.java deleted file mode 100644 index 88f0573aeb..0000000000 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/OpenSessionInViewFilter.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright 2002-2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate4.support; - -import java.io.IOException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.hibernate.FlushMode; -import org.hibernate.HibernateException; -import org.hibernate.Session; -import org.hibernate.SessionFactory; - -import org.springframework.dao.DataAccessResourceFailureException; -import org.springframework.orm.hibernate4.SessionFactoryUtils; -import org.springframework.orm.hibernate4.SessionHolder; -import org.springframework.transaction.support.TransactionSynchronizationManager; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.context.request.async.WebAsyncManager; -import org.springframework.web.context.request.async.WebAsyncUtils; -import org.springframework.web.context.support.WebApplicationContextUtils; -import org.springframework.web.filter.OncePerRequestFilter; - -/** - * Servlet Filter that binds a Hibernate Session to the thread for the entire - * processing of the request. Intended for the "Open Session in View" pattern, - * i.e. to allow for lazy loading in web views despite the original transactions - * already being completed. - * - *

This filter makes Hibernate Sessions available via the current thread, which - * will be autodetected by transaction managers. It is suitable for service layer - * transactions via {@link org.springframework.orm.hibernate4.HibernateTransactionManager} - * as well as for non-transactional execution (if configured appropriately). - * - *

NOTE: This filter will by default not flush the Hibernate Session, - * with the flush mode set to {@code FlushMode.NEVER}. It assumes to be used - * in combination with service layer transactions that care for the flushing: The - * active transaction manager will temporarily change the flush mode to - * {@code FlushMode.AUTO} during a read-write transaction, with the flush - * mode reset to {@code FlushMode.NEVER} at the end of each transaction. - * - *

WARNING: Applying this filter to existing logic can cause issues that - * have not appeared before, through the use of a single Hibernate Session for the - * processing of an entire request. In particular, the reassociation of persistent - * objects with a Hibernate Session has to occur at the very beginning of request - * processing, to avoid clashes with already loaded instances of the same objects. - * - *

Looks up the SessionFactory in Spring's root web application context. - * Supports a "sessionFactoryBeanName" filter init-param in {@code web.xml}; - * the default bean name is "sessionFactory". - * - * @author Juergen Hoeller - * @since 3.1 - * @see #lookupSessionFactory - * @see OpenSessionInViewInterceptor - * @see OpenSessionInterceptor - * @see org.springframework.orm.hibernate4.HibernateTransactionManager - * @see org.springframework.transaction.support.TransactionSynchronizationManager - * @see org.hibernate.SessionFactory#getCurrentSession() - */ -public class OpenSessionInViewFilter extends OncePerRequestFilter { - - public static final String DEFAULT_SESSION_FACTORY_BEAN_NAME = "sessionFactory"; - - private String sessionFactoryBeanName = DEFAULT_SESSION_FACTORY_BEAN_NAME; - - - /** - * Set the bean name of the SessionFactory to fetch from Spring's - * root application context. Default is "sessionFactory". - * @see #DEFAULT_SESSION_FACTORY_BEAN_NAME - */ - public void setSessionFactoryBeanName(String sessionFactoryBeanName) { - this.sessionFactoryBeanName = sessionFactoryBeanName; - } - - /** - * Return the bean name of the SessionFactory to fetch from Spring's - * root application context. - */ - protected String getSessionFactoryBeanName() { - return this.sessionFactoryBeanName; - } - - - /** - * Returns "false" so that the filter may re-bind the opened Hibernate - * {@code Session} to each asynchronously dispatched thread and postpone - * closing it until the very last asynchronous dispatch. - */ - @Override - protected boolean shouldNotFilterAsyncDispatch() { - return false; - } - - /** - * Returns "false" so that the filter may provide a Hibernate - * {@code Session} to each error dispatches. - */ - @Override - protected boolean shouldNotFilterErrorDispatch() { - return false; - } - - @Override - protected void doFilterInternal( - HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) - throws ServletException, IOException { - - SessionFactory sessionFactory = lookupSessionFactory(request); - boolean participate = false; - - WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); - String key = getAlreadyFilteredAttributeName(); - - if (TransactionSynchronizationManager.hasResource(sessionFactory)) { - // Do not modify the Session: just set the participate flag. - participate = true; - } - else { - boolean isFirstRequest = !isAsyncDispatch(request); - if (isFirstRequest || !applySessionBindingInterceptor(asyncManager, key)) { - logger.debug("Opening Hibernate Session in OpenSessionInViewFilter"); - Session session = openSession(sessionFactory); - SessionHolder sessionHolder = new SessionHolder(session); - TransactionSynchronizationManager.bindResource(sessionFactory, sessionHolder); - - AsyncRequestInterceptor interceptor = new AsyncRequestInterceptor(sessionFactory, sessionHolder); - asyncManager.registerCallableInterceptor(key, interceptor); - asyncManager.registerDeferredResultInterceptor(key, interceptor); - } - } - - try { - filterChain.doFilter(request, response); - } - - finally { - if (!participate) { - SessionHolder sessionHolder = - (SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory); - if (!isAsyncStarted(request)) { - logger.debug("Closing Hibernate Session in OpenSessionInViewFilter"); - SessionFactoryUtils.closeSession(sessionHolder.getSession()); - } - } - } - } - - /** - * Look up the SessionFactory that this filter should use, - * taking the current HTTP request as argument. - *

The default implementation delegates to the {@link #lookupSessionFactory()} - * variant without arguments. - * @param request the current request - * @return the SessionFactory to use - */ - protected SessionFactory lookupSessionFactory(HttpServletRequest request) { - return lookupSessionFactory(); - } - - /** - * Look up the SessionFactory that this filter should use. - *

The default implementation looks for a bean with the specified name - * in Spring's root application context. - * @return the SessionFactory to use - * @see #getSessionFactoryBeanName - */ - protected SessionFactory lookupSessionFactory() { - if (logger.isDebugEnabled()) { - logger.debug("Using SessionFactory '" + getSessionFactoryBeanName() + "' for OpenSessionInViewFilter"); - } - WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()); - return wac.getBean(getSessionFactoryBeanName(), SessionFactory.class); - } - - /** - * Open a Session for the SessionFactory that this filter uses. - *

The default implementation delegates to the {@link SessionFactory#openSession} - * method and sets the {@link Session}'s flush mode to "MANUAL". - * @param sessionFactory the SessionFactory that this filter uses - * @return the Session to use - * @throws DataAccessResourceFailureException if the Session could not be created - * @see org.hibernate.FlushMode#MANUAL - */ - protected Session openSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException { - try { - Session session = sessionFactory.openSession(); - session.setFlushMode(FlushMode.MANUAL); - return session; - } - catch (HibernateException ex) { - throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex); - } - } - - private boolean applySessionBindingInterceptor(WebAsyncManager asyncManager, String key) { - if (asyncManager.getCallableInterceptor(key) == null) { - return false; - } - ((AsyncRequestInterceptor) asyncManager.getCallableInterceptor(key)).bindSession(); - return true; - } - -} diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/OpenSessionInViewInterceptor.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/OpenSessionInViewInterceptor.java deleted file mode 100644 index 39233b0acd..0000000000 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/OpenSessionInViewInterceptor.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate4.support; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.hibernate.FlushMode; -import org.hibernate.HibernateException; -import org.hibernate.Session; -import org.hibernate.SessionFactory; - -import org.springframework.dao.DataAccessException; -import org.springframework.dao.DataAccessResourceFailureException; -import org.springframework.orm.hibernate4.SessionFactoryUtils; -import org.springframework.orm.hibernate4.SessionHolder; -import org.springframework.transaction.support.TransactionSynchronizationManager; -import org.springframework.ui.ModelMap; -import org.springframework.web.context.request.AsyncWebRequestInterceptor; -import org.springframework.web.context.request.WebRequest; -import org.springframework.web.context.request.async.WebAsyncManager; -import org.springframework.web.context.request.async.WebAsyncUtils; - -/** - * Spring web request interceptor that binds a Hibernate {@code Session} to the - * thread for the entire processing of the request. - * - *

This class is a concrete expression of the "Open Session in View" pattern, which - * is a pattern that allows for the lazy loading of associations in web views despite - * the original transactions already being completed. - * - *

This interceptor makes Hibernate Sessions available via the current thread, - * which will be autodetected by transaction managers. It is suitable for service layer - * transactions via {@link org.springframework.orm.hibernate4.HibernateTransactionManager} - * as well as for non-transactional execution (if configured appropriately). - * - *

In contrast to {@link OpenSessionInViewFilter}, this interceptor is configured - * in a Spring application context and can thus take advantage of bean wiring. - * - *

WARNING: Applying this interceptor to existing logic can cause issues - * that have not appeared before, through the use of a single Hibernate - * {@code Session} for the processing of an entire request. In particular, the - * reassociation of persistent objects with a Hibernate {@code Session} has to - * occur at the very beginning of request processing, to avoid clashes with already - * loaded instances of the same objects. - * - * @author Juergen Hoeller - * @since 3.1 - * @see OpenSessionInViewFilter - * @see OpenSessionInterceptor - * @see org.springframework.orm.hibernate4.HibernateTransactionManager - * @see org.springframework.transaction.support.TransactionSynchronizationManager - * @see org.hibernate.SessionFactory#getCurrentSession() - */ -public class OpenSessionInViewInterceptor implements AsyncWebRequestInterceptor { - - /** - * Suffix that gets appended to the {@code SessionFactory} - * {@code toString()} representation for the "participate in existing - * session handling" request attribute. - * @see #getParticipateAttributeName - */ - public static final String PARTICIPATE_SUFFIX = ".PARTICIPATE"; - - protected final Log logger = LogFactory.getLog(getClass()); - - private SessionFactory sessionFactory; - - - /** - * Set the Hibernate SessionFactory that should be used to create Hibernate Sessions. - */ - public void setSessionFactory(SessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; - } - - /** - * Return the Hibernate SessionFactory that should be used to create Hibernate Sessions. - */ - public SessionFactory getSessionFactory() { - return this.sessionFactory; - } - - - /** - * Open a new Hibernate {@code Session} according and bind it to the thread via the - * {@link org.springframework.transaction.support.TransactionSynchronizationManager}. - */ - @Override - public void preHandle(WebRequest request) throws DataAccessException { - String participateAttributeName = getParticipateAttributeName(); - - WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); - if (asyncManager.hasConcurrentResult()) { - if (applySessionBindingInterceptor(asyncManager, participateAttributeName)) { - return; - } - } - - if (TransactionSynchronizationManager.hasResource(getSessionFactory())) { - // Do not modify the Session: just mark the request accordingly. - Integer count = (Integer) request.getAttribute(participateAttributeName, WebRequest.SCOPE_REQUEST); - int newCount = (count != null ? count + 1 : 1); - request.setAttribute(getParticipateAttributeName(), newCount, WebRequest.SCOPE_REQUEST); - } - else { - logger.debug("Opening Hibernate Session in OpenSessionInViewInterceptor"); - Session session = openSession(); - SessionHolder sessionHolder = new SessionHolder(session); - TransactionSynchronizationManager.bindResource(getSessionFactory(), sessionHolder); - - AsyncRequestInterceptor asyncRequestInterceptor = - new AsyncRequestInterceptor(getSessionFactory(), sessionHolder); - asyncManager.registerCallableInterceptor(participateAttributeName, asyncRequestInterceptor); - asyncManager.registerDeferredResultInterceptor(participateAttributeName, asyncRequestInterceptor); - } - } - - @Override - public void postHandle(WebRequest request, ModelMap model) { - } - - /** - * Unbind the Hibernate {@code Session} from the thread and close it). - * @see org.springframework.transaction.support.TransactionSynchronizationManager - */ - @Override - public void afterCompletion(WebRequest request, Exception ex) throws DataAccessException { - if (!decrementParticipateCount(request)) { - SessionHolder sessionHolder = - (SessionHolder) TransactionSynchronizationManager.unbindResource(getSessionFactory()); - logger.debug("Closing Hibernate Session in OpenSessionInViewInterceptor"); - SessionFactoryUtils.closeSession(sessionHolder.getSession()); - - } - } - - private boolean decrementParticipateCount(WebRequest request) { - String participateAttributeName = getParticipateAttributeName(); - Integer count = (Integer) request.getAttribute(participateAttributeName, WebRequest.SCOPE_REQUEST); - if (count == null) { - return false; - } - // Do not modify the Session: just clear the marker. - if (count > 1) { - request.setAttribute(participateAttributeName, count - 1, WebRequest.SCOPE_REQUEST); - } - else { - request.removeAttribute(participateAttributeName, WebRequest.SCOPE_REQUEST); - } - return true; - } - - @Override - public void afterConcurrentHandlingStarted(WebRequest request) { - if (!decrementParticipateCount(request)) { - TransactionSynchronizationManager.unbindResource(getSessionFactory()); - } - } - - /** - * Open a Session for the SessionFactory that this interceptor uses. - *

The default implementation delegates to the {@link SessionFactory#openSession} - * method and sets the {@link Session}'s flush mode to "MANUAL". - * @return the Session to use - * @throws DataAccessResourceFailureException if the Session could not be created - * @see org.hibernate.FlushMode#MANUAL - */ - protected Session openSession() throws DataAccessResourceFailureException { - try { - Session session = getSessionFactory().openSession(); - session.setFlushMode(FlushMode.MANUAL); - return session; - } - catch (HibernateException ex) { - throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex); - } - } - - /** - * Return the name of the request attribute that identifies that a request is - * already intercepted. - *

The default implementation takes the {@code toString()} representation - * of the {@code SessionFactory} instance and appends {@link #PARTICIPATE_SUFFIX}. - */ - protected String getParticipateAttributeName() { - return getSessionFactory().toString() + PARTICIPATE_SUFFIX; - } - - private boolean applySessionBindingInterceptor(WebAsyncManager asyncManager, String key) { - if (asyncManager.getCallableInterceptor(key) == null) { - return false; - } - ((AsyncRequestInterceptor) asyncManager.getCallableInterceptor(key)).bindSession(); - return true; - } - -} diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/OpenSessionInterceptor.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/OpenSessionInterceptor.java deleted file mode 100644 index 65be305494..0000000000 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/OpenSessionInterceptor.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate4.support; - -import org.aopalliance.intercept.MethodInterceptor; -import org.aopalliance.intercept.MethodInvocation; -import org.hibernate.FlushMode; -import org.hibernate.HibernateException; -import org.hibernate.Session; -import org.hibernate.SessionFactory; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.dao.DataAccessResourceFailureException; -import org.springframework.orm.hibernate4.SessionFactoryUtils; -import org.springframework.orm.hibernate4.SessionHolder; -import org.springframework.transaction.support.TransactionSynchronizationManager; - -/** - * Simple AOP Alliance {@link MethodInterceptor} implementation that binds a new - * Hibernate {@link Session} for each method invocation, if none bound before. - * - *

This is a simple Hibernate Session scoping interceptor along the lines of - * {@link OpenSessionInViewInterceptor}, just for use with AOP setup instead of - * MVC setup. It opens a new {@link Session} with flush mode "MANUAL" since the - * Session is only meant for reading, except when participating in a transaction. - * - * @author Juergen Hoeller - * @since 4.0.2 - * @see OpenSessionInViewInterceptor - * @see OpenSessionInViewFilter - * @see org.springframework.orm.hibernate4.HibernateTransactionManager - * @see org.springframework.transaction.support.TransactionSynchronizationManager - * @see org.hibernate.SessionFactory#getCurrentSession() - */ -public class OpenSessionInterceptor implements MethodInterceptor, InitializingBean { - - private SessionFactory sessionFactory; - - - /** - * Set the Hibernate SessionFactory that should be used to create Hibernate Sessions. - */ - public void setSessionFactory(SessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; - } - - /** - * Return the Hibernate SessionFactory that should be used to create Hibernate Sessions. - */ - public SessionFactory getSessionFactory() { - return this.sessionFactory; - } - - @Override - public void afterPropertiesSet() { - if (getSessionFactory() == null) { - throw new IllegalArgumentException("Property 'sessionFactory' is required"); - } - } - - - @Override - public Object invoke(MethodInvocation invocation) throws Throwable { - SessionFactory sf = getSessionFactory(); - if (!TransactionSynchronizationManager.hasResource(sf)) { - // New Session to be bound for the current method's scope... - Session session = openSession(); - try { - TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session)); - return invocation.proceed(); - } - finally { - SessionFactoryUtils.closeSession(session); - TransactionSynchronizationManager.unbindResource(sf); - } - } - else { - // Pre-bound Session found -> simply proceed. - return invocation.proceed(); - } - } - - /** - * Open a Session for the SessionFactory that this interceptor uses. - *

The default implementation delegates to the {@link SessionFactory#openSession} - * method and sets the {@link Session}'s flush mode to "MANUAL". - * @return the Session to use - * @throws DataAccessResourceFailureException if the Session could not be created - * @see org.hibernate.FlushMode#MANUAL - */ - protected Session openSession() throws DataAccessResourceFailureException { - try { - Session session = getSessionFactory().openSession(); - session.setFlushMode(FlushMode.MANUAL); - return session; - } - catch (HibernateException ex) { - throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex); - } - } - -} diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/package-info.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/package-info.java deleted file mode 100644 index 546c98d593..0000000000 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Classes supporting the {@code org.springframework.orm.hibernate4} package. - */ -package org.springframework.orm.hibernate4.support; diff --git a/spring-orm-hibernate4/src/test/java/org/springframework/orm/hibernate4/HibernateTemplateTests.java b/spring-orm-hibernate4/src/test/java/org/springframework/orm/hibernate4/HibernateTemplateTests.java deleted file mode 100644 index 806ae297e6..0000000000 --- a/spring-orm-hibernate4/src/test/java/org/springframework/orm/hibernate4/HibernateTemplateTests.java +++ /dev/null @@ -1,1189 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate4; - -import java.lang.reflect.Proxy; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import org.hibernate.Criteria; -import org.hibernate.Filter; -import org.hibernate.FlushMode; -import org.hibernate.HibernateException; -import org.hibernate.JDBCException; -import org.hibernate.NonUniqueResultException; -import org.hibernate.ObjectDeletedException; -import org.hibernate.ObjectNotFoundException; -import org.hibernate.PersistentObjectException; -import org.hibernate.PropertyValueException; -import org.hibernate.Query; -import org.hibernate.QueryException; -import org.hibernate.ReplicationMode; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.StaleObjectStateException; -import org.hibernate.StaleStateException; -import org.hibernate.TransientObjectException; -import org.hibernate.UnresolvableObjectException; -import org.hibernate.WrongClassException; -import org.hibernate.exception.ConstraintViolationException; -import org.hibernate.exception.DataException; -import org.hibernate.exception.JDBCConnectionException; -import org.hibernate.exception.LockAcquisitionException; -import org.hibernate.exception.SQLGrammarException; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.mockito.InOrder; - -import org.springframework.dao.CannotAcquireLockException; -import org.springframework.dao.DataAccessResourceFailureException; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.dao.IncorrectResultSizeDataAccessException; -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.dao.InvalidDataAccessResourceUsageException; -import org.springframework.tests.sample.beans.TestBean; -import org.springframework.transaction.support.TransactionSynchronizationManager; - -import static org.junit.Assert.*; -import static org.mockito.BDDMockito.*; - -/** - * @author Juergen Hoeller - * @since 4.0.1 - */ -@SuppressWarnings({ "rawtypes", "unchecked" }) -public class HibernateTemplateTests { - - private SessionFactory sessionFactory; - private Session session; - private HibernateTemplate hibernateTemplate; - - @Before - public void setUp() { - this.sessionFactory = mock(SessionFactory.class); - this.session = mock(Session.class); - this.hibernateTemplate = new HibernateTemplate(sessionFactory); - given(sessionFactory.getCurrentSession()).willReturn(session); - } - - @After - public void tearDown() { - assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty()); - assertFalse(TransactionSynchronizationManager.isSynchronizationActive()); - } - - @Test - public void testExecuteWithNewSession() { - given(sessionFactory.getCurrentSession()).willThrow(new HibernateException("no current session")); - given(sessionFactory.openSession()).willReturn(session); - - final List l = new ArrayList(); - l.add("test"); - List result = hibernateTemplate.execute(new HibernateCallback() { - @Override - public List doInHibernate(Session session) { - return l; - } - }); - assertTrue("Correct result list", result == l); - verify(session).close(); - } - - @Test - public void testExecuteWithNewSessionAndFilter() { - given(sessionFactory.getCurrentSession()).willThrow(new HibernateException("no current session")); - given(sessionFactory.openSession()).willReturn(session); - hibernateTemplate.setFilterNames("myFilter"); - - final List l = new ArrayList(); - l.add("test"); - List result = hibernateTemplate.execute(new HibernateCallback() { - @Override - public List doInHibernate(Session session) { - return l; - } - }); - assertTrue("Correct result list", result == l); - verify(session).enableFilter("myFilter"); - verify(session).close(); - } - - @Test - public void testExecuteWithNewSessionAndFilters() { - given(sessionFactory.getCurrentSession()).willThrow(new HibernateException("no current session")); - given(sessionFactory.openSession()).willReturn(session); - hibernateTemplate.setFilterNames("myFilter", "yourFilter"); - - final List l = new ArrayList(); - l.add("test"); - List result = hibernateTemplate.execute(new HibernateCallback() { - @Override - public List doInHibernate(Session session) { - return l; - } - }); - assertTrue("Correct result list", result == l); - InOrder ordered = inOrder(session); - ordered.verify(session).enableFilter("myFilter"); - ordered.verify(session).enableFilter("yourFilter"); - ordered.verify(session).close(); - } - - @Test - public void testExecuteWithThreadBound() { - final List l = new ArrayList(); - l.add("test"); - List result = hibernateTemplate.execute(new HibernateCallback() { - @Override - public List doInHibernate(Session session) { - return l; - } - }); - assertTrue("Correct result list", result == l); - } - - @Test - public void testExecuteWithThreadBoundAndFilter() { - hibernateTemplate.setFilterNames("myFilter"); - - final List l = new ArrayList(); - l.add("test"); - List result = hibernateTemplate.execute(new HibernateCallback() { - @Override - public List doInHibernate(Session session) { - return l; - } - }); - assertTrue("Correct result list", result == l); - - InOrder ordered = inOrder(session); - ordered.verify(session).enableFilter("myFilter"); - ordered.verify(session).disableFilter("myFilter"); - } - - @Test - public void testExecuteWithThreadBoundAndFilters() { - hibernateTemplate.setFilterNames("myFilter", "yourFilter"); - - final List l = new ArrayList(); - l.add("test"); - List result = hibernateTemplate.execute(new HibernateCallback() { - @Override - public List doInHibernate(Session session) { - return l; - } - }); - assertTrue("Correct result list", result == l); - - InOrder ordered = inOrder(session); - ordered.verify(session).enableFilter("myFilter"); - ordered.verify(session).enableFilter("yourFilter"); - ordered.verify(session).disableFilter("myFilter"); - ordered.verify(session).disableFilter("yourFilter"); - } - - @Test - public void testExecuteWithThreadBoundAndParameterizedFilter() { - Filter filter = mock(Filter.class); - given(session.enableFilter("myFilter")).willReturn(filter); - hibernateTemplate.setFilterNames("myFilter"); - - final List l = new ArrayList(); - l.add("test"); - Filter f = hibernateTemplate.enableFilter("myFilter"); - assertTrue("Correct filter", f == filter); - - InOrder ordered = inOrder(session); - ordered.verify(session).getEnabledFilter("myFilter"); - ordered.verify(session).enableFilter("myFilter"); - } - - @Test - public void testExecuteWithThreadBoundAndParameterizedExistingFilter() { - Filter filter = mock(Filter.class); - given(session.enableFilter("myFilter")).willReturn(filter); - hibernateTemplate.setFilterNames("myFilter"); - - final List l = new ArrayList(); - l.add("test"); - Filter f = hibernateTemplate.enableFilter("myFilter"); - assertTrue("Correct filter", f == filter); - - verify(session).getEnabledFilter("myFilter"); - } - - @Test - public void testExecuteWithCacheQueries() { - Query query1 = mock(Query.class); - Query query2 = mock(Query.class); - Criteria criteria = mock(Criteria.class); - given(session.createQuery("some query")).willReturn(query1); - given(query1.setCacheable(true)).willReturn(query1); - given(session.getNamedQuery("some query name")).willReturn(query2); - given(query2.setCacheable(true)).willReturn(query2); - given(session.createCriteria(TestBean.class)).willReturn(criteria); - given(criteria.setCacheable(true)).willReturn(criteria); - - hibernateTemplate.setCacheQueries(true); - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(Session sess) { - assertNotSame(session, sess); - assertTrue(Proxy.isProxyClass(sess.getClass())); - sess.createQuery("some query"); - sess.getNamedQuery("some query name"); - sess.createCriteria(TestBean.class); - // should be ignored - sess.close(); - return null; - } - }); - } - - @Test - public void testExecuteWithCacheQueriesAndCacheRegion() { - Query query1 = mock(Query.class); - Query query2 = mock(Query.class); - Criteria criteria = mock(Criteria.class); - given(session.createQuery("some query")).willReturn(query1); - given(query1.setCacheable(true)).willReturn(query1); - given(query1.setCacheRegion("myRegion")).willReturn(query1); - given(session.getNamedQuery("some query name")).willReturn(query2); - given(query2.setCacheable(true)).willReturn(query2); - given(query2.setCacheRegion("myRegion")).willReturn(query2); - given(session.createCriteria(TestBean.class)).willReturn(criteria); - given(criteria.setCacheable(true)).willReturn(criteria); - given(criteria.setCacheRegion("myRegion")).willReturn(criteria); - - hibernateTemplate.setCacheQueries(true); - hibernateTemplate.setQueryCacheRegion("myRegion"); - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(Session sess) { - assertNotSame(session, sess); - assertTrue(Proxy.isProxyClass(sess.getClass())); - sess.createQuery("some query"); - sess.getNamedQuery("some query name"); - sess.createCriteria(TestBean.class); - // should be ignored - sess.close(); - return null; - } - }); - } - - @Test - public void testExecuteWithCacheQueriesAndCacheRegionAndNativeSession() { - Query query1 = mock(Query.class); - Query query2 = mock(Query.class); - Criteria criteria = mock(Criteria.class); - - given(session.createQuery("some query")).willReturn(query1); - given(session.getNamedQuery("some query name")).willReturn(query2); - given(session.createCriteria(TestBean.class)).willReturn(criteria); - - hibernateTemplate.setExposeNativeSession(true); - hibernateTemplate.setCacheQueries(true); - hibernateTemplate.setQueryCacheRegion("myRegion"); - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(Session sess) { - assertSame(session, sess); - sess.createQuery("some query"); - sess.getNamedQuery("some query name"); - sess.createCriteria(TestBean.class); - return null; - } - }); - } - - @Test - public void testExecuteWithFetchSizeAndMaxResults() { - Query query1 = mock(Query.class); - Query query2 = mock(Query.class); - Criteria criteria = mock(Criteria.class); - - given(session.createQuery("some query")).willReturn(query1); - given(query1.setFetchSize(10)).willReturn(query1); - given(query1.setMaxResults(20)).willReturn(query1); - given(session.getNamedQuery("some query name")).willReturn(query2); - given(query2.setFetchSize(10)).willReturn(query2); - given(query2.setMaxResults(20)).willReturn(query2); - given(session.createCriteria(TestBean.class)).willReturn(criteria); - given(criteria.setFetchSize(10)).willReturn(criteria); - given(criteria.setMaxResults(20)).willReturn(criteria); - - hibernateTemplate.setFetchSize(10); - hibernateTemplate.setMaxResults(20); - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(Session sess) { - sess.createQuery("some query"); - sess.getNamedQuery("some query name"); - sess.createCriteria(TestBean.class); - return null; - } - }); - } - - @Test - public void testGet() { - TestBean tb = new TestBean(); - given(session.get(TestBean.class, "")).willReturn(tb); - Object result = hibernateTemplate.get(TestBean.class, ""); - assertTrue("Correct result", result == tb); - } - - @Test - public void testGetWithEntityName() { - TestBean tb = new TestBean(); - given(session.get("myEntity", "")).willReturn(tb); - Object result = hibernateTemplate.get("myEntity", ""); - assertTrue("Correct result", result == tb); - } - - @Test - public void testLoad() { - TestBean tb = new TestBean(); - given(session.load(TestBean.class, "")).willReturn(tb); - Object result = hibernateTemplate.load(TestBean.class, ""); - assertTrue("Correct result", result == tb); - } - - @Test - public void testLoadWithNotFound() { - ObjectNotFoundException onfex = new ObjectNotFoundException("id", TestBean.class.getName()); - given(session.load(TestBean.class, "id")).willThrow(onfex); - try { - hibernateTemplate.load(TestBean.class, "id"); - fail("Should have thrown HibernateObjectRetrievalFailureException"); - } - catch (HibernateObjectRetrievalFailureException ex) { - // expected - assertEquals(TestBean.class.getName(), ex.getPersistentClassName()); - assertEquals("id", ex.getIdentifier()); - assertEquals(onfex, ex.getCause()); - } - } - - @Test - public void testLoadWithEntityName() { - TestBean tb = new TestBean(); - given(session.load("myEntity", "")).willReturn(tb); - Object result = hibernateTemplate.load("myEntity", ""); - assertTrue("Correct result", result == tb); - } - - @Test - public void testLoadWithObject() { - TestBean tb = new TestBean(); - hibernateTemplate.load(tb, ""); - verify(session).load(tb, ""); - } - - @Test - public void testLoadAll() { - Criteria criteria = mock(Criteria.class); - List list = new ArrayList(); - given(session.createCriteria(TestBean.class)).willReturn(criteria); - given(criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)).willReturn(criteria); - given(criteria.list()).willReturn(list); - List result = hibernateTemplate.loadAll(TestBean.class); - assertTrue("Correct result", result == list); - } - - @Test - public void testLoadAllWithCacheable() { - Criteria criteria = mock(Criteria.class); - List list = new ArrayList(); - given(session.createCriteria(TestBean.class)).willReturn(criteria); - given(criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)).willReturn(criteria); - given(criteria.setCacheable(true)).willReturn(criteria); - given(criteria.list()).willReturn(list); - - hibernateTemplate.setCacheQueries(true); - List result = hibernateTemplate.loadAll(TestBean.class); - assertTrue("Correct result", result == list); - verify(criteria).setCacheable(true); - } - - @Test - public void testLoadAllWithCacheableAndCacheRegion() { - Criteria criteria = mock(Criteria.class); - List list = new ArrayList(); - given(session.createCriteria(TestBean.class)).willReturn(criteria); - given(criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)).willReturn(criteria); - given(criteria.setCacheable(true)).willReturn(criteria); - given(criteria.setCacheRegion("myCacheRegion")).willReturn(criteria); - given(criteria.list()).willReturn(list); - - hibernateTemplate.setCacheQueries(true); - hibernateTemplate.setQueryCacheRegion("myCacheRegion"); - List result = hibernateTemplate.loadAll(TestBean.class); - assertTrue("Correct result", result == list); - verify(criteria).setCacheable(true); - verify(criteria).setCacheRegion("myCacheRegion"); - } - - @Test public void testRefresh() { - TestBean tb = new TestBean(); - hibernateTemplate.refresh(tb); - verify(session).refresh(tb); - } - - @Test public void testContains() { - TestBean tb = new TestBean(); - given(session.contains(tb)).willReturn(true); - assertTrue(hibernateTemplate.contains(tb)); - } - - @Test - public void testEvict() { - TestBean tb = new TestBean(); - hibernateTemplate.evict(tb); - verify(session).evict(tb); - } - - @Test - public void testSave() { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - given(session.save(tb)).willReturn(0); - assertEquals("Correct return value", hibernateTemplate.save(tb), 0); - } - - @Test - public void testSaveWithEntityName() { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - given(session.save("myEntity", tb)).willReturn(0); - assertEquals("Correct return value", hibernateTemplate.save("myEntity", tb), 0); - } - - @Test - public void testUpdate() { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - hibernateTemplate.update(tb); - verify(session).update(tb); - } - - @Test - public void testUpdateWithEntityName() { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - hibernateTemplate.update("myEntity", tb); - verify(session).update("myEntity", tb); - } - - @Test - public void testSaveOrUpdate() { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - hibernateTemplate.saveOrUpdate(tb); - verify(session).saveOrUpdate(tb); - } - - @Test - public void testSaveOrUpdateWithFlushModeNever() { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.MANUAL); - try { - hibernateTemplate.saveOrUpdate(tb); - fail("Should have thrown InvalidDataAccessApiUsageException"); - } - catch (InvalidDataAccessApiUsageException ex) { - // expected - } - } - - @Test - public void testSaveOrUpdateWithEntityName() { - TestBean tb = new TestBean(); - - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - hibernateTemplate.saveOrUpdate("myEntity", tb); - verify(session).saveOrUpdate("myEntity", tb); - } - - @Test - public void testReplicate() { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - hibernateTemplate.replicate(tb, ReplicationMode.LATEST_VERSION); - verify(session).replicate(tb, ReplicationMode.LATEST_VERSION); - } - - @Test - public void testReplicateWithEntityName() { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - hibernateTemplate.replicate("myEntity", tb, ReplicationMode.LATEST_VERSION); - verify(session).replicate("myEntity", tb, ReplicationMode.LATEST_VERSION); - } - - @Test - public void testPersist() { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - hibernateTemplate.persist(tb); - verify(session).persist(tb); - } - - @Test - public void testPersistWithEntityName() { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - hibernateTemplate.persist("myEntity", tb); - verify(session).persist("myEntity", tb); - } - - @Test - public void testMerge() { - TestBean tb = new TestBean(); - TestBean tbMerged = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - given(session.merge(tb)).willReturn(tbMerged); - assertSame(tbMerged, hibernateTemplate.merge(tb)); - } - - @Test - public void testMergeWithEntityName() { - TestBean tb = new TestBean(); - TestBean tbMerged = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - given(session.merge("myEntity", tb)).willReturn(tbMerged); - assertSame(tbMerged, hibernateTemplate.merge("myEntity", tb)); - } - - @Test - public void testDelete() { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - hibernateTemplate.delete(tb); - verify(session).delete(tb); - } - - @Test - public void testDeleteWithEntityName() { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - hibernateTemplate.delete("myEntity", tb); - verify(session).delete("myEntity", tb); - } - - @Test - public void testDeleteAll() { - TestBean tb1 = new TestBean(); - TestBean tb2 = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - List tbs = new ArrayList(); - tbs.add(tb1); - tbs.add(tb2); - hibernateTemplate.deleteAll(tbs); - verify(session).delete(same(tb1)); - verify(session).delete(same(tb2)); - } - - @Test - public void testFlush() { - hibernateTemplate.flush(); - verify(session).flush(); - } - - @Test - public void testClear() { - hibernateTemplate.clear(); - verify(session).clear(); - } - - @Test - public void testFind() { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.createQuery("some query string")).willReturn(query); - given(query.list()).willReturn(list); - List result = hibernateTemplate.find("some query string"); - assertTrue("Correct list", result == list); - } - - @Test - public void testFindWithParameter() { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.createQuery("some query string")).willReturn(query); - given(query.setParameter(0, "myvalue")).willReturn(query); - given(query.list()).willReturn(list); - List result = hibernateTemplate.find("some query string", "myvalue"); - assertTrue("Correct list", result == list); - verify(query).setParameter(0, "myvalue"); - } - - @Test - public void testFindWithParameters() { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.createQuery("some query string")).willReturn(query); - given(query.setParameter(0, "myvalue1")).willReturn(query); - given(query.setParameter(1, 2)).willReturn(query); - given(query.list()).willReturn(list); - List result = hibernateTemplate.find("some query string", "myvalue1", 2); - assertTrue("Correct list", result == list); - verify(query).setParameter(0, "myvalue1"); - verify(query).setParameter(1, 2); - } - - @Test - public void testFindWithNamedParameter() { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.createQuery("some query string")).willReturn(query); - given(query.setParameter("myparam", "myvalue")).willReturn(query); - given(query.list()).willReturn(list); - List result = hibernateTemplate.findByNamedParam("some query string", "myparam", "myvalue"); - assertTrue("Correct list", result == list); - verify(query).setParameter("myparam", "myvalue"); - } - - @Test - public void testFindWithNamedParameters() { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.createQuery("some query string")).willReturn(query); - given(query.setParameter("myparam1", "myvalue1")).willReturn(query); - given(query.setParameter("myparam2", 2)).willReturn(query); - given(query.list()).willReturn(list); - List result = hibernateTemplate.findByNamedParam("some query string", - new String[]{"myparam1", "myparam2"}, - new Object[]{"myvalue1", 2}); - assertTrue("Correct list", result == list); - verify(query).setParameter("myparam1", "myvalue1"); - verify(query).setParameter("myparam2", 2); - } - - @Test - public void testFindByValueBean() { - Query query = mock(Query.class); - TestBean tb = new TestBean(); - List list = new ArrayList(); - given(session.createQuery("some query string")).willReturn(query); - given(query.setProperties(tb)).willReturn(query); - given(query.list()).willReturn(list); - List result = hibernateTemplate.findByValueBean("some query string", tb); - assertTrue("Correct list", result == list); - verify(query).setProperties(tb); - } - - @Test - public void testFindByNamedQuery() { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.getNamedQuery("some query name")).willReturn(query); - given(query.list()).willReturn(list); - List result = hibernateTemplate.findByNamedQuery("some query name"); - assertTrue("Correct list", result == list); - } - - @Test - public void testFindByNamedQueryWithParameter() { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.getNamedQuery("some query name")).willReturn(query); - given(query.setParameter(0, "myvalue")).willReturn(query); - given(query.list()).willReturn(list); - List result = hibernateTemplate.findByNamedQuery("some query name", "myvalue"); - assertTrue("Correct list", result == list); - verify(query).setParameter(0, "myvalue"); - } - - @Test - public void testFindByNamedQueryWithParameters() { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.getNamedQuery("some query name")).willReturn(query); - given(query.setParameter(0, "myvalue1")).willReturn(query); - given(query.setParameter(1, 2)).willReturn(query); - given(query.list()).willReturn(list); - List result = hibernateTemplate.findByNamedQuery("some query name", new Object[] {"myvalue1", 2}); - assertTrue("Correct list", result == list); - verify(query).setParameter(0, "myvalue1"); - verify(query).setParameter(1, 2); - } - - @Test - public void testFindByNamedQueryWithNamedParameter() { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.getNamedQuery("some query name")).willReturn(query); - given(query.setParameter("myparam", "myvalue")).willReturn(query); - given(query.list()).willReturn(list); - List result = hibernateTemplate.findByNamedQueryAndNamedParam("some query name", "myparam", "myvalue"); - assertTrue("Correct list", result == list); - verify(query).setParameter("myparam", "myvalue"); - } - - @Test - public void testFindByNamedQueryWithNamedParameters() { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.getNamedQuery("some query name")).willReturn(query); - given(query.setParameter("myparam1", "myvalue1")).willReturn(query); - given(query.setParameter("myparam2", 2)).willReturn(query); - given(query.list()).willReturn(list); - List result = hibernateTemplate.findByNamedQueryAndNamedParam("some query name", - new String[]{"myparam1", "myparam2"}, - new Object[]{"myvalue1", 2}); - assertTrue("Correct list", result == list); - verify(query).setParameter("myparam1", "myvalue1"); - verify(query).setParameter("myparam2", 2); - } - - @Test - public void testFindByNamedQueryAndValueBean() { - Query query = mock(Query.class); - TestBean tb = new TestBean(); - List list = new ArrayList(); - given(session.getNamedQuery("some query name")).willReturn(query); - given(query.setProperties(tb)).willReturn(query); - given(query.list()).willReturn(list); - List result = hibernateTemplate.findByNamedQueryAndValueBean("some query name", tb); - assertTrue("Correct list", result == list); - verify(query).setProperties(tb); - } - - @Test - public void testFindWithCacheable() { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.createQuery("some query string")).willReturn(query); - given(query.setCacheable(true)).willReturn(query); - given(query.list()).willReturn(list); - hibernateTemplate.setCacheQueries(true); - List result = hibernateTemplate.find("some query string"); - assertTrue("Correct list", result == list); - verify(query).setCacheable(true); - } - - @Test - public void testFindWithCacheableAndCacheRegion() { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.createQuery("some query string")).willReturn(query); - given(query.setCacheable(true)).willReturn(query); - given(query.setCacheRegion("myCacheRegion")).willReturn(query); - given(query.list()).willReturn(list); - hibernateTemplate.setCacheQueries(true); - hibernateTemplate.setQueryCacheRegion("myCacheRegion"); - List result = hibernateTemplate.find("some query string"); - assertTrue("Correct list", result == list); - verify(query).setCacheable(true); - verify(query).setCacheRegion("myCacheRegion"); - } - - @Test - public void testFindByNamedQueryWithCacheable() { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.getNamedQuery("some query name")).willReturn(query); - given(query.setCacheable(true)).willReturn(query); - given(query.list()).willReturn(list); - hibernateTemplate.setCacheQueries(true); - List result = hibernateTemplate.findByNamedQuery("some query name"); - assertTrue("Correct list", result == list); - verify(query).setCacheable(true); - } - - @Test - public void testFindByNamedQueryWithCacheableAndCacheRegion() { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.getNamedQuery("some query name")).willReturn(query); - given(query.setCacheable(true)).willReturn(query); - given(query.setCacheRegion("myCacheRegion")).willReturn(query); - given(query.list()).willReturn(list); - hibernateTemplate.setCacheQueries(true); - hibernateTemplate.setQueryCacheRegion("myCacheRegion"); - List result = hibernateTemplate.findByNamedQuery("some query name"); - assertTrue("Correct list", result == list); - verify(query).setCacheable(true); - verify(query).setCacheRegion("myCacheRegion"); - } - - @Test - public void testIterate() { - Query query = mock(Query.class); - Iterator it = Collections.EMPTY_LIST.iterator(); - given(session.createQuery("some query string")).willReturn(query); - given(query.iterate()).willReturn(it); - Iterator result = hibernateTemplate.iterate("some query string"); - assertTrue("Correct list", result == it); - } - - @Test - public void testIterateWithParameter() { - Query query = mock(Query.class); - Iterator it = Collections.EMPTY_LIST.iterator(); - given(session.createQuery("some query string")).willReturn(query); - given(query.setParameter(0, "myvalue")).willReturn(query); - given(query.iterate()).willReturn(it); - Iterator result = hibernateTemplate.iterate("some query string", "myvalue"); - assertTrue("Correct list", result == it); - verify(query).setParameter(0, "myvalue"); - } - - @Test - public void testIterateWithParameters() { - Query query = mock(Query.class); - Iterator it = Collections.EMPTY_LIST.iterator(); - given(session.createQuery("some query string")).willReturn(query); - given(query.setParameter(0, "myvalue1")).willReturn(query); - given(query.setParameter(1, 2)).willReturn(query); - given(query.iterate()).willReturn(it); - Iterator result = hibernateTemplate.iterate("some query string", "myvalue1", 2); - assertTrue("Correct list", result == it); - verify(query).setParameter(0, "myvalue1"); - verify(query).setParameter(1, 2); - } - - @Test - public void testBulkUpdate() { - Query query = mock(Query.class); - given(session.createQuery("some query string")).willReturn(query); - given(query.executeUpdate()).willReturn(5); - int result = hibernateTemplate.bulkUpdate("some query string"); - assertTrue("Correct list", result == 5); - } - - @Test - public void testBulkUpdateWithParameter() { - Query query = mock(Query.class); - given(session.createQuery("some query string")).willReturn(query); - given(query.setParameter(0, "myvalue")).willReturn(query); - given(query.executeUpdate()).willReturn(5); - int result = hibernateTemplate.bulkUpdate("some query string", "myvalue"); - assertTrue("Correct list", result == 5); - verify(query).setParameter(0, "myvalue"); - } - - @Test - public void testBulkUpdateWithParameters() { - Query query = mock(Query.class); - given(session.createQuery("some query string")).willReturn(query); - given(query.setParameter(0, "myvalue1")).willReturn(query); - given(query.setParameter(1, 2)).willReturn(query); - given(query.executeUpdate()).willReturn(5); - int result = hibernateTemplate.bulkUpdate("some query string", "myvalue1", 2); - assertTrue("Correct list", result == 5); - verify(query).setParameter(0, "myvalue1"); - verify(query).setParameter(1, 2); - } - - @Test - public void testExceptions() { - SQLException sqlEx = new SQLException("argh", "27"); - - final JDBCConnectionException jcex = new JDBCConnectionException("mymsg", sqlEx); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) { - throw jcex; - } - }); - fail("Should have thrown DataAccessResourceFailureException"); - } - catch (DataAccessResourceFailureException ex) { - // expected - assertEquals(jcex, ex.getCause()); - assertTrue(ex.getMessage().contains("mymsg")); - } - - final SQLGrammarException sgex = new SQLGrammarException("mymsg", sqlEx); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) { - throw sgex; - } - }); - fail("Should have thrown InvalidDataAccessResourceUsageException"); - } - catch (InvalidDataAccessResourceUsageException ex) { - // expected - assertEquals(sgex, ex.getCause()); - assertTrue(ex.getMessage().contains("mymsg")); - } - - final LockAcquisitionException laex = new LockAcquisitionException("mymsg", sqlEx); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) { - throw laex; - } - }); - fail("Should have thrown CannotAcquireLockException"); - } - catch (CannotAcquireLockException ex) { - // expected - assertEquals(laex, ex.getCause()); - assertTrue(ex.getMessage().contains("mymsg")); - } - - final ConstraintViolationException cvex = new ConstraintViolationException("mymsg", sqlEx, "myconstraint"); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) { - throw cvex; - } - }); - fail("Should have thrown DataIntegrityViolationException"); - } - catch (DataIntegrityViolationException ex) { - // expected - assertEquals(cvex, ex.getCause()); - assertTrue(ex.getMessage().contains("mymsg")); - } - - final DataException dex = new DataException("mymsg", sqlEx); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) { - throw dex; - } - }); - fail("Should have thrown DataIntegrityViolationException"); - } - catch (DataIntegrityViolationException ex) { - // expected - assertEquals(dex, ex.getCause()); - assertTrue(ex.getMessage().contains("mymsg")); - } - - final JDBCException jdex = new JDBCException("mymsg", sqlEx); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) { - throw jdex; - } - }); - fail("Should have thrown HibernateJdbcException"); - } - catch (HibernateJdbcException ex) { - // expected - assertEquals(jdex, ex.getCause()); - assertTrue(ex.getMessage().contains("mymsg")); - } - - final PropertyValueException pvex = new PropertyValueException("mymsg", "myentity", "myproperty"); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) { - throw pvex; - } - }); - fail("Should have thrown DataIntegrityViolationException"); - } - catch (DataIntegrityViolationException ex) { - // expected - assertEquals(pvex, ex.getCause()); - assertTrue(ex.getMessage().contains("mymsg")); - } - - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) { - throw new PersistentObjectException(""); - } - }); - fail("Should have thrown InvalidDataAccessApiUsageException"); - } - catch (InvalidDataAccessApiUsageException ex) { - // expected - } - - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) { - throw new TransientObjectException(""); - } - }); - fail("Should have thrown InvalidDataAccessApiUsageException"); - } - catch (InvalidDataAccessApiUsageException ex) { - // expected - } - - final ObjectDeletedException odex = new ObjectDeletedException("msg", "id", TestBean.class.getName()); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) { - throw odex; - } - }); - fail("Should have thrown InvalidDataAccessApiUsageException"); - } - catch (InvalidDataAccessApiUsageException ex) { - // expected - assertEquals(odex, ex.getCause()); - } - - final QueryException qex = new QueryException("msg", "query"); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) { - throw qex; - } - }); - fail("Should have thrown InvalidDataAccessResourceUsageException"); - } - catch (HibernateQueryException ex) { - // expected - assertEquals(qex, ex.getCause()); - assertEquals("query", ex.getQueryString()); - } - - final UnresolvableObjectException uoex = new UnresolvableObjectException("id", TestBean.class.getName()); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) { - throw uoex; - } - }); - fail("Should have thrown HibernateObjectRetrievalFailureException"); - } - catch (HibernateObjectRetrievalFailureException ex) { - // expected - assertEquals(TestBean.class.getName(), ex.getPersistentClassName()); - assertEquals("id", ex.getIdentifier()); - assertEquals(uoex, ex.getCause()); - } - - final ObjectNotFoundException onfe = new ObjectNotFoundException("id", TestBean.class.getName()); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) { - throw onfe; - } - }); - fail("Should have thrown HibernateObjectRetrievalFailureException"); - } - catch (HibernateObjectRetrievalFailureException ex) { - // expected - assertEquals(TestBean.class.getName(), ex.getPersistentClassName()); - assertEquals("id", ex.getIdentifier()); - assertEquals(onfe, ex.getCause()); - } - - final WrongClassException wcex = new WrongClassException("msg", "id", TestBean.class.getName()); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) { - throw wcex; - } - }); - fail("Should have thrown HibernateObjectRetrievalFailureException"); - } - catch (HibernateObjectRetrievalFailureException ex) { - // expected - assertEquals(TestBean.class.getName(), ex.getPersistentClassName()); - assertEquals("id", ex.getIdentifier()); - assertEquals(wcex, ex.getCause()); - } - - final NonUniqueResultException nuex = new NonUniqueResultException(2); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) { - throw nuex; - } - }); - fail("Should have thrown IncorrectResultSizeDataAccessException"); - } - catch (IncorrectResultSizeDataAccessException ex) { - // expected - assertEquals(1, ex.getExpectedSize()); - assertEquals(-1, ex.getActualSize()); - } - - final StaleObjectStateException sosex = new StaleObjectStateException(TestBean.class.getName(), "id"); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) { - throw sosex; - } - }); - fail("Should have thrown HibernateOptimisticLockingFailureException"); - } - catch (HibernateOptimisticLockingFailureException ex) { - // expected - assertEquals(TestBean.class.getName(), ex.getPersistentClassName()); - assertEquals("id", ex.getIdentifier()); - assertEquals(sosex, ex.getCause()); - } - - final StaleStateException ssex = new StaleStateException("msg"); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) { - throw ssex; - } - }); - fail("Should have thrown HibernateOptimisticLockingFailureException"); - } - catch (HibernateOptimisticLockingFailureException ex) { - // expected - assertNull(ex.getPersistentClassName()); - assertNull(ex.getIdentifier()); - assertEquals(ssex, ex.getCause()); - } - - final HibernateException hex = new HibernateException("msg"); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) { - throw hex; - } - }); - fail("Should have thrown HibernateSystemException"); - } - catch (HibernateSystemException ex) { - // expected - assertEquals(hex, ex.getCause()); - } - } - -} diff --git a/spring-orm-hibernate4/src/test/java/org/springframework/orm/hibernate4/HibernateTransactionManagerTests.java b/spring-orm-hibernate4/src/test/java/org/springframework/orm/hibernate4/HibernateTransactionManagerTests.java deleted file mode 100644 index 9192ca9d7e..0000000000 --- a/spring-orm-hibernate4/src/test/java/org/springframework/orm/hibernate4/HibernateTransactionManagerTests.java +++ /dev/null @@ -1,1331 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate4; - -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Savepoint; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; -import javax.sql.DataSource; -import javax.transaction.TransactionManager; -import javax.transaction.TransactionSynchronizationRegistry; -import javax.transaction.UserTransaction; - -import org.hibernate.FlushMode; -import org.hibernate.Interceptor; -import org.hibernate.Query; -import org.hibernate.Session; -import org.hibernate.SessionBuilder; -import org.hibernate.SessionFactory; -import org.hibernate.Transaction; -import org.hibernate.cfg.AvailableSettings; -import org.hibernate.dialect.HSQLDialect; -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory; -import org.hibernate.exception.ConstraintViolationException; -import org.junit.After; -import org.junit.Test; -import org.mockito.InOrder; - -import org.springframework.beans.factory.BeanFactory; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.jdbc.datasource.ConnectionHolder; -import org.springframework.jdbc.datasource.DriverManagerDataSource; -import org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy; -import org.springframework.transaction.CannotCreateTransactionException; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.TransactionStatus; -import org.springframework.transaction.UnexpectedRollbackException; -import org.springframework.transaction.jta.JtaTransactionManager; -import org.springframework.transaction.support.TransactionCallback; -import org.springframework.transaction.support.TransactionCallbackWithoutResult; -import org.springframework.transaction.support.TransactionSynchronizationManager; -import org.springframework.transaction.support.TransactionTemplate; - -import static org.junit.Assert.*; -import static org.mockito.BDDMockito.*; - -/** - * @author Juergen Hoeller - * @since 3.2 - */ -@SuppressWarnings({"rawtypes", "unchecked"}) -public class HibernateTransactionManagerTests { - - @After - public void tearDown() { - assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty()); - assertFalse(TransactionSynchronizationManager.isSynchronizationActive()); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); - } - - @Test - public void testTransactionCommit() throws Exception { - final DataSource ds = mock(DataSource.class); - Connection con = mock(Connection.class); - final SessionFactory sf = mock(SessionFactory.class); - final ImplementingSession session = mock(ImplementingSession.class); - Transaction tx = mock(Transaction.class); - Query query = mock(Query.class); - - final List list = new ArrayList(); - list.add("test"); - given(con.getTransactionIsolation()).willReturn(Connection.TRANSACTION_READ_COMMITTED); - given(sf.openSession()).willReturn(session); - given(session.getTransaction()).willReturn(tx); - given(session.connection()).willReturn(con); - given(session.isOpen()).willReturn(true); - given(session.createQuery("some query string")).willReturn(query); - given(query.list()).willReturn(list); - given(session.isConnected()).willReturn(true); - - LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean() { - @Override - protected SessionFactory buildSessionFactory(LocalSessionFactoryBuilder sfb) { - return sf; - } - }; - lsfb.afterPropertiesSet(); - final SessionFactory sfProxy = lsfb.getObject(); - - HibernateTransactionManager tm = new HibernateTransactionManager(); - tm.setSessionFactory(sfProxy); - tm.setDataSource(ds); - TransactionTemplate tt = new TransactionTemplate(tm); - tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE); - tt.setTimeout(10); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sfProxy)); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - Object result = tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sfProxy)); - assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); - Session session = ((SessionHolder) TransactionSynchronizationManager.getResource(sfProxy)).getSession(); - return session.createQuery("some query string").list(); - } - }); - assertTrue("Correct result list", result == list); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sfProxy)); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - verify(con).setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); - verify(con).setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); - verify(tx).setTimeout(10); - verify(tx).begin(); - verify(tx).commit(); - verify(session).close(); - } - - @Test - public void testTransactionRollback() throws Exception { - Connection con = mock(Connection.class); - final SessionFactory sf = mock(SessionFactory.class); - ImplementingSession session = mock(ImplementingSession.class); - Transaction tx = mock(Transaction.class); - - given(sf.openSession()).willReturn(session); - given(session.beginTransaction()).willReturn(tx); - given(session.isOpen()).willReturn(true); - given(session.isConnected()).willReturn(true); - given(session.connection()).willReturn(con); - - PlatformTransactionManager tm = new HibernateTransactionManager(sf); - TransactionTemplate tt = new TransactionTemplate(tm); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - try { - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - throw new RuntimeException("application exception"); - } - }); - fail("Should have thrown RuntimeException"); - } - catch (RuntimeException ex) { - // expected - } - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - verify(session).close(); - verify(tx).rollback(); - } - - @Test - public void testTransactionRollbackOnly() throws Exception { - Connection con = mock(Connection.class); - final SessionFactory sf = mock(SessionFactory.class); - ImplementingSession session = mock(ImplementingSession.class); - Transaction tx = mock(Transaction.class); - - given(sf.openSession()).willReturn(session); - given(session.beginTransaction()).willReturn(tx); - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - given(session.isConnected()).willReturn(true); - given(session.connection()).willReturn(con); - - PlatformTransactionManager tm = new HibernateTransactionManager(sf); - TransactionTemplate tt = new TransactionTemplate(tm); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - Session session = ((SessionHolder) TransactionSynchronizationManager.getResource(sf)).getSession(); - session.flush(); - status.setRollbackOnly(); - return null; - } - }); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - verify(session).flush(); - verify(session).close(); - verify(tx).rollback(); - } - - @Test - public void testParticipatingTransactionWithCommit() throws Exception { - Connection con = mock(Connection.class); - final SessionFactory sf = mock(SessionFactory.class); - final ImplementingSession session = mock(ImplementingSession.class); - Transaction tx = mock(Transaction.class); - - given(sf.openSession()).willReturn(session); - given(session.beginTransaction()).willReturn(tx); - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - given(session.isConnected()).willReturn(true); - given(session.connection()).willReturn(con); - - LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean() { - @Override - protected SessionFactory buildSessionFactory(LocalSessionFactoryBuilder sfb) { - return sf; - } - }; - lsfb.afterPropertiesSet(); - final SessionFactory sfProxy = lsfb.getObject(); - - PlatformTransactionManager tm = new HibernateTransactionManager(sfProxy); - final TransactionTemplate tt = new TransactionTemplate(tm); - final List l = new ArrayList(); - l.add("test"); - - Object result = tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - return tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - Session session = ((SessionHolder) TransactionSynchronizationManager.getResource(sf)).getSession(); - session.flush(); - return l; - } - }); - } - }); - assertTrue("Correct result list", result == l); - - verify(session).flush(); - verify(session).close(); - verify(tx).commit(); - } - - @Test - public void testParticipatingTransactionWithRollback() throws Exception { - Connection con = mock(Connection.class); - final SessionFactory sf = mock(SessionFactory.class); - ImplementingSession session = mock(ImplementingSession.class); - Transaction tx = mock(Transaction.class); - - given(sf.openSession()).willReturn(session); - given(session.beginTransaction()).willReturn(tx); - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - given(session.isConnected()).willReturn(true); - given(session.connection()).willReturn(con); - - PlatformTransactionManager tm = new HibernateTransactionManager(sf); - final TransactionTemplate tt = new TransactionTemplate(tm); - try { - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - return tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - throw new RuntimeException("application exception"); - } - }); - } - }); - fail("Should have thrown RuntimeException"); - } - catch (RuntimeException ex) { - // expected - } - - verify(session).close(); - verify(tx).rollback(); - } - - @Test - public void testParticipatingTransactionWithRollbackOnly() throws Exception { - Connection con = mock(Connection.class); - final SessionFactory sf = mock(SessionFactory.class); - ImplementingSession session = mock(ImplementingSession.class); - Transaction tx = mock(Transaction.class); - - given(sf.openSession()).willReturn(session); - given(session.beginTransaction()).willReturn(tx); - given(session.isOpen()).willReturn(true); - given(session.isConnected()).willReturn(true); - given(session.connection()).willReturn(con); - - PlatformTransactionManager tm = new HibernateTransactionManager(sf); - final TransactionTemplate tt = new TransactionTemplate(tm); - final List l = new ArrayList(); - l.add("test"); - - try { - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - return tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - status.setRollbackOnly(); - return null; - } - }); - } - }); - fail("Should have thrown UnexpectedRollbackException"); - } - catch (UnexpectedRollbackException ex) { - // expected - } - - verify(session).close(); - verify(tx).rollback(); - } - - @Test - public void testParticipatingTransactionWithRequiresNew() throws Exception { - final SessionFactory sf = mock(SessionFactory.class); - ImplementingSession session1 = mock(ImplementingSession.class); - ImplementingSession session2 = mock(ImplementingSession.class); - Connection con = mock(Connection.class); - Transaction tx = mock(Transaction.class); - - given(sf.openSession()).willReturn(session1, session2); - given(session1.beginTransaction()).willReturn(tx); - given(session1.isOpen()).willReturn(true); - given(session2.beginTransaction()).willReturn(tx); - given(session2.isOpen()).willReturn(true); - given(session2.getFlushMode()).willReturn(FlushMode.AUTO); - given(session1.isConnected()).willReturn(true); - given(session1.connection()).willReturn(con); - given(session2.isConnected()).willReturn(true); - given(session2.connection()).willReturn(con); - - PlatformTransactionManager tm = new HibernateTransactionManager(sf); - final TransactionTemplate tt = new TransactionTemplate(tm); - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - final SessionHolder holder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); - assertTrue("Has thread session", holder != null); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - Session session = ((SessionHolder) TransactionSynchronizationManager.getResource(sf)).getSession(); - assertTrue("Not enclosing session", session != holder.getSession()); - session.flush(); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); - return null; - } - }); - assertTrue("Same thread session as before", - holder.getSession() == ((SessionHolder) TransactionSynchronizationManager.getResource(sf)).getSession()); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); - return null; - } - }); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - - verify(session2).flush(); - verify(session1).close(); - verify(session2).close(); - verify(tx, times(2)).commit(); - } - - @Test - public void testParticipatingTransactionWithNotSupported() throws Exception { - final SessionFactory sf = mock(SessionFactory.class); - ImplementingSession session = mock(ImplementingSession.class); - Connection con = mock(Connection.class); - Transaction tx = mock(Transaction.class); - - given(sf.openSession()).willReturn(session); - given(session.getSessionFactory()).willReturn(sf); - given(session.beginTransaction()).willReturn(tx); - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - given(session.isConnected()).willReturn(true); - given(session.connection()).willReturn(con); - - HibernateTransactionManager tm = new HibernateTransactionManager(sf); - final TransactionTemplate tt = new TransactionTemplate(tm); - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - SessionHolder holder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); - assertTrue("Has thread session", holder != null); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED); - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); - return null; - } - }); - assertTrue("Same thread session as before", - holder.getSession() == ((SessionHolder) TransactionSynchronizationManager.getResource(sf)).getSession()); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); - return null; - } - }); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - - verify(session).close(); - verify(tx).commit(); - } - - @Test - public void testTransactionWithPropagationSupports() throws Exception { - final SessionFactory sf = mock(SessionFactory.class); - final Session session = mock(Session.class); - - given(sf.openSession()).willReturn(session); - given(session.getSessionFactory()).willReturn(sf); - given(session.getFlushMode()).willReturn(FlushMode.MANUAL); - - LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean() { - @Override - protected SessionFactory buildSessionFactory(LocalSessionFactoryBuilder sfb) { - return sf; - } - }; - lsfb.afterPropertiesSet(); - final SessionFactory sfProxy = lsfb.getObject(); - - PlatformTransactionManager tm = new HibernateTransactionManager(sfProxy); - TransactionTemplate tt = new TransactionTemplate(tm); - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sfProxy)); - - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sfProxy)); - assertTrue("Is not new transaction", !status.isNewTransaction()); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); - Session session = sf.openSession(); - session.flush(); - session.close(); - return null; - } - }); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sfProxy)); - InOrder ordered = inOrder(session); - ordered.verify(session).flush(); - ordered.verify(session).close(); - } - - @Test - public void testTransactionWithPropagationSupportsAndCurrentSession() throws Exception { - final SessionFactoryImplementor sf = mock(SessionFactoryImplementor.class); - final Session session = mock(Session.class); - - given(sf.openSession()).willReturn(session); - given(session.getSessionFactory()).willReturn(sf); - given(session.getFlushMode()).willReturn(FlushMode.MANUAL); - - LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean() { - @Override - protected SessionFactory buildSessionFactory(LocalSessionFactoryBuilder sfb) { - return sf; - } - }; - lsfb.afterPropertiesSet(); - final SessionFactory sfProxy = lsfb.getObject(); - - PlatformTransactionManager tm = new HibernateTransactionManager(sfProxy); - TransactionTemplate tt = new TransactionTemplate(tm); - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sfProxy)); - - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sfProxy)); - assertTrue("Is not new transaction", !status.isNewTransaction()); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); - Session session = new SpringSessionContext(sf).currentSession(); - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sfProxy)); - session.flush(); - return null; - } - }); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sfProxy)); - InOrder ordered = inOrder(session); - ordered.verify(session).flush(); - ordered.verify(session).close(); - } - - @Test - public void testTransactionWithPropagationSupportsAndInnerTransaction() throws Exception { - final SessionFactory sf = mock(SessionFactory.class); - final ImplementingSession session1 = mock(ImplementingSession.class); - final ImplementingSession session2 = mock(ImplementingSession.class); - Connection con = mock(Connection.class); - Transaction tx = mock(Transaction.class); - - given(sf.openSession()).willReturn(session1, session2); - given(session1.getSessionFactory()).willReturn(sf); - given(session1.getFlushMode()).willReturn(FlushMode.AUTO); - given(session2.beginTransaction()).willReturn(tx); - given(session2.connection()).willReturn(con); - given(session2.getFlushMode()).willReturn(FlushMode.AUTO); - given(session2.isOpen()).willReturn(true); - given(session2.isConnected()).willReturn(true); - - LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean() { - @Override - protected SessionFactory buildSessionFactory(LocalSessionFactoryBuilder sfb) { - return sf; - } - }; - lsfb.afterPropertiesSet(); - final SessionFactory sfProxy = lsfb.getObject(); - - PlatformTransactionManager tm = new HibernateTransactionManager(sfProxy); - TransactionTemplate tt = new TransactionTemplate(tm); - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); - final TransactionTemplate tt2 = new TransactionTemplate(tm); - tt2.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sfProxy)); - assertTrue("Is not new transaction", !status.isNewTransaction()); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); - Session session = sfProxy.openSession(); - assertSame(session1, session); - tt2.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); - Session session = ((SessionHolder) TransactionSynchronizationManager.getResource(sf)).getSession(); - assertSame(session2, session); - session.flush(); - return null; - } - }); - session.flush(); - session.close(); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); - return null; - } - }); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - - verify(session1).flush(); - verify(session1).close(); - verify(session2).flush(); - verify(session2).close(); - verify(tx).commit(); - } - - @Test - public void testTransactionCommitWithEntityInterceptor() throws Exception { - Interceptor entityInterceptor = mock(Interceptor.class); - Connection con = mock(Connection.class); - final SessionFactory sf = mock(SessionFactory.class); - ImplementingSession session = mock(ImplementingSession.class); - SessionBuilder options = mock(SessionBuilder.class); - Transaction tx = mock(Transaction.class); - - given(sf.withOptions()).willReturn(options); - given(options.interceptor(entityInterceptor)).willReturn(options); - given(options.openSession()).willReturn(session); - given(session.beginTransaction()).willReturn(tx); - given(session.isOpen()).willReturn(true); - given(session.isConnected()).willReturn(true); - given(session.connection()).willReturn(con); - - HibernateTransactionManager tm = new HibernateTransactionManager(sf); - tm.setEntityInterceptor(entityInterceptor); - tm.setAllowResultAccessAfterCompletion(true); - TransactionTemplate tt = new TransactionTemplate(tm); - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - tt.execute(new TransactionCallbackWithoutResult() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - } - }); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - verify(session).close(); - verify(tx).commit(); - } - - @Test - public void testTransactionCommitWithEntityInterceptorBeanName() throws Exception { - Interceptor entityInterceptor = mock(Interceptor.class); - Interceptor entityInterceptor2 = mock(Interceptor.class); - Connection con = mock(Connection.class); - final SessionFactory sf = mock(SessionFactory.class); - ImplementingSession session = mock(ImplementingSession.class); - SessionBuilder options = mock(SessionBuilder.class); - Transaction tx = mock(Transaction.class); - - given(sf.withOptions()).willReturn(options); - given(options.interceptor(entityInterceptor)).willReturn(options); - given(options.interceptor(entityInterceptor2)).willReturn(options); - given(options.openSession()).willReturn(session); - given(session.beginTransaction()).willReturn(tx); - given(session.isOpen()).willReturn(true); - given(session.isConnected()).willReturn(true); - given(session.connection()).willReturn(con); - - BeanFactory beanFactory = mock(BeanFactory.class); - given(beanFactory.getBean("entityInterceptor", Interceptor.class)).willReturn( - entityInterceptor, entityInterceptor2); - - HibernateTransactionManager tm = new HibernateTransactionManager(sf); - tm.setEntityInterceptorBeanName("entityInterceptor"); - tm.setBeanFactory(beanFactory); - - TransactionTemplate tt = new TransactionTemplate(tm); - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - for (int i = 0; i < 2; i++) { - tt.execute(new TransactionCallbackWithoutResult() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - } - }); - } - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - verify(session, times(2)).close(); - verify(tx, times(2)).commit(); - } - - @Test - public void testTransactionCommitWithReadOnly() throws Exception { - Connection con = mock(Connection.class); - final SessionFactory sf = mock(SessionFactory.class); - ImplementingSession session = mock(ImplementingSession.class); - Transaction tx = mock(Transaction.class); - Query query = mock(Query.class); - - final List list = new ArrayList(); - list.add("test"); - given(sf.openSession()).willReturn(session); - given(session.beginTransaction()).willReturn(tx); - given(session.connection()).willReturn(con); - given(session.isOpen()).willReturn(true); - given(session.createQuery("some query string")).willReturn(query); - given(query.list()).willReturn(list); - given(session.isConnected()).willReturn(true); - given(con.isReadOnly()).willReturn(true); - - HibernateTransactionManager tm = new HibernateTransactionManager(sf); - TransactionTemplate tt = new TransactionTemplate(tm); - tt.setReadOnly(true); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - Object result = tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertTrue(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); - Session session = ((SessionHolder) TransactionSynchronizationManager.getResource(sf)).getSession(); - return session.createQuery("some query string").list(); - } - }); - assertTrue("Correct result list", result == list); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - verify(session).setFlushMode(FlushMode.MANUAL); - verify(con).setReadOnly(true); - verify(tx).commit(); - verify(con).setReadOnly(false); - verify(session).close(); - } - - @Test - public void testTransactionCommitWithFlushFailure() throws Exception { - Connection con = mock(Connection.class); - final SessionFactory sf = mock(SessionFactory.class); - ImplementingSession session = mock(ImplementingSession.class); - Transaction tx = mock(Transaction.class); - - given(sf.openSession()).willReturn(session); - given(session.beginTransaction()).willReturn(tx); - given(session.isOpen()).willReturn(true); - SQLException sqlEx = new SQLException("argh", "27"); - Exception rootCause = null; - ConstraintViolationException jdbcEx = new ConstraintViolationException("mymsg", sqlEx, null); - rootCause = jdbcEx; - willThrow(jdbcEx).given(tx).commit(); - given(session.isConnected()).willReturn(true); - given(session.connection()).willReturn(con); - - HibernateTransactionManager tm = new HibernateTransactionManager(sf); - TransactionTemplate tt = new TransactionTemplate(tm); - final List l = new ArrayList(); - l.add("test"); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - try { - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - return l; - } - }); - fail("Should have thrown DataIntegrityViolationException"); - } - catch (DataIntegrityViolationException ex) { - // expected - assertEquals(rootCause, ex.getCause()); - assertTrue(ex.getMessage().contains("mymsg")); - } - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - verify(session).close(); - verify(tx).rollback(); - } - - @Test - public void testTransactionCommitWithPreBound() throws Exception { - final DataSource ds = mock(DataSource.class); - Connection con = mock(Connection.class); - final SessionFactory sf = mock(SessionFactory.class); - final ImplementingSession session = mock(ImplementingSession.class); - Transaction tx = mock(Transaction.class); - - given(session.beginTransaction()).willReturn(tx); - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(FlushMode.MANUAL); - given(session.connection()).willReturn(con); - given(con.getTransactionIsolation()).willReturn(Connection.TRANSACTION_READ_COMMITTED); - given(session.isConnected()).willReturn(true); - - HibernateTransactionManager tm = new HibernateTransactionManager(); - tm.setSessionFactory(sf); - tm.setDataSource(ds); - TransactionTemplate tt = new TransactionTemplate(tm); - tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE); - final List l = new ArrayList(); - l.add("test"); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session)); - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - - Object result = tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); - SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); - assertTrue("Has thread transaction", sessionHolder.getTransaction() != null); - Session sess = ((SessionHolder) TransactionSynchronizationManager.getResource(sf)).getSession(); - assertEquals(session, sess); - return l; - } - }); - assertTrue("Correct result list", result == l); - - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); - assertTrue("Hasn't thread transaction", sessionHolder.getTransaction() == null); - TransactionSynchronizationManager.unbindResource(sf); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - InOrder ordered = inOrder(session, con); - ordered.verify(con).setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); - ordered.verify(session).setFlushMode(FlushMode.AUTO); - ordered.verify(con).setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); - ordered.verify(session).setFlushMode(FlushMode.MANUAL); - verify(tx).commit(); - verify(session).disconnect(); - } - - @Test - public void testTransactionCommitWithPreBoundAndResultAccessAfterCommit() throws Exception { - final DataSource ds = mock(DataSource.class); - Connection con = mock(Connection.class); - final SessionFactory sf = mock(SessionFactory.class); - final ImplementingSession session = mock(ImplementingSession.class); - Transaction tx = mock(Transaction.class); - - given(session.beginTransaction()).willReturn(tx); - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(FlushMode.MANUAL); - given(session.connection()).willReturn(con); - given(con.getTransactionIsolation()).willReturn(Connection.TRANSACTION_READ_COMMITTED); - given(con.getHoldability()).willReturn(ResultSet.CLOSE_CURSORS_AT_COMMIT); - given(session.isConnected()).willReturn(true); - - HibernateTransactionManager tm = new HibernateTransactionManager(); - tm.setSessionFactory(sf); - tm.setDataSource(ds); - tm.setAllowResultAccessAfterCompletion(true); - TransactionTemplate tt = new TransactionTemplate(tm); - tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE); - final List l = new ArrayList(); - l.add("test"); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session)); - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - - Object result = tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); - SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); - assertTrue("Has thread transaction", sessionHolder.getTransaction() != null); - Session sess = ((SessionHolder) TransactionSynchronizationManager.getResource(sf)).getSession(); - assertEquals(session, sess); - return l; - } - }); - assertTrue("Correct result list", result == l); - - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); - assertTrue("Hasn't thread transaction", sessionHolder.getTransaction() == null); - TransactionSynchronizationManager.unbindResource(sf); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - InOrder ordered = inOrder(session, con); - ordered.verify(con).setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); - ordered.verify(con).setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT); - ordered.verify(session).setFlushMode(FlushMode.AUTO); - ordered.verify(con).setHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT); - ordered.verify(con).setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); - ordered.verify(session).setFlushMode(FlushMode.MANUAL); - verify(tx).commit(); - } - - @Test - public void testTransactionRollbackWithPreBound() throws Exception { - final DataSource ds = mock(DataSource.class); - Connection con = mock(Connection.class); - final SessionFactory sf = mock(SessionFactory.class); - final ImplementingSession session = mock(ImplementingSession.class); - final Transaction tx1 = mock(Transaction.class); - final Transaction tx2 = mock(Transaction.class); - - given(session.beginTransaction()).willReturn(tx1, tx2); - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(FlushMode.MANUAL); - given(session.isConnected()).willReturn(true); - given(session.connection()).willReturn(con); - - HibernateTransactionManager tm = new HibernateTransactionManager(); - tm.setSessionFactory(sf); - tm.setDataSource(ds); - final TransactionTemplate tt = new TransactionTemplate(tm); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session)); - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - - try { - tt.execute(new TransactionCallbackWithoutResult() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); - SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); - assertEquals(tx1, sessionHolder.getTransaction()); - tt.execute(new TransactionCallbackWithoutResult() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - status.setRollbackOnly(); - Session sess = ((SessionHolder) TransactionSynchronizationManager.getResource(sf)).getSession(); - assertEquals(session, sess); - } - }); - } - }); - fail("Should have thrown UnexpectedRollbackException"); - } - catch (UnexpectedRollbackException ex) { - // expected - } - - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); - assertTrue("Hasn't thread transaction", sessionHolder.getTransaction() == null); - assertTrue("Not marked rollback-only", !sessionHolder.isRollbackOnly()); - - tt.execute(new TransactionCallbackWithoutResult() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); - SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); - assertEquals(tx2, sessionHolder.getTransaction()); - Session sess = ((SessionHolder) TransactionSynchronizationManager.getResource(sf)).getSession(); - assertEquals(session, sess); - } - }); - - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Hasn't thread transaction", sessionHolder.getTransaction() == null); - TransactionSynchronizationManager.unbindResource(sf); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - verify(tx1).rollback(); - verify(tx2).commit(); - InOrder ordered = inOrder(session); - ordered.verify(session).clear(); - ordered.verify(session).setFlushMode(FlushMode.AUTO); - ordered.verify(session).setFlushMode(FlushMode.MANUAL); - ordered.verify(session).disconnect(); - } - - @Test - public void testTransactionRollbackWithHibernateManagedSession() throws Exception { - final SessionFactory sf = mock(SessionFactory.class); - final Session session = mock(Session.class); - final Transaction tx1 = mock(Transaction.class); - final Transaction tx2 = mock(Transaction.class); - - given(sf.getCurrentSession()).willReturn(session); - given(session.isOpen()).willReturn(true); - given(session.getTransaction()).willReturn(tx1, tx2); - given(session.beginTransaction()).willReturn(tx1, tx2); - given(session.getFlushMode()).willReturn(FlushMode.MANUAL); - - HibernateTransactionManager tm = new HibernateTransactionManager(); - tm.setSessionFactory(sf); - tm.setPrepareConnection(false); - tm.setHibernateManagedSession(true); - final TransactionTemplate tt = new TransactionTemplate(tm); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - - try { - tt.execute(new TransactionCallbackWithoutResult() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - tt.execute(new TransactionCallbackWithoutResult() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - status.setRollbackOnly(); - Session sess = ((SessionHolder) TransactionSynchronizationManager.getResource(sf)).getSession(); - assertEquals(session, sess); - } - }); - } - }); - fail("Should have thrown UnexpectedRollbackException"); - } - catch (UnexpectedRollbackException ex) { - // expected - } - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - - tt.execute(new TransactionCallbackWithoutResult() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - Session sess = ((SessionHolder) TransactionSynchronizationManager.getResource(sf)).getSession(); - assertEquals(session, sess); - } - }); - - verify(tx1).rollback(); - verify(tx2).commit(); - InOrder ordered = inOrder(session); - ordered.verify(session).setFlushMode(FlushMode.AUTO); - ordered.verify(session).setFlushMode(FlushMode.MANUAL); - } - - @Test - public void testExistingTransactionWithPropagationNestedAndRollback() throws Exception { - doTestExistingTransactionWithPropagationNestedAndRollback(false); - } - - @Test - public void testExistingTransactionWithManualSavepointAndRollback() throws Exception { - doTestExistingTransactionWithPropagationNestedAndRollback(true); - } - - private void doTestExistingTransactionWithPropagationNestedAndRollback(final boolean manualSavepoint) - throws Exception { - - final DataSource ds = mock(DataSource.class); - Connection con = mock(Connection.class); - DatabaseMetaData md = mock(DatabaseMetaData.class); - Savepoint sp = mock(Savepoint.class); - final SessionFactory sf = mock(SessionFactory.class); - ImplementingSession session = mock(ImplementingSession.class); - Transaction tx = mock(Transaction.class); - Query query = mock(Query.class); - - final List list = new ArrayList(); - list.add("test"); - given(sf.openSession()).willReturn(session); - given(session.beginTransaction()).willReturn(tx); - given(session.connection()).willReturn(con); - given(session.isOpen()).willReturn(true); - given(md.supportsSavepoints()).willReturn(true); - given(con.getMetaData()).willReturn(md); - given(con.setSavepoint(ConnectionHolder.SAVEPOINT_NAME_PREFIX + 1)).willReturn(sp); - given(session.createQuery("some query string")).willReturn(query); - given(query.list()).willReturn(list); - given(session.isConnected()).willReturn(true); - - HibernateTransactionManager tm = new HibernateTransactionManager(); - tm.setNestedTransactionAllowed(true); - tm.setSessionFactory(sf); - tm.setDataSource(ds); - final TransactionTemplate tt = new TransactionTemplate(tm); - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - Object result = tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); - if (manualSavepoint) { - Object savepoint = status.createSavepoint(); - status.rollbackToSavepoint(savepoint); - } - else { - tt.execute(new TransactionCallbackWithoutResult() { - @Override - protected void doInTransactionWithoutResult(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); - status.setRollbackOnly(); - } - }); - } - Session session = ((SessionHolder) TransactionSynchronizationManager.getResource(sf)).getSession(); - return session.createQuery("some query string").list(); - } - }); - assertTrue("Correct result list", result == list); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - verify(con).setSavepoint(ConnectionHolder.SAVEPOINT_NAME_PREFIX + 1); - verify(con).rollback(sp); - verify(session).close(); - verify(tx).commit(); - } - - @Test - public void testTransactionCommitWithNonExistingDatabase() throws Exception { - final DriverManagerDataSource ds = new DriverManagerDataSource(); - LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean(); - lsfb.setDataSource(ds); - Properties props = new Properties(); - props.setProperty("hibernate.dialect", HSQLDialect.class.getName()); - lsfb.setHibernateProperties(props); - lsfb.afterPropertiesSet(); - final SessionFactory sf = lsfb.getObject(); - - HibernateTransactionManager tm = new HibernateTransactionManager(); - tm.setSessionFactory(sf); - tm.afterPropertiesSet(); - TransactionTemplate tt = new TransactionTemplate(tm); - tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE); - tt.setTimeout(10); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - try { - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); - Session session = ((SessionHolder) TransactionSynchronizationManager.getResource(sf)).getSession(); - return session.createQuery("from java.lang.Object").list(); - } - }); - fail("Should have thrown CannotCreateTransactionException"); - } - catch (CannotCreateTransactionException ex) { - // expected - } - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - } - - @Test - public void testTransactionCommitWithPreBoundSessionAndNonExistingDatabase() throws Exception { - final DriverManagerDataSource ds = new DriverManagerDataSource(); - LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean(); - lsfb.setDataSource(ds); - Properties props = new Properties(); - props.setProperty("hibernate.dialect", HSQLDialect.class.getName()); - lsfb.setHibernateProperties(props); - lsfb.afterPropertiesSet(); - final SessionFactory sf = lsfb.getObject(); - - HibernateTransactionManager tm = new HibernateTransactionManager(); - tm.setSessionFactory(sf); - tm.afterPropertiesSet(); - TransactionTemplate tt = new TransactionTemplate(tm); - tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE); - tt.setTimeout(10); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - Session session = sf.openSession(); - TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session)); - try { - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); - Session session = ((SessionHolder) TransactionSynchronizationManager.getResource(sf)).getSession(); - return session.createQuery("from java.lang.Object").list(); - } - }); - fail("Should have thrown CannotCreateTransactionException"); - } - catch (CannotCreateTransactionException ex) { - // expected - SessionHolder holder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); - assertFalse(holder.isSynchronizedWithTransaction()); - } - finally { - TransactionSynchronizationManager.unbindResource(sf); - session.close(); - } - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - } - - @Test - public void testTransactionCommitWithNonExistingDatabaseAndLazyConnection() throws Exception { - DriverManagerDataSource dsTarget = new DriverManagerDataSource(); - final LazyConnectionDataSourceProxy ds = new LazyConnectionDataSourceProxy(); - ds.setTargetDataSource(dsTarget); - ds.setDefaultAutoCommit(true); - ds.setDefaultTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); - //ds.setDefaultTransactionIsolationName("TRANSACTION_READ_COMMITTED"); - - LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean(); - lsfb.setDataSource(ds); - Properties props = new Properties(); - props.setProperty("hibernate.dialect", HSQLDialect.class.getName()); - props.setProperty("hibernate.temp.use_jdbc_metadata_defaults", "false"); - lsfb.setHibernateProperties(props); - lsfb.afterPropertiesSet(); - final SessionFactory sf = lsfb.getObject(); - - HibernateTransactionManager tm = new HibernateTransactionManager(); - tm.setSessionFactory(sf); - tm.afterPropertiesSet(); - TransactionTemplate tt = new TransactionTemplate(tm); - tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE); - tt.setTimeout(10); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); - Session session = ((SessionHolder) TransactionSynchronizationManager.getResource(sf)).getSession(); - return session.createQuery("from java.lang.Object").list(); - } - }); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - } - - @Test - public void testTransactionFlush() throws Exception { - final SessionFactory sf = mock(SessionFactory.class); - final Session session = mock(Session.class); - Transaction tx = mock(Transaction.class); - - given(sf.openSession()).willReturn(session); - given(session.beginTransaction()).willReturn(tx); - - HibernateTransactionManager tm = new HibernateTransactionManager(sf); - tm.setPrepareConnection(false); - TransactionTemplate tt = new TransactionTemplate(tm); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - tt.execute(new TransactionCallbackWithoutResult() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); - status.flush(); - } - }); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - verify(session).flush(); - verify(tx).commit(); - verify(session).close(); - } - - @Test - public void testSetJtaTransactionManager() throws Exception { - DataSource ds = mock(DataSource.class); - TransactionManager tm = mock(TransactionManager.class); - UserTransaction ut = mock(UserTransaction.class); - TransactionSynchronizationRegistry tsr = mock(TransactionSynchronizationRegistry.class); - JtaTransactionManager jtm = new JtaTransactionManager(); - jtm.setTransactionManager(tm); - jtm.setUserTransaction(ut); - jtm.setTransactionSynchronizationRegistry(tsr); - LocalSessionFactoryBuilder lsfb = new LocalSessionFactoryBuilder(ds); - lsfb.setJtaTransactionManager(jtm); - Object jtaPlatform = lsfb.getProperties().get(AvailableSettings.JTA_PLATFORM); - assertNotNull(jtaPlatform); - assertSame(tm, jtaPlatform.getClass().getMethod("retrieveTransactionManager").invoke(jtaPlatform)); - assertSame(ut, jtaPlatform.getClass().getMethod("retrieveUserTransaction").invoke(jtaPlatform)); - assertTrue(lsfb.getProperties().get(AvailableSettings.TRANSACTION_STRATEGY) instanceof CMTTransactionFactory); - } - - @Test - public void testSetTransactionManager() throws Exception { - DataSource ds = mock(DataSource.class); - TransactionManager tm = mock(TransactionManager.class); - LocalSessionFactoryBuilder lsfb = new LocalSessionFactoryBuilder(ds); - lsfb.setJtaTransactionManager(tm); - Object jtaPlatform = lsfb.getProperties().get(AvailableSettings.JTA_PLATFORM); - assertNotNull(jtaPlatform); - assertSame(tm, jtaPlatform.getClass().getMethod("retrieveTransactionManager").invoke(jtaPlatform)); - assertTrue(lsfb.getProperties().get(AvailableSettings.TRANSACTION_STRATEGY) instanceof CMTTransactionFactory); - } - - - public interface ImplementingSession extends Session, SessionImplementor { - } - -} diff --git a/spring-orm-hibernate4/src/test/java/org/springframework/orm/jpa/jpa21/PersistenceContextTransactionTests.java b/spring-orm-hibernate4/src/test/java/org/springframework/orm/jpa/jpa21/PersistenceContextTransactionTests.java deleted file mode 100644 index 1a93a4ea74..0000000000 --- a/spring-orm-hibernate4/src/test/java/org/springframework/orm/jpa/jpa21/PersistenceContextTransactionTests.java +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright 2002-2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.jpa.jpa21; - -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.EntityTransaction; -import javax.persistence.PersistenceContext; -import javax.persistence.PersistenceContextType; -import javax.persistence.SynchronizationType; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.orm.jpa.JpaTransactionManager; -import org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.support.TransactionSynchronizationManager; -import org.springframework.transaction.support.TransactionTemplate; - -import static org.junit.Assert.*; -import static org.mockito.BDDMockito.*; - -/** - * Copy of {@link org.springframework.orm.jpa.support.PersistenceContextTransactionTests}, - * here to be tested against JPA 2.1, including unsynchronized persistence contexts. - * - * @author Juergen Hoeller - * @since 4.1.2 - */ -public class PersistenceContextTransactionTests { - - private EntityManagerFactory factory; - - private EntityManager manager; - - private EntityTransaction tx; - - private TransactionTemplate tt; - - private EntityManagerHoldingBean bean; - - - @Before - public void setUp() throws Exception { - factory = mock(EntityManagerFactory.class); - manager = mock(EntityManager.class); - tx = mock(EntityTransaction.class); - - JpaTransactionManager tm = new JpaTransactionManager(factory); - tt = new TransactionTemplate(tm); - - given(factory.createEntityManager()).willReturn(manager); - given(manager.getTransaction()).willReturn(tx); - given(manager.isOpen()).willReturn(true); - - bean = new EntityManagerHoldingBean(); - @SuppressWarnings("serial") - PersistenceAnnotationBeanPostProcessor pabpp = new PersistenceAnnotationBeanPostProcessor() { - @Override - protected EntityManagerFactory findEntityManagerFactory(String unitName, String requestingBeanName) { - return factory; - } - }; - pabpp.postProcessPropertyValues(null, null, bean, "bean"); - - assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty()); - assertFalse(TransactionSynchronizationManager.isSynchronizationActive()); - } - - @After - public void tearDown() throws Exception { - assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty()); - assertFalse(TransactionSynchronizationManager.isSynchronizationActive()); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); - } - - - @Test - public void testTransactionCommitWithSharedEntityManager() { - given(manager.getTransaction()).willReturn(tx); - - tt.execute(status -> { - bean.sharedEntityManager.flush(); - return null; - }); - - verify(tx).commit(); - verify(manager).flush(); - verify(manager).close(); - } - - @Test - public void testTransactionCommitWithSharedEntityManagerAndPropagationSupports() { - given(manager.isOpen()).willReturn(true); - - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); - - tt.execute(status -> { - bean.sharedEntityManager.clear(); - return null; - }); - - verify(manager).clear(); - verify(manager).close(); - } - - @Test - public void testTransactionCommitWithExtendedEntityManager() { - given(manager.getTransaction()).willReturn(tx); - - tt.execute(status -> { - bean.extendedEntityManager.flush(); - return null; - }); - - verify(tx, times(2)).commit(); - verify(manager).flush(); - verify(manager).close(); - } - - @Test - public void testTransactionCommitWithExtendedEntityManagerAndPropagationSupports() { - given(manager.isOpen()).willReturn(true); - - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); - - tt.execute(status -> { - bean.extendedEntityManager.flush(); - return null; - }); - - verify(manager).flush(); - } - - @Test - public void testTransactionCommitWithSharedEntityManagerUnsynchronized() { - given(manager.getTransaction()).willReturn(tx); - - tt.execute(status -> { - bean.sharedEntityManagerUnsynchronized.flush(); - return null; - }); - - verify(tx).commit(); - verify(manager).flush(); - verify(manager, times(2)).close(); - } - - @Test - public void testTransactionCommitWithSharedEntityManagerUnsynchronizedAndPropagationSupports() { - given(manager.isOpen()).willReturn(true); - - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); - - tt.execute(status -> { - bean.sharedEntityManagerUnsynchronized.clear(); - return null; - }); - - verify(manager).clear(); - verify(manager).close(); - } - - @Test - public void testTransactionCommitWithExtendedEntityManagerUnsynchronized() { - given(manager.getTransaction()).willReturn(tx); - - tt.execute(status -> { - bean.extendedEntityManagerUnsynchronized.flush(); - return null; - }); - - verify(tx).commit(); - verify(manager).flush(); - verify(manager).close(); - } - - @Test - public void testTransactionCommitWithExtendedEntityManagerUnsynchronizedAndPropagationSupports() { - given(manager.isOpen()).willReturn(true); - - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); - - tt.execute(status -> { - bean.extendedEntityManagerUnsynchronized.flush(); - return null; - }); - - verify(manager).flush(); - } - - @Test - public void testTransactionCommitWithSharedEntityManagerUnsynchronizedJoined() { - given(manager.getTransaction()).willReturn(tx); - - tt.execute(status -> { - bean.sharedEntityManagerUnsynchronized.joinTransaction(); - bean.sharedEntityManagerUnsynchronized.flush(); - return null; - }); - - verify(tx).commit(); - verify(manager).flush(); - verify(manager, times(2)).close(); - } - - @Test - public void testTransactionCommitWithExtendedEntityManagerUnsynchronizedJoined() { - given(manager.getTransaction()).willReturn(tx); - - tt.execute(status -> { - bean.extendedEntityManagerUnsynchronized.joinTransaction(); - bean.extendedEntityManagerUnsynchronized.flush(); - return null; - }); - - verify(tx, times(2)).commit(); - verify(manager).flush(); - verify(manager).close(); - } - - @Test - public void testTransactionCommitWithExtendedEntityManagerUnsynchronizedJoinedAndPropagationSupports() { - given(manager.isOpen()).willReturn(true); - - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); - - tt.execute(status -> { - bean.extendedEntityManagerUnsynchronized.joinTransaction(); - bean.extendedEntityManagerUnsynchronized.flush(); - return null; - }); - - verify(manager).flush(); - } - - - public static class EntityManagerHoldingBean { - - @PersistenceContext - public EntityManager sharedEntityManager; - - @PersistenceContext(type = PersistenceContextType.EXTENDED) - public EntityManager extendedEntityManager; - - @PersistenceContext(synchronization = SynchronizationType.UNSYNCHRONIZED) - public EntityManager sharedEntityManagerUnsynchronized; - - @PersistenceContext(type = PersistenceContextType.EXTENDED, synchronization = SynchronizationType.UNSYNCHRONIZED) - public EntityManager extendedEntityManagerUnsynchronized; - } - -} diff --git a/spring-orm-hibernate4/src/test/java/org/springframework/validation/hibernatevalidator5/BeanValidationPostProcessorTests.java b/spring-orm-hibernate4/src/test/java/org/springframework/validation/hibernatevalidator5/BeanValidationPostProcessorTests.java deleted file mode 100644 index 36837d8cad..0000000000 --- a/spring-orm-hibernate4/src/test/java/org/springframework/validation/hibernatevalidator5/BeanValidationPostProcessorTests.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright 2002-2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.validation.hibernatevalidator5; - -import javax.annotation.PostConstruct; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - -import org.junit.Test; - -import org.springframework.beans.factory.BeanCreationException; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.tests.sample.beans.TestBean; -import org.springframework.validation.beanvalidation.BeanValidationPostProcessor; - -import static org.junit.Assert.*; - -/** - * Copy of {@link org.springframework.validation.beanvalidation.BeanValidationPostProcessor}, - * here to be tested against Hibernate Validator 5. - * - * @author Juergen Hoeller - * @since 4.1 - */ -public class BeanValidationPostProcessorTests { - - @Test - public void testNotNullConstraint() { - GenericApplicationContext ac = new GenericApplicationContext(); - ac.registerBeanDefinition("bvpp", new RootBeanDefinition(BeanValidationPostProcessor.class)); - ac.registerBeanDefinition("capp", new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class)); - ac.registerBeanDefinition("bean", new RootBeanDefinition(NotNullConstrainedBean.class)); - try { - ac.refresh(); - fail("Should have thrown BeanCreationException"); - } - catch (BeanCreationException ex) { - assertTrue(ex.getRootCause().getMessage().contains("testBean")); - assertTrue(ex.getRootCause().getMessage().contains("invalid")); - } - ac.close(); - } - - @Test - public void testNotNullConstraintSatisfied() { - GenericApplicationContext ac = new GenericApplicationContext(); - ac.registerBeanDefinition("bvpp", new RootBeanDefinition(BeanValidationPostProcessor.class)); - ac.registerBeanDefinition("capp", new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class)); - RootBeanDefinition bd = new RootBeanDefinition(NotNullConstrainedBean.class); - bd.getPropertyValues().add("testBean", new TestBean()); - ac.registerBeanDefinition("bean", bd); - ac.refresh(); - ac.close(); - } - - @Test - public void testNotNullConstraintAfterInitialization() { - GenericApplicationContext ac = new GenericApplicationContext(); - RootBeanDefinition bvpp = new RootBeanDefinition(BeanValidationPostProcessor.class); - bvpp.getPropertyValues().add("afterInitialization", true); - ac.registerBeanDefinition("bvpp", bvpp); - ac.registerBeanDefinition("capp", new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class)); - ac.registerBeanDefinition("bean", new RootBeanDefinition(AfterInitConstraintBean.class)); - ac.refresh(); - ac.close(); - } - - @Test - public void testSizeConstraint() { - GenericApplicationContext ac = new GenericApplicationContext(); - ac.registerBeanDefinition("bvpp", new RootBeanDefinition(BeanValidationPostProcessor.class)); - RootBeanDefinition bd = new RootBeanDefinition(NotNullConstrainedBean.class); - bd.getPropertyValues().add("testBean", new TestBean()); - bd.getPropertyValues().add("stringValue", "s"); - ac.registerBeanDefinition("bean", bd); - try { - ac.refresh(); - fail("Should have thrown BeanCreationException"); - } - catch (BeanCreationException ex) { - assertTrue(ex.getRootCause().getMessage().contains("stringValue")); - assertTrue(ex.getRootCause().getMessage().contains("invalid")); - } - ac.close(); - } - - @Test - public void testSizeConstraintSatisfied() { - GenericApplicationContext ac = new GenericApplicationContext(); - ac.registerBeanDefinition("bvpp", new RootBeanDefinition(BeanValidationPostProcessor.class)); - RootBeanDefinition bd = new RootBeanDefinition(NotNullConstrainedBean.class); - bd.getPropertyValues().add("testBean", new TestBean()); - bd.getPropertyValues().add("stringValue", "ss"); - ac.registerBeanDefinition("bean", bd); - ac.refresh(); - ac.close(); - } - - - public static class NotNullConstrainedBean { - - @NotNull - private TestBean testBean; - - @Size(min = 2) - private String stringValue; - - public TestBean getTestBean() { - return testBean; - } - - public void setTestBean(TestBean testBean) { - this.testBean = testBean; - } - - public String getStringValue() { - return stringValue; - } - - public void setStringValue(String stringValue) { - this.stringValue = stringValue; - } - - @PostConstruct - public void init() { - assertNotNull("Shouldn't be here after constraint checking", this.testBean); - } - } - - - public static class AfterInitConstraintBean { - - @NotNull - private TestBean testBean; - - public TestBean getTestBean() { - return testBean; - } - - public void setTestBean(TestBean testBean) { - this.testBean = testBean; - } - - @PostConstruct - public void init() { - this.testBean = new TestBean(); - } - } - -} diff --git a/spring-orm-hibernate4/src/test/java/org/springframework/validation/hibernatevalidator5/MethodValidationTests.java b/spring-orm-hibernate4/src/test/java/org/springframework/validation/hibernatevalidator5/MethodValidationTests.java deleted file mode 100644 index af94ccb0af..0000000000 --- a/spring-orm-hibernate4/src/test/java/org/springframework/validation/hibernatevalidator5/MethodValidationTests.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright 2002-2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.validation.hibernatevalidator5; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import javax.validation.constraints.Max; -import javax.validation.constraints.NotNull; -import javax.validation.groups.Default; - -import org.junit.Test; - -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.beans.MutablePropertyValues; -import org.springframework.context.support.StaticApplicationContext; -import org.springframework.scheduling.annotation.Async; -import org.springframework.scheduling.annotation.AsyncAnnotationAdvisor; -import org.springframework.scheduling.annotation.AsyncAnnotationBeanPostProcessor; -import org.springframework.validation.annotation.Validated; -import org.springframework.validation.beanvalidation.MethodValidationInterceptor; -import org.springframework.validation.beanvalidation.MethodValidationPostProcessor; - -import static org.junit.Assert.*; - -/** - * Copy of {@link org.springframework.validation.beanvalidation.MethodValidationTests}, - * here to be tested against Hibernate Validator 5. - * - * @author Juergen Hoeller - * @since 4.1 - */ -@SuppressWarnings("rawtypes") -public class MethodValidationTests { - - @Test - public void testMethodValidationInterceptor() { - MyValidBean bean = new MyValidBean(); - ProxyFactory proxyFactory = new ProxyFactory(bean); - proxyFactory.addAdvice(new MethodValidationInterceptor()); - proxyFactory.addAdvisor(new AsyncAnnotationAdvisor()); - doTestProxyValidation((MyValidInterface) proxyFactory.getProxy()); - } - - @Test - public void testMethodValidationPostProcessor() { - StaticApplicationContext ac = new StaticApplicationContext(); - ac.registerSingleton("mvpp", MethodValidationPostProcessor.class); - MutablePropertyValues pvs = new MutablePropertyValues(); - pvs.add("beforeExistingAdvisors", false); - ac.registerSingleton("aapp", AsyncAnnotationBeanPostProcessor.class, pvs); - ac.registerSingleton("bean", MyValidBean.class); - ac.refresh(); - doTestProxyValidation(ac.getBean("bean", MyValidInterface.class)); - ac.close(); - } - - - @SuppressWarnings("unchecked") - private void doTestProxyValidation(MyValidInterface proxy) { - assertNotNull(proxy.myValidMethod("value", 5)); - try { - assertNotNull(proxy.myValidMethod("value", 15)); - fail("Should have thrown ValidationException"); - } - catch (javax.validation.ValidationException ex) { - // expected - } - try { - assertNotNull(proxy.myValidMethod(null, 5)); - fail("Should have thrown ValidationException"); - } - catch (javax.validation.ValidationException ex) { - // expected - } - try { - assertNotNull(proxy.myValidMethod("value", 0)); - fail("Should have thrown ValidationException"); - } - catch (javax.validation.ValidationException ex) { - // expected - } - - proxy.myValidAsyncMethod("value", 5); - try { - proxy.myValidAsyncMethod("value", 15); - fail("Should have thrown ValidationException"); - } - catch (javax.validation.ValidationException ex) { - // expected - } - try { - proxy.myValidAsyncMethod(null, 5); - fail("Should have thrown ValidationException"); - } - catch (javax.validation.ValidationException ex) { - // expected - } - - assertEquals("myValue", proxy.myGenericMethod("myValue")); - try { - proxy.myGenericMethod(null); - fail("Should have thrown ValidationException"); - } - catch (javax.validation.ValidationException ex) { - // expected - } - } - - - @MyStereotype - public static class MyValidBean implements MyValidInterface { - - @Override - public Object myValidMethod(String arg1, int arg2) { - return (arg2 == 0 ? null : "value"); - } - - @Override - public void myValidAsyncMethod(String arg1, int arg2) { - } - - @Override - public String myGenericMethod(String value) { - return value; - } - } - - - public interface MyValidInterface { - - @NotNull Object myValidMethod(@NotNull(groups = MyGroup.class) String arg1, @Max(10) int arg2); - - @MyValid - @Async void myValidAsyncMethod(@NotNull(groups = OtherGroup.class) String arg1, @Max(10) int arg2); - - T myGenericMethod(@NotNull T value); - } - - - public interface MyGroup { - } - - - public interface OtherGroup { - } - - - @Validated({MyGroup.class, Default.class}) - @Retention(RetentionPolicy.RUNTIME) - public @interface MyStereotype { - } - - - @Validated({OtherGroup.class, Default.class}) - @Retention(RetentionPolicy.RUNTIME) - public @interface MyValid { - } - -} diff --git a/spring-orm-hibernate4/src/test/java/org/springframework/validation/hibernatevalidator5/ValidatorFactoryTests.java b/spring-orm-hibernate4/src/test/java/org/springframework/validation/hibernatevalidator5/ValidatorFactoryTests.java deleted file mode 100644 index 4165836065..0000000000 --- a/spring-orm-hibernate4/src/test/java/org/springframework/validation/hibernatevalidator5/ValidatorFactoryTests.java +++ /dev/null @@ -1,430 +0,0 @@ -/* - * Copyright 2002-2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.validation.hibernatevalidator5; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.util.Arrays; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import javax.validation.Constraint; -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; -import javax.validation.ConstraintViolation; -import javax.validation.Payload; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; - -import org.hibernate.validator.HibernateValidator; -import org.junit.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.core.env.Environment; -import org.springframework.validation.BeanPropertyBindingResult; -import org.springframework.validation.Errors; -import org.springframework.validation.FieldError; -import org.springframework.validation.ObjectError; -import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; - -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; - -/** - * Copy of {@link org.springframework.validation.beanvalidation.ValidatorFactoryTests}, - * here to be tested against Hibernate Validator 5. - * - * @author Juergen Hoeller - * @since 4.1 - */ -public class ValidatorFactoryTests { - - @Test - public void testSimpleValidation() throws Exception { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.afterPropertiesSet(); - - ValidPerson person = new ValidPerson(); - Set> result = validator.validate(person); - assertEquals(2, result.size()); - for (ConstraintViolation cv : result) { - String path = cv.getPropertyPath().toString(); - if ("name".equals(path) || "address.street".equals(path)) { - assertTrue(cv.getConstraintDescriptor().getAnnotation() instanceof NotNull); - } - else { - fail("Invalid constraint violation with path '" + path + "'"); - } - } - validator.destroy(); - } - - @Test - public void testSimpleValidationWithCustomProvider() throws Exception { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.setProviderClass(HibernateValidator.class); - validator.afterPropertiesSet(); - - ValidPerson person = new ValidPerson(); - Set> result = validator.validate(person); - assertEquals(2, result.size()); - for (ConstraintViolation cv : result) { - String path = cv.getPropertyPath().toString(); - if ("name".equals(path) || "address.street".equals(path)) { - assertTrue(cv.getConstraintDescriptor().getAnnotation() instanceof NotNull); - } - else { - fail("Invalid constraint violation with path '" + path + "'"); - } - } - validator.destroy(); - } - - @Test - public void testSimpleValidationWithClassLevel() throws Exception { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.afterPropertiesSet(); - ValidPerson person = new ValidPerson(); - person.setName("Juergen"); - person.getAddress().setStreet("Juergen's Street"); - Set> result = validator.validate(person); - assertEquals(1, result.size()); - Iterator> iterator = result.iterator(); - ConstraintViolation cv = iterator.next(); - assertEquals("", cv.getPropertyPath().toString()); - assertTrue(cv.getConstraintDescriptor().getAnnotation() instanceof NameAddressValid); - } - - @Test - public void testSpringValidationFieldType() throws Exception { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.afterPropertiesSet(); - - ValidPerson person = new ValidPerson(); - person.setName("Phil"); - person.getAddress().setStreet("Phil's Street"); - BeanPropertyBindingResult errors = new BeanPropertyBindingResult(person, "person"); - validator.validate(person, errors); - assertEquals(1, errors.getErrorCount()); - assertThat("Field/Value type mismatch", errors.getFieldError("address").getRejectedValue(), - instanceOf(ValidAddress.class)); - } - - @Test - public void testSpringValidation() throws Exception { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.afterPropertiesSet(); - - ValidPerson person = new ValidPerson(); - BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); - validator.validate(person, result); - assertEquals(2, result.getErrorCount()); - FieldError fieldError = result.getFieldError("name"); - assertEquals("name", fieldError.getField()); - List errorCodes = Arrays.asList(fieldError.getCodes()); - assertEquals(4, errorCodes.size()); - assertTrue(errorCodes.contains("NotNull.person.name")); - assertTrue(errorCodes.contains("NotNull.name")); - assertTrue(errorCodes.contains("NotNull.java.lang.String")); - assertTrue(errorCodes.contains("NotNull")); - fieldError = result.getFieldError("address.street"); - assertEquals("address.street", fieldError.getField()); - errorCodes = Arrays.asList(fieldError.getCodes()); - assertEquals(5, errorCodes.size()); - assertTrue(errorCodes.contains("NotNull.person.address.street")); - assertTrue(errorCodes.contains("NotNull.address.street")); - assertTrue(errorCodes.contains("NotNull.street")); - assertTrue(errorCodes.contains("NotNull.java.lang.String")); - assertTrue(errorCodes.contains("NotNull")); - } - - @Test - public void testSpringValidationWithClassLevel() throws Exception { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.afterPropertiesSet(); - - ValidPerson person = new ValidPerson(); - person.setName("Juergen"); - person.getAddress().setStreet("Juergen's Street"); - BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); - validator.validate(person, result); - assertEquals(1, result.getErrorCount()); - ObjectError globalError = result.getGlobalError(); - List errorCodes = Arrays.asList(globalError.getCodes()); - assertEquals(2, errorCodes.size()); - assertTrue(errorCodes.contains("NameAddressValid.person")); - assertTrue(errorCodes.contains("NameAddressValid")); - } - - @Test - public void testSpringValidationWithAutowiredValidator() throws Exception { - ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext( - LocalValidatorFactoryBean.class); - LocalValidatorFactoryBean validator = ctx.getBean(LocalValidatorFactoryBean.class); - - ValidPerson person = new ValidPerson(); - person.expectsAutowiredValidator = true; - person.setName("Juergen"); - person.getAddress().setStreet("Juergen's Street"); - BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); - validator.validate(person, result); - assertEquals(1, result.getErrorCount()); - ObjectError globalError = result.getGlobalError(); - List errorCodes = Arrays.asList(globalError.getCodes()); - assertEquals(2, errorCodes.size()); - assertTrue(errorCodes.contains("NameAddressValid.person")); - assertTrue(errorCodes.contains("NameAddressValid")); - ctx.close(); - } - - @Test - public void testSpringValidationWithErrorInListElement() throws Exception { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.afterPropertiesSet(); - - ValidPerson person = new ValidPerson(); - person.getAddressList().add(new ValidAddress()); - BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); - validator.validate(person, result); - assertEquals(3, result.getErrorCount()); - FieldError fieldError = result.getFieldError("name"); - assertEquals("name", fieldError.getField()); - fieldError = result.getFieldError("address.street"); - assertEquals("address.street", fieldError.getField()); - fieldError = result.getFieldError("addressList[0].street"); - assertEquals("addressList[0].street", fieldError.getField()); - } - - @Test - public void testSpringValidationWithErrorInSetElement() throws Exception { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.afterPropertiesSet(); - - ValidPerson person = new ValidPerson(); - person.getAddressSet().add(new ValidAddress()); - BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); - validator.validate(person, result); - assertEquals(3, result.getErrorCount()); - FieldError fieldError = result.getFieldError("name"); - assertEquals("name", fieldError.getField()); - fieldError = result.getFieldError("address.street"); - assertEquals("address.street", fieldError.getField()); - fieldError = result.getFieldError("addressSet[].street"); - assertEquals("addressSet[].street", fieldError.getField()); - } - - @Test - public void testInnerBeanValidation() throws Exception { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.afterPropertiesSet(); - - MainBean mainBean = new MainBean(); - Errors errors = new BeanPropertyBindingResult(mainBean, "mainBean"); - validator.validate(mainBean, errors); - Object rejected = errors.getFieldValue("inner.value"); - assertNull(rejected); - } - - @Test - public void testValidationWithOptionalField() throws Exception { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.afterPropertiesSet(); - - MainBeanWithOptional mainBean = new MainBeanWithOptional(); - Errors errors = new BeanPropertyBindingResult(mainBean, "mainBean"); - validator.validate(mainBean, errors); - Object rejected = errors.getFieldValue("inner.value"); - assertNull(rejected); - } - - - @NameAddressValid - public static class ValidPerson { - - @NotNull - private String name; - - @Valid - private ValidAddress address = new ValidAddress(); - - @Valid - private List addressList = new LinkedList(); - - @Valid - private Set addressSet = new LinkedHashSet(); - - public boolean expectsAutowiredValidator = false; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public ValidAddress getAddress() { - return address; - } - - public void setAddress(ValidAddress address) { - this.address = address; - } - - public List getAddressList() { - return addressList; - } - - public void setAddressList(List addressList) { - this.addressList = addressList; - } - - public Set getAddressSet() { - return addressSet; - } - - public void setAddressSet(Set addressSet) { - this.addressSet = addressSet; - } - } - - - public static class ValidAddress { - - @NotNull - private String street; - - public String getStreet() { - return street; - } - - public void setStreet(String street) { - this.street = street; - } - } - - - @Target(ElementType.TYPE) - @Retention(RetentionPolicy.RUNTIME) - @Constraint(validatedBy = NameAddressValidator.class) - public @interface NameAddressValid { - - String message() default "Street must not contain name"; - - Class[] groups() default {}; - - Class[] payload() default {}; - } - - - public static class NameAddressValidator implements ConstraintValidator { - - @Autowired - private Environment environment; - - @Override - public void initialize(NameAddressValid constraintAnnotation) { - } - - @Override - public boolean isValid(ValidPerson value, ConstraintValidatorContext context) { - if (value.expectsAutowiredValidator) { - assertNotNull(this.environment); - } - boolean valid = (value.name == null || !value.address.street.contains(value.name)); - if (!valid && "Phil".equals(value.name)) { - context.buildConstraintViolationWithTemplate( - context.getDefaultConstraintMessageTemplate()).addPropertyNode("address").addConstraintViolation().disableDefaultConstraintViolation(); - } - return valid; - } - } - - - public static class MainBean { - - @InnerValid - private InnerBean inner = new InnerBean(); - - public InnerBean getInner() { - return inner; - } - } - - - public static class MainBeanWithOptional { - - @InnerValid - private InnerBean inner = new InnerBean(); - - public Optional getInner() { - return Optional.ofNullable(inner); - } - } - - - public static class InnerBean { - - private String value; - - public String getValue() { - return value; - } - public void setValue(String value) { - this.value = value; - } - } - - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.FIELD) - @Constraint(validatedBy=InnerValidator.class) - public static @interface InnerValid { - - String message() default "NOT VALID"; - - Class[] groups() default { }; - - Class[] payload() default {}; - } - - - public static class InnerValidator implements ConstraintValidator { - - @Override - public void initialize(InnerValid constraintAnnotation) { - } - - @Override - public boolean isValid(InnerBean bean, ConstraintValidatorContext context) { - context.disableDefaultConstraintViolation(); - if (bean.getValue() == null) { - context.buildConstraintViolationWithTemplate("NULL").addPropertyNode("value").addConstraintViolation(); - return false; - } - return true; - } - } - -} diff --git a/spring-orm-hibernate4/src/test/resources/log4j.properties b/spring-orm-hibernate4/src/test/resources/log4j.properties deleted file mode 100644 index 9b7421a223..0000000000 --- a/spring-orm-hibernate4/src/test/resources/log4j.properties +++ /dev/null @@ -1,10 +0,0 @@ -log4j.appender.console=org.apache.log4j.ConsoleAppender -log4j.appender.console.layout=org.apache.log4j.PatternLayout -log4j.appender.console.layout.ConversionPattern=%d{HH:mm:ss,SSS} [%c] - %m%n - -log4j.rootCategory=WARN, console -log4j.logger.org.springframework.beans=WARN -log4j.logger.org.springframework.binding=DEBUG - -#log4j.logger.org.springframework.orm.hibernate4=TRACE - diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/AbstractSessionFactoryBean.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/AbstractSessionFactoryBean.java deleted file mode 100644 index 61f731064b..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/AbstractSessionFactoryBean.java +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import javax.sql.DataSource; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.hibernate.HibernateException; -import org.hibernate.SessionFactory; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.InitializingBean; - -/** - * Abstract {@link org.springframework.beans.factory.FactoryBean} that creates - * a Hibernate {@link org.hibernate.SessionFactory} within a Spring application - * context, providing general infrastructure not related to Hibernate's - * specific configuration API. - * - *

This class implements the - * {@link org.springframework.dao.support.PersistenceExceptionTranslator} - * interface, as autodetected by Spring's - * {@link org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor}, - * for AOP-based translation of native exceptions to Spring DataAccessExceptions. - * Hence, the presence of e.g. LocalSessionFactoryBean automatically enables - * a PersistenceExceptionTranslationPostProcessor to translate Hibernate exceptions. - * - *

This class mainly serves as common base class for {@link LocalSessionFactoryBean}. - * For details on typical SessionFactory setup, see the LocalSessionFactoryBean javadoc. - * - * @author Juergen Hoeller - * @since 2.0 - * @see #setExposeTransactionAwareSessionFactory - * @see org.hibernate.SessionFactory#getCurrentSession() - * @see org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public abstract class AbstractSessionFactoryBean extends HibernateExceptionTranslator - implements FactoryBean, InitializingBean, DisposableBean { - - /** Logger available to subclasses */ - protected final Log logger = LogFactory.getLog(getClass()); - - private DataSource dataSource; - - private boolean useTransactionAwareDataSource = false; - - private boolean exposeTransactionAwareSessionFactory = true; - - private SessionFactory sessionFactory; - - - /** - * Set the DataSource to be used by the SessionFactory. - * If set, this will override corresponding settings in Hibernate properties. - *

If this is set, the Hibernate settings should not define - * a connection provider to avoid meaningless double configuration. - *

If using HibernateTransactionManager as transaction strategy, consider - * proxying your target DataSource with a LazyConnectionDataSourceProxy. - * This defers fetching of an actual JDBC Connection until the first JDBC - * Statement gets executed, even within JDBC transactions (as performed by - * HibernateTransactionManager). Such lazy fetching is particularly beneficial - * for read-only operations, in particular if the chances of resolving the - * result in the second-level cache are high. - *

As JTA and transactional JNDI DataSources already provide lazy enlistment - * of JDBC Connections, LazyConnectionDataSourceProxy does not add value with - * JTA (i.e. Spring's JtaTransactionManager) as transaction strategy. - * @see #setUseTransactionAwareDataSource - * @see HibernateTransactionManager - * @see org.springframework.transaction.jta.JtaTransactionManager - * @see org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy - */ - public void setDataSource(DataSource dataSource) { - this.dataSource = dataSource; - } - - /** - * Return the DataSource to be used by the SessionFactory. - */ - public DataSource getDataSource() { - return this.dataSource; - } - - /** - * Set whether to use a transaction-aware DataSource for the SessionFactory, - * i.e. whether to automatically wrap the passed-in DataSource with Spring's - * TransactionAwareDataSourceProxy. - *

Default is "false": LocalSessionFactoryBean is usually used with Spring's - * HibernateTransactionManager or JtaTransactionManager, both of which work nicely - * on a plain JDBC DataSource. Hibernate Sessions and their JDBC Connections are - * fully managed by the Hibernate/JTA transaction infrastructure in such a scenario. - *

If you switch this flag to "true", Spring's Hibernate access will be able to - * participate in JDBC-based transactions managed outside of Hibernate - * (for example, by Spring's DataSourceTransactionManager). This can be convenient - * if you need a different local transaction strategy for another O/R mapping tool, - * for example, but still want Hibernate access to join into those transactions. - *

A further benefit of this option is that plain Sessions opened directly - * via the SessionFactory, outside of Spring's Hibernate support, will still - * participate in active Spring-managed transactions. However, consider using - * Hibernate's {@code getCurrentSession()} method instead (see javadoc of - * "exposeTransactionAwareSessionFactory" property). - *

WARNING: When using a transaction-aware JDBC DataSource in combination - * with OpenSessionInViewFilter/Interceptor, whether participating in JTA or - * external JDBC-based transactions, it is strongly recommended to set Hibernate's - * Connection release mode to "after_transaction" or "after_statement", which - * guarantees proper Connection handling in such a scenario. In contrast to that, - * HibernateTransactionManager generally requires release mode "on_close". - *

Note: If you want to use Hibernate's Connection release mode "after_statement" - * with a DataSource specified on this LocalSessionFactoryBean (for example, a - * JTA-aware DataSource fetched from JNDI), switch this setting to "true". - * Otherwise, the ConnectionProvider used underneath will vote against aggressive - * release and thus silently switch to release mode "after_transaction". - * @see #setDataSource - * @see #setExposeTransactionAwareSessionFactory - * @see org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy - * @see org.springframework.jdbc.datasource.DataSourceTransactionManager - * @see org.springframework.orm.hibernate3.support.OpenSessionInViewFilter - * @see org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor - * @see HibernateTransactionManager - * @see org.springframework.transaction.jta.JtaTransactionManager - */ - public void setUseTransactionAwareDataSource(boolean useTransactionAwareDataSource) { - this.useTransactionAwareDataSource = useTransactionAwareDataSource; - } - - /** - * Return whether to use a transaction-aware DataSource for the SessionFactory. - */ - protected boolean isUseTransactionAwareDataSource() { - return this.useTransactionAwareDataSource; - } - - /** - * Set whether to expose a transaction-aware current Session from the - * SessionFactory's {@code getCurrentSession()} method, returning the - * Session that's associated with the current Spring-managed transaction, if any. - *

Default is "true", letting data access code work with the plain - * Hibernate SessionFactory and its {@code getCurrentSession()} method, - * while still being able to participate in current Spring-managed transactions: - * with any transaction management strategy, either local or JTA / EJB CMT, - * and any transaction synchronization mechanism, either Spring or JTA. - * Furthermore, {@code getCurrentSession()} will also seamlessly work with - * a request-scoped Session managed by OpenSessionInViewFilter/Interceptor. - *

Turn this flag off to expose the plain Hibernate SessionFactory with - * Hibernate's default {@code getCurrentSession()} behavior, supporting - * plain JTA synchronization only. Alternatively, simply override the - * corresponding Hibernate property "hibernate.current_session_context_class". - * @see SpringSessionContext - * @see org.hibernate.SessionFactory#getCurrentSession() - * @see org.springframework.transaction.jta.JtaTransactionManager - * @see HibernateTransactionManager - * @see org.springframework.orm.hibernate3.support.OpenSessionInViewFilter - * @see org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor - */ - public void setExposeTransactionAwareSessionFactory(boolean exposeTransactionAwareSessionFactory) { - this.exposeTransactionAwareSessionFactory = exposeTransactionAwareSessionFactory; - } - - /** - * Return whether to expose a transaction-aware proxy for the SessionFactory. - */ - protected boolean isExposeTransactionAwareSessionFactory() { - return this.exposeTransactionAwareSessionFactory; - } - - - /** - * Build and expose the SessionFactory. - * @see #buildSessionFactory() - * @see #wrapSessionFactoryIfNecessary - */ - @Override - public void afterPropertiesSet() throws Exception { - SessionFactory rawSf = buildSessionFactory(); - this.sessionFactory = wrapSessionFactoryIfNecessary(rawSf); - afterSessionFactoryCreation(); - } - - /** - * Wrap the given SessionFactory with a proxy, if demanded. - *

The default implementation simply returns the given SessionFactory as-is. - * Subclasses may override this to implement transaction awareness through - * a SessionFactory proxy, for example. - * @param rawSf the raw SessionFactory as built by {@link #buildSessionFactory()} - * @return the SessionFactory reference to expose - * @see #buildSessionFactory() - */ - protected SessionFactory wrapSessionFactoryIfNecessary(SessionFactory rawSf) { - return rawSf; - } - - /** - * Return the exposed SessionFactory. - * Will throw an exception if not initialized yet. - * @return the SessionFactory (never {@code null}) - * @throws IllegalStateException if the SessionFactory has not been initialized yet - */ - protected final SessionFactory getSessionFactory() { - if (this.sessionFactory == null) { - throw new IllegalStateException("SessionFactory not initialized yet"); - } - return this.sessionFactory; - } - - /** - * Close the SessionFactory on bean factory shutdown. - */ - @Override - public void destroy() throws HibernateException { - logger.info("Closing Hibernate SessionFactory"); - try { - beforeSessionFactoryDestruction(); - } - finally { - this.sessionFactory.close(); - } - } - - - /** - * Return the singleton SessionFactory. - */ - @Override - public SessionFactory getObject() { - return this.sessionFactory; - } - - @Override - public Class getObjectType() { - return (this.sessionFactory != null ? this.sessionFactory.getClass() : SessionFactory.class); - } - - @Override - public boolean isSingleton() { - return true; - } - - - /** - * Build the underlying Hibernate SessionFactory. - * @return the raw SessionFactory (potentially to be wrapped with a - * transaction-aware proxy before it is exposed to the application) - * @throws Exception in case of initialization failure - */ - protected abstract SessionFactory buildSessionFactory() throws Exception; - - /** - * Hook that allows post-processing after the SessionFactory has been - * successfully created. The SessionFactory is already available through - * {@code getSessionFactory()} at this point. - *

This implementation is empty. - * @throws Exception in case of initialization failure - * @see #getSessionFactory() - */ - protected void afterSessionFactoryCreation() throws Exception { - } - - /** - * Hook that allows shutdown processing before the SessionFactory - * will be closed. The SessionFactory is still available through - * {@code getSessionFactory()} at this point. - *

This implementation is empty. - * @see #getSessionFactory() - */ - protected void beforeSessionFactoryDestruction() { - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/FilterDefinitionFactoryBean.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/FilterDefinitionFactoryBean.java deleted file mode 100644 index 24f5c33a63..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/FilterDefinitionFactoryBean.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import java.util.HashMap; -import java.util.Map; - -import org.hibernate.engine.FilterDefinition; -import org.hibernate.type.Type; -import org.hibernate.type.TypeResolver; - -import org.springframework.beans.factory.BeanNameAware; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.InitializingBean; - -/** - * Convenient FactoryBean for defining Hibernate FilterDefinitions. - * Exposes a corresponding Hibernate FilterDefinition object. - * - *

Typically defined as an inner bean within a LocalSessionFactoryBean - * definition, as the list element for the "filterDefinitions" bean property. - * For example: - * - *

- * <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
- *   ...
- *   <property name="filterDefinitions">
- *     <list>
- *       <bean class="org.springframework.orm.hibernate3.FilterDefinitionFactoryBean">
- *         <property name="filterName" value="myFilter"/>
- *         <property name="parameterTypes">
- *           <map>
- *             <entry key="myParam" value="string"/>
- *             <entry key="myOtherParam" value="long"/>
- *           </map>
- *         </property>
- *       </bean>
- *     </list>
- *   </property>
- *   ...
- * </bean>
- * - * Alternatively, specify a bean id (or name) attribute for the inner bean, - * instead of the "filterName" property. - * - * @author Juergen Hoeller - * @since 1.2 - * @see org.hibernate.engine.FilterDefinition - * @see LocalSessionFactoryBean#setFilterDefinitions - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public class FilterDefinitionFactoryBean implements FactoryBean, BeanNameAware, InitializingBean { - - private final TypeResolver typeResolver = new TypeResolver(); - - private String filterName; - - private Map parameterTypeMap = new HashMap(); - - private String defaultFilterCondition; - - private FilterDefinition filterDefinition; - - - /** - * Set the name of the filter. - */ - public void setFilterName(String filterName) { - this.filterName = filterName; - } - - /** - * Set the parameter types for the filter, - * with parameter names as keys and type names as values. - * See {@code org.hibernate.type.TypeResolver#heuristicType(String)}. - */ - public void setParameterTypes(Map parameterTypes) { - if (parameterTypes != null) { - this.parameterTypeMap = new HashMap(parameterTypes.size()); - for (Map.Entry entry : parameterTypes.entrySet()) { - this.parameterTypeMap.put(entry.getKey(), this.typeResolver.heuristicType(entry.getValue())); - } - } - else { - this.parameterTypeMap = new HashMap(); - } - } - - /** - * Specify a default filter condition for the filter, if any. - */ - public void setDefaultFilterCondition(String defaultFilterCondition) { - this.defaultFilterCondition = defaultFilterCondition; - } - - /** - * If no explicit filter name has been specified, the bean name of - * the FilterDefinitionFactoryBean will be used. - * @see #setFilterName - */ - @Override - public void setBeanName(String name) { - if (this.filterName == null) { - this.filterName = name; - } - } - - @Override - public void afterPropertiesSet() { - this.filterDefinition = - new FilterDefinition(this.filterName, this.defaultFilterCondition, this.parameterTypeMap); - } - - - @Override - public FilterDefinition getObject() { - return this.filterDefinition; - } - - @Override - public Class getObjectType() { - return FilterDefinition.class; - } - - @Override - public boolean isSingleton() { - return true; - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateAccessor.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateAccessor.java deleted file mode 100644 index 8b5dc6647d..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateAccessor.java +++ /dev/null @@ -1,492 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import java.sql.SQLException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.hibernate.FlushMode; -import org.hibernate.HibernateException; -import org.hibernate.Interceptor; -import org.hibernate.JDBCException; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.exception.GenericJDBCException; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.core.Constants; -import org.springframework.dao.DataAccessException; -import org.springframework.jdbc.support.SQLExceptionTranslator; - -/** - * Base class for {@link HibernateTemplate} and {@link HibernateInterceptor}, - * defining common properties such as SessionFactory and flushing behavior. - * - *

Not intended to be used directly. - * See {@link HibernateTemplate} and {@link HibernateInterceptor}. - * - * @author Juergen Hoeller - * @since 1.2 - * @see HibernateTemplate - * @see HibernateInterceptor - * @see #setFlushMode - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public abstract class HibernateAccessor implements InitializingBean, BeanFactoryAware { - - /** - * Never flush is a good strategy for read-only units of work. - * Hibernate will not track and look for changes in this case, - * avoiding any overhead of modification detection. - *

In case of an existing Session, FLUSH_NEVER will turn the flush mode - * to NEVER for the scope of the current operation, resetting the previous - * flush mode afterwards. - * @see #setFlushMode - */ - public static final int FLUSH_NEVER = 0; - - /** - * Automatic flushing is the default mode for a Hibernate Session. - * A session will get flushed on transaction commit, and on certain find - * operations that might involve already modified instances, but not - * after each unit of work like with eager flushing. - *

In case of an existing Session, FLUSH_AUTO will participate in the - * existing flush mode, not modifying it for the current operation. - * This in particular means that this setting will not modify an existing - * flush mode NEVER, in contrast to FLUSH_EAGER. - * @see #setFlushMode - */ - public static final int FLUSH_AUTO = 1; - - /** - * Eager flushing leads to immediate synchronization with the database, - * even if in a transaction. This causes inconsistencies to show up and throw - * a respective exception immediately, and JDBC access code that participates - * in the same transaction will see the changes as the database is already - * aware of them then. But the drawbacks are: - *

    - *
  • additional communication roundtrips with the database, instead of a - * single batch at transaction commit; - *
  • the fact that an actual database rollback is needed if the Hibernate - * transaction rolls back (due to already submitted SQL statements). - *
- *

In case of an existing Session, FLUSH_EAGER will turn the flush mode - * to AUTO for the scope of the current operation and issue a flush at the - * end, resetting the previous flush mode afterwards. - * @see #setFlushMode - */ - public static final int FLUSH_EAGER = 2; - - /** - * Flushing at commit only is intended for units of work where no - * intermediate flushing is desired, not even for find operations - * that might involve already modified instances. - *

In case of an existing Session, FLUSH_COMMIT will turn the flush mode - * to COMMIT for the scope of the current operation, resetting the previous - * flush mode afterwards. The only exception is an existing flush mode - * NEVER, which will not be modified through this setting. - * @see #setFlushMode - */ - public static final int FLUSH_COMMIT = 3; - - /** - * Flushing before every query statement is rarely necessary. - * It is only available for special needs. - *

In case of an existing Session, FLUSH_ALWAYS will turn the flush mode - * to ALWAYS for the scope of the current operation, resetting the previous - * flush mode afterwards. - * @see #setFlushMode - */ - public static final int FLUSH_ALWAYS = 4; - - - /** Constants instance for HibernateAccessor */ - private static final Constants constants = new Constants(HibernateAccessor.class); - - /** Logger available to subclasses */ - protected final Log logger = LogFactory.getLog(getClass()); - - private SessionFactory sessionFactory; - - private Object entityInterceptor; - - private SQLExceptionTranslator jdbcExceptionTranslator; - - private SQLExceptionTranslator defaultJdbcExceptionTranslator; - - private int flushMode = FLUSH_AUTO; - - private String[] filterNames; - - /** - * Just needed for entityInterceptorBeanName. - * @see #setEntityInterceptorBeanName - */ - private BeanFactory beanFactory; - - - /** - * Set the Hibernate SessionFactory that should be used to create - * Hibernate Sessions. - */ - public void setSessionFactory(SessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; - } - - /** - * Return the Hibernate SessionFactory that should be used to create - * Hibernate Sessions. - */ - public SessionFactory getSessionFactory() { - return this.sessionFactory; - } - - /** - * Set the bean name of a Hibernate entity interceptor that allows to inspect - * and change property values before writing to and reading from the database. - * Will get applied to any new Session created by this transaction manager. - *

Requires the bean factory to be known, to be able to resolve the bean - * name to an interceptor instance on session creation. Typically used for - * prototype interceptors, i.e. a new interceptor instance per session. - *

Can also be used for shared interceptor instances, but it is recommended - * to set the interceptor reference directly in such a scenario. - * @param entityInterceptorBeanName the name of the entity interceptor in - * the bean factory - * @see #setBeanFactory - * @see #setEntityInterceptor - */ - public void setEntityInterceptorBeanName(String entityInterceptorBeanName) { - this.entityInterceptor = entityInterceptorBeanName; - } - - /** - * Set a Hibernate entity interceptor that allows to inspect and change - * property values before writing to and reading from the database. - * Will get applied to any new Session created by this object. - *

Such an interceptor can either be set at the SessionFactory level, - * i.e. on LocalSessionFactoryBean, or at the Session level, i.e. on - * HibernateTemplate, HibernateInterceptor, and HibernateTransactionManager. - * It's preferable to set it on LocalSessionFactoryBean or HibernateTransactionManager - * to avoid repeated configuration and guarantee consistent behavior in transactions. - * @see #setEntityInterceptorBeanName - * @see LocalSessionFactoryBean#setEntityInterceptor - * @see HibernateTransactionManager#setEntityInterceptor - */ - public void setEntityInterceptor(Interceptor entityInterceptor) { - this.entityInterceptor = entityInterceptor; - } - - /** - * Return the current Hibernate entity interceptor, or {@code null} if none. - * Resolves an entity interceptor bean name via the bean factory, - * if necessary. - * @throws IllegalStateException if bean name specified but no bean factory set - * @throws org.springframework.beans.BeansException if bean name resolution via the bean factory failed - * @see #setEntityInterceptor - * @see #setEntityInterceptorBeanName - * @see #setBeanFactory - */ - public Interceptor getEntityInterceptor() throws IllegalStateException, BeansException { - if (this.entityInterceptor instanceof String) { - if (this.beanFactory == null) { - throw new IllegalStateException("Cannot get entity interceptor via bean name if no bean factory set"); - } - return this.beanFactory.getBean((String) this.entityInterceptor, Interceptor.class); - } - return (Interceptor) this.entityInterceptor; - } - - /** - * Set the JDBC exception translator for this instance. - *

Applied to any SQLException root cause of a Hibernate JDBCException, - * overriding Hibernate's default SQLException translation (which is - * based on Hibernate's Dialect for a specific target database). - * @param jdbcExceptionTranslator the exception translator - * @see java.sql.SQLException - * @see org.hibernate.JDBCException - * @see org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator - * @see org.springframework.jdbc.support.SQLStateSQLExceptionTranslator - */ - public void setJdbcExceptionTranslator(SQLExceptionTranslator jdbcExceptionTranslator) { - this.jdbcExceptionTranslator = jdbcExceptionTranslator; - } - - /** - * Return the JDBC exception translator for this instance, if any. - */ - public SQLExceptionTranslator getJdbcExceptionTranslator() { - return this.jdbcExceptionTranslator; - } - - /** - * Set the flush behavior by the name of the respective constant - * in this class, e.g. "FLUSH_AUTO". Default is "FLUSH_AUTO". - * @param constantName name of the constant - * @see #setFlushMode - * @see #FLUSH_AUTO - */ - public void setFlushModeName(String constantName) { - setFlushMode(constants.asNumber(constantName).intValue()); - } - - /** - * Set the flush behavior to one of the constants in this class. - * Default is FLUSH_AUTO. - * @see #setFlushModeName - * @see #FLUSH_AUTO - */ - public void setFlushMode(int flushMode) { - this.flushMode = flushMode; - } - - /** - * Return if a flush should be forced after executing the callback code. - */ - public int getFlushMode() { - return this.flushMode; - } - - /** - * Set the name of a Hibernate filter to be activated for all - * Sessions that this accessor works with. - *

This filter will be enabled at the beginning of each operation - * and correspondingly disabled at the end of the operation. - * This will work for newly opened Sessions as well as for existing - * Sessions (for example, within a transaction). - * @see #enableFilters(org.hibernate.Session) - * @see org.hibernate.Session#enableFilter(String) - * @see LocalSessionFactoryBean#setFilterDefinitions - */ - public void setFilterName(String filter) { - this.filterNames = new String[] {filter}; - } - - /** - * Set one or more names of Hibernate filters to be activated for all - * Sessions that this accessor works with. - *

Each of those filters will be enabled at the beginning of each - * operation and correspondingly disabled at the end of the operation. - * This will work for newly opened Sessions as well as for existing - * Sessions (for example, within a transaction). - * @see #enableFilters(org.hibernate.Session) - * @see org.hibernate.Session#enableFilter(String) - * @see LocalSessionFactoryBean#setFilterDefinitions - */ - public void setFilterNames(String... filterNames) { - this.filterNames = filterNames; - } - - /** - * Return the names of Hibernate filters to be activated, if any. - */ - public String[] getFilterNames() { - return this.filterNames; - } - - /** - * The bean factory just needs to be known for resolving entity interceptor - * bean names. It does not need to be set for any other mode of operation. - * @see #setEntityInterceptorBeanName - */ - @Override - public void setBeanFactory(BeanFactory beanFactory) { - this.beanFactory = beanFactory; - } - - @Override - public void afterPropertiesSet() { - if (getSessionFactory() == null) { - throw new IllegalArgumentException("Property 'sessionFactory' is required"); - } - } - - - /** - * Apply the flush mode that's been specified for this accessor - * to the given Session. - * @param session the current Hibernate Session - * @param existingTransaction if executing within an existing transaction - * @return the previous flush mode to restore after the operation, - * or {@code null} if none - * @see #setFlushMode - * @see org.hibernate.Session#setFlushMode - */ - protected FlushMode applyFlushMode(Session session, boolean existingTransaction) { - if (getFlushMode() == FLUSH_NEVER) { - if (existingTransaction) { - FlushMode previousFlushMode = session.getFlushMode(); - if (!previousFlushMode.lessThan(FlushMode.COMMIT)) { - session.setFlushMode(FlushMode.MANUAL); - return previousFlushMode; - } - } - else { - session.setFlushMode(FlushMode.MANUAL); - } - } - else if (getFlushMode() == FLUSH_EAGER) { - if (existingTransaction) { - FlushMode previousFlushMode = session.getFlushMode(); - if (!previousFlushMode.equals(FlushMode.AUTO)) { - session.setFlushMode(FlushMode.AUTO); - return previousFlushMode; - } - } - else { - // rely on default FlushMode.AUTO - } - } - else if (getFlushMode() == FLUSH_COMMIT) { - if (existingTransaction) { - FlushMode previousFlushMode = session.getFlushMode(); - if (previousFlushMode.equals(FlushMode.AUTO) || previousFlushMode.equals(FlushMode.ALWAYS)) { - session.setFlushMode(FlushMode.COMMIT); - return previousFlushMode; - } - } - else { - session.setFlushMode(FlushMode.COMMIT); - } - } - else if (getFlushMode() == FLUSH_ALWAYS) { - if (existingTransaction) { - FlushMode previousFlushMode = session.getFlushMode(); - if (!previousFlushMode.equals(FlushMode.ALWAYS)) { - session.setFlushMode(FlushMode.ALWAYS); - return previousFlushMode; - } - } - else { - session.setFlushMode(FlushMode.ALWAYS); - } - } - return null; - } - - /** - * Flush the given Hibernate Session if necessary. - * @param session the current Hibernate Session - * @param existingTransaction if executing within an existing transaction - * @throws HibernateException in case of Hibernate flushing errors - */ - protected void flushIfNecessary(Session session, boolean existingTransaction) throws HibernateException { - if (getFlushMode() == FLUSH_EAGER || (!existingTransaction && getFlushMode() != FLUSH_NEVER)) { - logger.debug("Eagerly flushing Hibernate session"); - session.flush(); - } - } - - - /** - * Convert the given HibernateException to an appropriate exception - * from the {@code org.springframework.dao} hierarchy. - *

Will automatically apply a specified SQLExceptionTranslator to a - * Hibernate JDBCException, else rely on Hibernate's default translation. - * @param ex HibernateException that occured - * @return a corresponding DataAccessException - * @see SessionFactoryUtils#convertHibernateAccessException - * @see #setJdbcExceptionTranslator - */ - public DataAccessException convertHibernateAccessException(HibernateException ex) { - if (getJdbcExceptionTranslator() != null && ex instanceof JDBCException) { - return convertJdbcAccessException((JDBCException) ex, getJdbcExceptionTranslator()); - } - else if (GenericJDBCException.class == ex.getClass()) { - return convertJdbcAccessException((GenericJDBCException) ex, getDefaultJdbcExceptionTranslator()); - } - return SessionFactoryUtils.convertHibernateAccessException(ex); - } - - /** - * Convert the given Hibernate JDBCException to an appropriate exception - * from the {@code org.springframework.dao} hierarchy, using the - * given SQLExceptionTranslator. - * @param ex Hibernate JDBCException that occured - * @param translator the SQLExceptionTranslator to use - * @return a corresponding DataAccessException - */ - protected DataAccessException convertJdbcAccessException(JDBCException ex, SQLExceptionTranslator translator) { - return translator.translate("Hibernate operation: " + ex.getMessage(), ex.getSQL(), ex.getSQLException()); - } - - /** - * Convert the given SQLException to an appropriate exception from the - * {@code org.springframework.dao} hierarchy. Can be overridden in subclasses. - *

Note that a direct SQLException can just occur when callback code - * performs direct JDBC access via {@code Session.connection()}. - * @param ex the SQLException - * @return the corresponding DataAccessException instance - * @see #setJdbcExceptionTranslator - */ - protected DataAccessException convertJdbcAccessException(SQLException ex) { - SQLExceptionTranslator translator = getJdbcExceptionTranslator(); - if (translator == null) { - translator = getDefaultJdbcExceptionTranslator(); - } - return translator.translate("Hibernate-related JDBC operation", null, ex); - } - - /** - * Obtain a default SQLExceptionTranslator, lazily creating it if necessary. - *

Creates a default - * {@link org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator} - * for the SessionFactory's underlying DataSource. - */ - protected synchronized SQLExceptionTranslator getDefaultJdbcExceptionTranslator() { - if (this.defaultJdbcExceptionTranslator == null) { - this.defaultJdbcExceptionTranslator = SessionFactoryUtils.newJdbcExceptionTranslator(getSessionFactory()); - } - return this.defaultJdbcExceptionTranslator; - } - - - /** - * Enable the specified filters on the given Session. - * @param session the current Hibernate Session - * @see #setFilterNames - * @see org.hibernate.Session#enableFilter(String) - */ - protected void enableFilters(Session session) { - String[] filterNames = getFilterNames(); - if (filterNames != null) { - for (String filterName : filterNames) { - session.enableFilter(filterName); - } - } - } - - /** - * Disable the specified filters on the given Session. - * @param session the current Hibernate Session - * @see #setFilterNames - * @see org.hibernate.Session#disableFilter(String) - */ - protected void disableFilters(Session session) { - String[] filterNames = getFilterNames(); - if (filterNames != null) { - for (String filterName : filterNames) { - session.disableFilter(filterName); - } - } - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateCallback.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateCallback.java deleted file mode 100644 index db081638d9..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateCallback.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2002-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import java.sql.SQLException; - -import org.hibernate.HibernateException; -import org.hibernate.Session; - -/** - * Callback interface for Hibernate code. To be used with {@link HibernateTemplate}'s - * execution methods, often as anonymous classes within a method implementation. - * A typical implementation will call {@code Session.load/find/update} to perform - * some operations on persistent objects. It can also perform direct JDBC operations - * via Hibernate's {@code Session.connection()}, operating on a JDBC Connection. - * - *

Note that Hibernate works on unmodified plain Java objects, performing dirty - * detection via copies made at load time. Returned objects can thus be used outside - * of an active Hibernate Session without any hassle, e.g. for display in a web GUI. - * Reassociating such instances with a new Session, e.g. for updates when coming - * back from the GUI, is straightforward, as the instance has kept its identity. - * You should care to reassociate them as early as possible though, to avoid having - * already loaded a version from the database in the same Session. - * - * @author Juergen Hoeller - * @since 1.2 - * @see HibernateTemplate - * @see HibernateTransactionManager - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public interface HibernateCallback { - - /** - * Gets called by {@code HibernateTemplate.execute} with an active - * Hibernate {@code Session}. Does not need to care about activating - * or closing the {@code Session}, or handling transactions. - *

If called without a thread-bound Hibernate transaction (initiated - * by HibernateTransactionManager), the code will simply get executed on the - * underlying JDBC connection with its transactional semantics. If Hibernate - * is configured to use a JTA-aware DataSource, the JDBC connection and thus - * the callback code will be transactional if a JTA transaction is active. - *

Allows for returning a result object created within the callback, - * i.e. a domain object or a collection of domain objects. - * A thrown custom RuntimeException is treated as an application exception: - * It gets propagated to the caller of the template. - * @param session active Hibernate session - * @return a result object, or {@code null} if none - * @throws HibernateException if thrown by the Hibernate API - * @throws SQLException if thrown by Hibernate-exposed JDBC API - * @see HibernateTemplate#execute - * @see HibernateTemplate#executeFind - */ - T doInHibernate(Session session) throws HibernateException, SQLException; - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateExceptionTranslator.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateExceptionTranslator.java deleted file mode 100644 index db7401743b..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateExceptionTranslator.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import org.hibernate.HibernateException; -import org.hibernate.JDBCException; - -import org.springframework.dao.DataAccessException; -import org.springframework.dao.support.PersistenceExceptionTranslator; -import org.springframework.jdbc.support.SQLExceptionTranslator; - -/** - * {@link PersistenceExceptionTranslator} capable of translating {@link HibernateException} - * instances to Spring's {@link DataAccessException} hierarchy. - * - *

Extended by {@link LocalSessionFactoryBean}, so there is no need to declare this - * translator in addition to a {@code LocalSessionFactoryBean}. - * - *

When configuring the container with {@code @Configuration} classes, a {@code @Bean} - * of this type must be registered manually. - * - * @author Juergen Hoeller - * @author Chris Beams - * @since 3.1 - * @see org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor - * @see SessionFactoryUtils#convertHibernateAccessException(HibernateException) - * @see SQLExceptionTranslator - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public class HibernateExceptionTranslator implements PersistenceExceptionTranslator { - - private SQLExceptionTranslator jdbcExceptionTranslator; - - - /** - * Set the JDBC exception translator for the SessionFactory, - * exposed via the PersistenceExceptionTranslator interface. - *

Applied to any SQLException root cause of a Hibernate JDBCException, - * overriding Hibernate's default SQLException translation (which is - * based on Hibernate's Dialect for a specific target database). - * @param jdbcExceptionTranslator the exception translator - * @see java.sql.SQLException - * @see org.hibernate.JDBCException - * @see org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator - * @see org.springframework.jdbc.support.SQLStateSQLExceptionTranslator - * @see org.springframework.dao.support.PersistenceExceptionTranslator - */ - public void setJdbcExceptionTranslator(SQLExceptionTranslator jdbcExceptionTranslator) { - this.jdbcExceptionTranslator = jdbcExceptionTranslator; - } - - - @Override - public DataAccessException translateExceptionIfPossible(RuntimeException ex) { - if (ex instanceof HibernateException) { - return convertHibernateAccessException((HibernateException) ex); - } - return null; - } - - /** - * Convert the given HibernateException to an appropriate exception from the - * {@code org.springframework.dao} hierarchy. - *

Will automatically apply a specified SQLExceptionTranslator to a - * Hibernate JDBCException, else rely on Hibernate's default translation. - * @param ex HibernateException that occured - * @return a corresponding DataAccessException - * @see SessionFactoryUtils#convertHibernateAccessException - * @see #setJdbcExceptionTranslator - */ - protected DataAccessException convertHibernateAccessException(HibernateException ex) { - if (this.jdbcExceptionTranslator != null && ex instanceof JDBCException) { - JDBCException jdbcEx = (JDBCException) ex; - return this.jdbcExceptionTranslator.translate( - "Hibernate operation: " + jdbcEx.getMessage(), jdbcEx.getSQL(), jdbcEx.getSQLException()); - } - return SessionFactoryUtils.convertHibernateAccessException(ex); - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateInterceptor.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateInterceptor.java deleted file mode 100644 index 8feba6af36..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateInterceptor.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import org.aopalliance.intercept.MethodInterceptor; -import org.aopalliance.intercept.MethodInvocation; -import org.hibernate.FlushMode; -import org.hibernate.HibernateException; -import org.hibernate.Session; - -import org.springframework.transaction.support.TransactionSynchronizationManager; - -/** - * This interceptor binds a new Hibernate Session to the thread before a method - * call, closing and removing it afterwards in case of any method outcome. - * If there already is a pre-bound Session (e.g. from HibernateTransactionManager, - * or from a surrounding Hibernate-intercepted method), the interceptor simply - * participates in it. - * - *

Application code must retrieve a Hibernate Session via the - * {@code SessionFactoryUtils.getSession} method or - preferably - - * Hibernate's own {@code SessionFactory.getCurrentSession()} method, to be - * able to detect a thread-bound Session. Typically, the code will look like as follows: - * - *

- * public void doSomeDataAccessAction() {
- *   Session session = this.sessionFactory.getCurrentSession();
- *   ...
- *   // No need to close the Session or translate exceptions!
- * }
- * - * Note that this interceptor automatically translates HibernateExceptions, - * via delegating to the {@code SessionFactoryUtils.convertHibernateAccessException} - * method that converts them to exceptions that are compatible with the - * {@code org.springframework.dao} exception hierarchy (like HibernateTemplate does). - * This can be turned off if the raw exceptions are preferred. - * - *

This class can be considered a declarative alternative to HibernateTemplate's - * callback approach. The advantages are: - *

    - *
  • no anonymous classes necessary for callback implementations; - *
  • the possibility to throw any application exceptions from within data access code. - *
- * - *

The drawback is the dependency on interceptor configuration. However, note - * that this interceptor is usually not necessary in scenarios where the - * data access code always executes within transactions. A transaction will always - * have a thread-bound Session in the first place, so adding this interceptor to the - * configuration just adds value when fine-tuning Session settings like the flush mode - * - or when relying on exception translation. - * - * @author Juergen Hoeller - * @since 1.2 - * @see org.hibernate.SessionFactory#getCurrentSession() - * @see HibernateTransactionManager - * @see HibernateTemplate - * @deprecated as of Spring 3.2.7, in favor of either HibernateTemplate usage or - * native Hibernate API usage within transactions, in combination with a general - * {@link org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor}. - * Note: This class does not have an equivalent replacement in {@code orm.hibernate4}. - * If you desperately need a scoped Session bound through AOP, consider the newly - * introduced {@link org.springframework.orm.hibernate3.support.OpenSessionInterceptor}. - */ -@Deprecated -public class HibernateInterceptor extends HibernateAccessor implements MethodInterceptor { - - private boolean exceptionConversionEnabled = true; - - - /** - * Set whether to convert any HibernateException raised to a Spring DataAccessException, - * compatible with the {@code org.springframework.dao} exception hierarchy. - *

Default is "true". Turn this flag off to let the caller receive raw exceptions - * as-is, without any wrapping. - * @see org.springframework.dao.DataAccessException - */ - public void setExceptionConversionEnabled(boolean exceptionConversionEnabled) { - this.exceptionConversionEnabled = exceptionConversionEnabled; - } - - - @Override - public Object invoke(MethodInvocation methodInvocation) throws Throwable { - Session session = getSession(); - SessionHolder sessionHolder = - (SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory()); - - boolean existingTransaction = (sessionHolder != null && sessionHolder.containsSession(session)); - if (existingTransaction) { - logger.debug("Found thread-bound Session for HibernateInterceptor"); - } - else { - if (sessionHolder != null) { - sessionHolder.addSession(session); - } - else { - TransactionSynchronizationManager.bindResource(getSessionFactory(), new SessionHolder(session)); - } - } - - FlushMode previousFlushMode = null; - try { - previousFlushMode = applyFlushMode(session, existingTransaction); - enableFilters(session); - Object retVal = methodInvocation.proceed(); - flushIfNecessary(session, existingTransaction); - return retVal; - } - catch (HibernateException ex) { - if (this.exceptionConversionEnabled) { - throw convertHibernateAccessException(ex); - } - else { - throw ex; - } - } - finally { - if (existingTransaction) { - logger.debug("Not closing pre-bound Hibernate Session after HibernateInterceptor"); - disableFilters(session); - if (previousFlushMode != null) { - session.setFlushMode(previousFlushMode); - } - } - else { - SessionFactoryUtils.closeSessionOrRegisterDeferredClose(session, getSessionFactory()); - if (sessionHolder == null || sessionHolder.doesNotHoldNonDefaultSession()) { - TransactionSynchronizationManager.unbindResource(getSessionFactory()); - } - } - } - } - - /** - * Return a Session for use by this interceptor. - * @see SessionFactoryUtils#getSession - */ - protected Session getSession() { - return SessionFactoryUtils.getSession( - getSessionFactory(), getEntityInterceptor(), getJdbcExceptionTranslator()); - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateJdbcException.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateJdbcException.java deleted file mode 100644 index 24af697090..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateJdbcException.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import java.sql.SQLException; - -import org.hibernate.JDBCException; - -import org.springframework.dao.UncategorizedDataAccessException; - -/** - * Hibernate-specific subclass of UncategorizedDataAccessException, - * for JDBC exceptions that Hibernate wrapped. - * - * @author Juergen Hoeller - * @since 1.2 - * @see SessionFactoryUtils#convertHibernateAccessException - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -@SuppressWarnings("serial") -public class HibernateJdbcException extends UncategorizedDataAccessException { - - public HibernateJdbcException(JDBCException ex) { - super("JDBC exception on Hibernate data access: SQLException for SQL [" + ex.getSQL() + "]; SQL state [" + - ex.getSQLState() + "]; error code [" + ex.getErrorCode() + "]; " + ex.getMessage(), ex); - } - - /** - * Return the underlying SQLException. - */ - public SQLException getSQLException() { - return ((JDBCException) getCause()).getSQLException(); - } - - /** - * Return the SQL that led to the problem. - */ - public String getSql() { - return ((JDBCException) getCause()).getSQL(); - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateObjectRetrievalFailureException.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateObjectRetrievalFailureException.java deleted file mode 100644 index 9a4cdf9a2e..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateObjectRetrievalFailureException.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import org.hibernate.UnresolvableObjectException; -import org.hibernate.WrongClassException; - -import org.springframework.orm.ObjectRetrievalFailureException; - -/** - * Hibernate-specific subclass of ObjectRetrievalFailureException. - * Converts Hibernate's UnresolvableObjectException and WrongClassException. - * - * @author Juergen Hoeller - * @since 1.2 - * @see SessionFactoryUtils#convertHibernateAccessException - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -@SuppressWarnings("serial") -public class HibernateObjectRetrievalFailureException extends ObjectRetrievalFailureException { - - public HibernateObjectRetrievalFailureException(UnresolvableObjectException ex) { - super(ex.getEntityName(), ex.getIdentifier(), ex.getMessage(), ex); - } - - public HibernateObjectRetrievalFailureException(WrongClassException ex) { - super(ex.getEntityName(), ex.getIdentifier(), ex.getMessage(), ex); - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateOperations.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateOperations.java deleted file mode 100644 index 6facdbec07..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateOperations.java +++ /dev/null @@ -1,921 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import java.io.Serializable; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; - -import org.hibernate.Filter; -import org.hibernate.LockMode; -import org.hibernate.ReplicationMode; -import org.hibernate.criterion.DetachedCriteria; - -import org.springframework.dao.DataAccessException; - -/** - * Interface that specifies a basic set of Hibernate operations, - * implemented by {@link HibernateTemplate}. Not often used, but a useful - * option to enhance testability, as it can easily be mocked or stubbed. - * - *

Defines {@code HibernateTemplate}'s data access methods that - * mirror various {@link org.hibernate.Session} methods. Users are - * strongly encouraged to read the Hibernate {@code Session} javadocs - * for details on the semantics of those methods. - * - *

Note that operations that return an {@link java.util.Iterator} (i.e. - * {@code iterate(..)}) are supposed to be used within Spring-driven - * or JTA-driven transactions (with {@link HibernateTransactionManager}, - * {@link org.springframework.transaction.jta.JtaTransactionManager}, - * or EJB CMT). Else, the {@code Iterator} won't be able to read - * results from its {@link java.sql.ResultSet} anymore, as the underlying - * Hibernate {@code Session} will already have been closed. - * - *

Note that lazy loading will just work with an open Hibernate - * {@code Session}, either within a transaction or within - * {@link org.springframework.orm.hibernate3.support.OpenSessionInViewFilter}/ - * {@link org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor}. - * Furthermore, some operations just make sense within transactions, - * for example: {@code contains}, {@code evict}, {@code lock}, - * {@code flush}, {@code clear}. - * - * @author Juergen Hoeller - * @since 1.2 - * @see HibernateTemplate - * @see org.hibernate.Session - * @see HibernateTransactionManager - * @see org.springframework.transaction.jta.JtaTransactionManager - * @see org.springframework.orm.hibernate3.support.OpenSessionInViewFilter - * @see org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public interface HibernateOperations { - - /** - * Execute the action specified by the given action object within a - * {@link org.hibernate.Session}. - *

Application exceptions thrown by the action object get propagated - * to the caller (can only be unchecked). Hibernate exceptions are - * transformed into appropriate DAO ones. Allows for returning a result - * object, that is a domain object or a collection of domain objects. - *

Note: Callback code is not supposed to handle transactions itself! - * Use an appropriate transaction manager like - * {@link HibernateTransactionManager}. Generally, callback code must not - * touch any {@code Session} lifecycle methods, like close, - * disconnect, or reconnect, to let the template do its work. - * @param action callback object that specifies the Hibernate action - * @return a result object returned by the action, or {@code null} - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see HibernateTransactionManager - * @see org.hibernate.Session - */ - T execute(HibernateCallback action) throws DataAccessException; - - /** - * Execute the specified action assuming that the result object is a - * {@link List}. - *

This is a convenience method for executing Hibernate find calls or - * queries within an action. - * @param action callback object that specifies the Hibernate action - * @return a List result returned by the action, or {@code null} - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @deprecated as of Spring 3.2.7, in favor of using a regular {@link #execute} - * call with a generic List type declared - */ - @Deprecated - List executeFind(HibernateCallback action) throws DataAccessException; - - - //------------------------------------------------------------------------- - // Convenience methods for loading individual objects - //------------------------------------------------------------------------- - - /** - * Return the persistent instance of the given entity class - * with the given identifier, or {@code null} if not found. - *

This method is a thin wrapper around - * {@link org.hibernate.Session#get(Class, java.io.Serializable)} for convenience. - * For an explanation of the exact semantics of this method, please do refer to - * the Hibernate API documentation in the first instance. - * @param entityClass a persistent class - * @param id the identifier of the persistent instance - * @return the persistent instance, or {@code null} if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#get(Class, java.io.Serializable) - */ - T get(Class entityClass, Serializable id) throws DataAccessException; - - /** - * Return the persistent instance of the given entity class - * with the given identifier, or {@code null} if not found. - *

Obtains the specified lock mode if the instance exists. - *

This method is a thin wrapper around - * {@link org.hibernate.Session#get(Class, java.io.Serializable, LockMode)} for convenience. - * For an explanation of the exact semantics of this method, please do refer to - * the Hibernate API documentation in the first instance. - * @param entityClass a persistent class - * @param id the identifier of the persistent instance - * @param lockMode the lock mode to obtain - * @return the persistent instance, or {@code null} if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#get(Class, java.io.Serializable, org.hibernate.LockMode) - */ - T get(Class entityClass, Serializable id, LockMode lockMode) throws DataAccessException; - - /** - * Return the persistent instance of the given entity class - * with the given identifier, or {@code null} if not found. - *

This method is a thin wrapper around - * {@link org.hibernate.Session#get(String, java.io.Serializable)} for convenience. - * For an explanation of the exact semantics of this method, please do refer to - * the Hibernate API documentation in the first instance. - * @param entityName the name of the persistent entity - * @param id the identifier of the persistent instance - * @return the persistent instance, or {@code null} if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#get(Class, java.io.Serializable) - */ - Object get(String entityName, Serializable id) throws DataAccessException; - - /** - * Return the persistent instance of the given entity class - * with the given identifier, or {@code null} if not found. - * Obtains the specified lock mode if the instance exists. - *

This method is a thin wrapper around - * {@link org.hibernate.Session#get(String, java.io.Serializable, LockMode)} for convenience. - * For an explanation of the exact semantics of this method, please do refer to - * the Hibernate API documentation in the first instance. - * @param entityName the name of the persistent entity - * @param id the identifier of the persistent instance - * @param lockMode the lock mode to obtain - * @return the persistent instance, or {@code null} if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#get(Class, java.io.Serializable, org.hibernate.LockMode) - */ - Object get(String entityName, Serializable id, LockMode lockMode) throws DataAccessException; - - /** - * Return the persistent instance of the given entity class - * with the given identifier, throwing an exception if not found. - *

This method is a thin wrapper around - * {@link org.hibernate.Session#load(Class, java.io.Serializable)} for convenience. - * For an explanation of the exact semantics of this method, please do refer to - * the Hibernate API documentation in the first instance. - * @param entityClass a persistent class - * @param id the identifier of the persistent instance - * @return the persistent instance - * @throws org.springframework.orm.ObjectRetrievalFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#load(Class, java.io.Serializable) - */ - T load(Class entityClass, Serializable id) throws DataAccessException; - - /** - * Return the persistent instance of the given entity class - * with the given identifier, throwing an exception if not found. - * Obtains the specified lock mode if the instance exists. - *

This method is a thin wrapper around - * {@link org.hibernate.Session#load(Class, java.io.Serializable, LockMode)} for convenience. - * For an explanation of the exact semantics of this method, please do refer to - * the Hibernate API documentation in the first instance. - * @param entityClass a persistent class - * @param id the identifier of the persistent instance - * @param lockMode the lock mode to obtain - * @return the persistent instance - * @throws org.springframework.orm.ObjectRetrievalFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#load(Class, java.io.Serializable) - */ - T load(Class entityClass, Serializable id, LockMode lockMode) throws DataAccessException; - - /** - * Return the persistent instance of the given entity class - * with the given identifier, throwing an exception if not found. - *

This method is a thin wrapper around - * {@link org.hibernate.Session#load(String, java.io.Serializable)} for convenience. - * For an explanation of the exact semantics of this method, please do refer to - * the Hibernate API documentation in the first instance. - * @param entityName the name of the persistent entity - * @param id the identifier of the persistent instance - * @return the persistent instance - * @throws org.springframework.orm.ObjectRetrievalFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#load(Class, java.io.Serializable) - */ - Object load(String entityName, Serializable id) throws DataAccessException; - - /** - * Return the persistent instance of the given entity class - * with the given identifier, throwing an exception if not found. - *

Obtains the specified lock mode if the instance exists. - *

This method is a thin wrapper around - * {@link org.hibernate.Session#load(String, java.io.Serializable, LockMode)} for convenience. - * For an explanation of the exact semantics of this method, please do refer to - * the Hibernate API documentation in the first instance. - * @param entityName the name of the persistent entity - * @param id the identifier of the persistent instance - * @param lockMode the lock mode to obtain - * @return the persistent instance - * @throws org.springframework.orm.ObjectRetrievalFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#load(Class, java.io.Serializable) - */ - Object load(String entityName, Serializable id, LockMode lockMode) throws DataAccessException; - - /** - * Return all persistent instances of the given entity class. - * Note: Use queries or criteria for retrieving a specific subset. - * @param entityClass a persistent class - * @return a {@link List} containing 0 or more persistent instances - * @throws org.springframework.dao.DataAccessException if there is a Hibernate error - * @see org.hibernate.Session#createCriteria - */ - List loadAll(Class entityClass) throws DataAccessException; - - /** - * Load the persistent instance with the given identifier - * into the given object, throwing an exception if not found. - *

This method is a thin wrapper around - * {@link org.hibernate.Session#load(Object, java.io.Serializable)} for convenience. - * For an explanation of the exact semantics of this method, please do refer to - * the Hibernate API documentation in the first instance. - * @param entity the object (of the target class) to load into - * @param id the identifier of the persistent instance - * @throws org.springframework.orm.ObjectRetrievalFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#load(Object, java.io.Serializable) - */ - void load(Object entity, Serializable id) throws DataAccessException; - - /** - * Re-read the state of the given persistent instance. - * @param entity the persistent instance to re-read - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#refresh(Object) - */ - void refresh(Object entity) throws DataAccessException; - - /** - * Re-read the state of the given persistent instance. - * Obtains the specified lock mode for the instance. - * @param entity the persistent instance to re-read - * @param lockMode the lock mode to obtain - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#refresh(Object, org.hibernate.LockMode) - */ - void refresh(Object entity, LockMode lockMode) throws DataAccessException; - - /** - * Check whether the given object is in the Session cache. - * @param entity the persistence instance to check - * @return whether the given object is in the Session cache - * @throws org.springframework.dao.DataAccessException if there is a Hibernate error - * @see org.hibernate.Session#contains - */ - boolean contains(Object entity) throws DataAccessException; - - /** - * Remove the given object from the {@link org.hibernate.Session} cache. - * @param entity the persistent instance to evict - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#evict - */ - void evict(Object entity) throws DataAccessException; - - /** - * Force initialization of a Hibernate proxy or persistent collection. - * @param proxy a proxy for a persistent object or a persistent collection - * @throws DataAccessException if we can't initialize the proxy, for example - * because it is not associated with an active Session - * @see org.hibernate.Hibernate#initialize - */ - void initialize(Object proxy) throws DataAccessException; - - /** - * Return an enabled Hibernate {@link Filter} for the given filter name. - * The returned {@code Filter} instance can be used to set filter parameters. - * @param filterName the name of the filter - * @return the enabled Hibernate {@code Filter} (either already - * enabled or enabled on the fly by this operation) - * @throws IllegalStateException if we are not running within a - * transactional Session (in which case this operation does not make sense) - */ - Filter enableFilter(String filterName) throws IllegalStateException; - - - //------------------------------------------------------------------------- - // Convenience methods for storing individual objects - //------------------------------------------------------------------------- - - /** - * Obtain the specified lock level upon the given object, implicitly - * checking whether the corresponding database entry still exists. - * @param entity the persistent instance to lock - * @param lockMode the lock mode to obtain - * @throws org.springframework.orm.ObjectOptimisticLockingFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#lock(Object, org.hibernate.LockMode) - */ - void lock(Object entity, LockMode lockMode) throws DataAccessException; - - /** - * Obtain the specified lock level upon the given object, implicitly - * checking whether the corresponding database entry still exists. - * @param entityName the name of the persistent entity - * @param entity the persistent instance to lock - * @param lockMode the lock mode to obtain - * @throws org.springframework.orm.ObjectOptimisticLockingFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#lock(String, Object, org.hibernate.LockMode) - */ - void lock(String entityName, Object entity, LockMode lockMode) throws DataAccessException; - - /** - * Persist the given transient instance. - * @param entity the transient instance to persist - * @return the generated identifier - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#save(Object) - */ - Serializable save(Object entity) throws DataAccessException; - - /** - * Persist the given transient instance. - * @param entityName the name of the persistent entity - * @param entity the transient instance to persist - * @return the generated identifier - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#save(String, Object) - */ - Serializable save(String entityName, Object entity) throws DataAccessException; - - /** - * Update the given persistent instance, - * associating it with the current Hibernate {@link org.hibernate.Session}. - * @param entity the persistent instance to update - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#update(Object) - */ - void update(Object entity) throws DataAccessException; - - /** - * Update the given persistent instance, - * associating it with the current Hibernate {@link org.hibernate.Session}. - *

Obtains the specified lock mode if the instance exists, implicitly - * checking whether the corresponding database entry still exists. - * @param entity the persistent instance to update - * @param lockMode the lock mode to obtain - * @throws org.springframework.orm.ObjectOptimisticLockingFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#update(Object) - */ - void update(Object entity, LockMode lockMode) throws DataAccessException; - - /** - * Update the given persistent instance, - * associating it with the current Hibernate {@link org.hibernate.Session}. - * @param entityName the name of the persistent entity - * @param entity the persistent instance to update - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#update(String, Object) - */ - void update(String entityName, Object entity) throws DataAccessException; - - /** - * Update the given persistent instance, - * associating it with the current Hibernate {@link org.hibernate.Session}. - *

Obtains the specified lock mode if the instance exists, implicitly - * checking whether the corresponding database entry still exists. - * @param entityName the name of the persistent entity - * @param entity the persistent instance to update - * @param lockMode the lock mode to obtain - * @throws org.springframework.orm.ObjectOptimisticLockingFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#update(String, Object) - */ - void update(String entityName, Object entity, LockMode lockMode) throws DataAccessException; - - /** - * Save or update the given persistent instance, - * according to its id (matching the configured "unsaved-value"?). - * Associates the instance with the current Hibernate {@link org.hibernate.Session}. - * @param entity the persistent instance to save or update - * (to be associated with the Hibernate {@code Session}) - * @throws DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#saveOrUpdate(Object) - */ - void saveOrUpdate(Object entity) throws DataAccessException; - - /** - * Save or update the given persistent instance, - * according to its id (matching the configured "unsaved-value"?). - * Associates the instance with the current Hibernate {@code Session}. - * @param entityName the name of the persistent entity - * @param entity the persistent instance to save or update - * (to be associated with the Hibernate {@code Session}) - * @throws DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#saveOrUpdate(String, Object) - */ - void saveOrUpdate(String entityName, Object entity) throws DataAccessException; - - /** - * Persist the state of the given detached instance according to the - * given replication mode, reusing the current identifier value. - * @param entity the persistent object to replicate - * @param replicationMode the Hibernate ReplicationMode - * @throws DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#replicate(Object, org.hibernate.ReplicationMode) - */ - void replicate(Object entity, ReplicationMode replicationMode) throws DataAccessException; - - /** - * Persist the state of the given detached instance according to the - * given replication mode, reusing the current identifier value. - * @param entityName the name of the persistent entity - * @param entity the persistent object to replicate - * @param replicationMode the Hibernate ReplicationMode - * @throws DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#replicate(String, Object, org.hibernate.ReplicationMode) - */ - void replicate(String entityName, Object entity, ReplicationMode replicationMode) throws DataAccessException; - - /** - * Persist the given transient instance. Follows JSR-220 semantics. - *

Similar to {@code save}, associating the given object - * with the current Hibernate {@link org.hibernate.Session}. - * @param entity the persistent instance to persist - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#persist(Object) - * @see #save - */ - void persist(Object entity) throws DataAccessException; - - /** - * Persist the given transient instance. Follows JSR-220 semantics. - *

Similar to {@code save}, associating the given object - * with the current Hibernate {@link org.hibernate.Session}. - * @param entityName the name of the persistent entity - * @param entity the persistent instance to persist - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#persist(String, Object) - * @see #save - */ - void persist(String entityName, Object entity) throws DataAccessException; - - /** - * Copy the state of the given object onto the persistent object - * with the same identifier. Follows JSR-220 semantics. - *

Similar to {@code saveOrUpdate}, but never associates the given - * object with the current Hibernate Session. In case of a new entity, - * the state will be copied over as well. - *

Note that {@code merge} will not update the identifiers - * in the passed-in object graph (in contrast to TopLink)! Consider - * registering Spring's {@code IdTransferringMergeEventListener} if - * you would like to have newly assigned ids transferred to the original - * object graph too. - * @param entity the object to merge with the corresponding persistence instance - * @return the updated, registered persistent instance - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#merge(Object) - * @see #saveOrUpdate - * @see org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener - */ - T merge(T entity) throws DataAccessException; - - /** - * Copy the state of the given object onto the persistent object - * with the same identifier. Follows JSR-220 semantics. - *

Similar to {@code saveOrUpdate}, but never associates the given - * object with the current Hibernate {@link org.hibernate.Session}. In - * the case of a new entity, the state will be copied over as well. - *

Note that {@code merge} will not update the identifiers - * in the passed-in object graph (in contrast to TopLink)! Consider - * registering Spring's {@code IdTransferringMergeEventListener} - * if you would like to have newly assigned ids transferred to the - * original object graph too. - * @param entityName the name of the persistent entity - * @param entity the object to merge with the corresponding persistence instance - * @return the updated, registered persistent instance - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#merge(String, Object) - * @see #saveOrUpdate - */ - T merge(String entityName, T entity) throws DataAccessException; - - /** - * Delete the given persistent instance. - * @param entity the persistent instance to delete - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#delete(Object) - */ - void delete(Object entity) throws DataAccessException; - - /** - * Delete the given persistent instance. - *

Obtains the specified lock mode if the instance exists, implicitly - * checking whether the corresponding database entry still exists. - * @param entity the persistent instance to delete - * @param lockMode the lock mode to obtain - * @throws org.springframework.orm.ObjectOptimisticLockingFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#delete(Object) - */ - void delete(Object entity, LockMode lockMode) throws DataAccessException; - - /** - * Delete the given persistent instance. - * @param entityName the name of the persistent entity - * @param entity the persistent instance to delete - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#delete(Object) - */ - void delete(String entityName, Object entity) throws DataAccessException; - - /** - * Delete the given persistent instance. - *

Obtains the specified lock mode if the instance exists, implicitly - * checking whether the corresponding database entry still exists. - * @param entityName the name of the persistent entity - * @param entity the persistent instance to delete - * @param lockMode the lock mode to obtain - * @throws org.springframework.orm.ObjectOptimisticLockingFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#delete(Object) - */ - void delete(String entityName, Object entity, LockMode lockMode) throws DataAccessException; - - /** - * Delete all given persistent instances. - *

This can be combined with any of the find methods to delete by query - * in two lines of code. - * @param entities the persistent instances to delete - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#delete(Object) - */ - void deleteAll(Collection entities) throws DataAccessException; - - /** - * Flush all pending saves, updates and deletes to the database. - *

Only invoke this for selective eager flushing, for example when - * JDBC code needs to see certain changes within the same transaction. - * Else, it is preferable to rely on auto-flushing at transaction - * completion. - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#flush - */ - void flush() throws DataAccessException; - - /** - * Remove all objects from the {@link org.hibernate.Session} cache, and - * cancel all pending saves, updates and deletes. - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#clear - */ - void clear() throws DataAccessException; - - - //------------------------------------------------------------------------- - // Convenience finder methods for HQL strings - //------------------------------------------------------------------------- - - /** - * Execute an HQL query. - * @param queryString a query expressed in Hibernate's query language - * @return a {@link List} containing the results of the query execution - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#createQuery - */ - List find(String queryString) throws DataAccessException; - - /** - * Execute an HQL query, binding one value to a "?" parameter in the - * query string. - * @param queryString a query expressed in Hibernate's query language - * @param value the value of the parameter - * @return a {@link List} containing the results of the query execution - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#createQuery - */ - List find(String queryString, Object value) throws DataAccessException; - - /** - * Execute an HQL query, binding a number of values to "?" parameters - * in the query string. - * @param queryString a query expressed in Hibernate's query language - * @param values the values of the parameters - * @return a {@link List} containing the results of the query execution - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#createQuery - */ - List find(String queryString, Object... values) throws DataAccessException; - - /** - * Execute an HQL query, binding one value to a ":" named parameter - * in the query string. - * @param queryString a query expressed in Hibernate's query language - * @param paramName the name of the parameter - * @param value the value of the parameter - * @return a {@link List} containing the results of the query execution - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#getNamedQuery(String) - */ - List findByNamedParam(String queryString, String paramName, Object value) throws DataAccessException; - - /** - * Execute an HQL query, binding a number of values to ":" named - * parameters in the query string. - * @param queryString a query expressed in Hibernate's query language - * @param paramNames the names of the parameters - * @param values the values of the parameters - * @return a {@link List} containing the results of the query execution - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#getNamedQuery(String) - */ - List findByNamedParam(String queryString, String[] paramNames, Object[] values) throws DataAccessException; - - /** - * Execute an HQL query, binding the properties of the given bean to - * named parameters in the query string. - * @param queryString a query expressed in Hibernate's query language - * @param valueBean the values of the parameters - * @return a {@link List} containing the results of the query execution - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Query#setProperties - * @see org.hibernate.Session#createQuery - */ - List findByValueBean(String queryString, Object valueBean) throws DataAccessException; - - - //------------------------------------------------------------------------- - // Convenience finder methods for named queries - //------------------------------------------------------------------------- - - /** - * Execute a named query. - *

A named query is defined in a Hibernate mapping file. - * @param queryName the name of a Hibernate query in a mapping file - * @return a {@link List} containing the results of the query execution - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#getNamedQuery(String) - */ - List findByNamedQuery(String queryName) throws DataAccessException; - - /** - * Execute a named query, binding one value to a "?" parameter in - * the query string. - *

A named query is defined in a Hibernate mapping file. - * @param queryName the name of a Hibernate query in a mapping file - * @param value the value of the parameter - * @return a {@link List} containing the results of the query execution - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#getNamedQuery(String) - */ - List findByNamedQuery(String queryName, Object value) throws DataAccessException; - - /** - * Execute a named query binding a number of values to "?" parameters - * in the query string. - *

A named query is defined in a Hibernate mapping file. - * @param queryName the name of a Hibernate query in a mapping file - * @param values the values of the parameters - * @return a {@link List} containing the results of the query execution - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#getNamedQuery(String) - */ - List findByNamedQuery(String queryName, Object... values) throws DataAccessException; - - /** - * Execute a named query, binding one value to a ":" named parameter - * in the query string. - *

A named query is defined in a Hibernate mapping file. - * @param queryName the name of a Hibernate query in a mapping file - * @param paramName the name of parameter - * @param value the value of the parameter - * @return a {@link List} containing the results of the query execution - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#getNamedQuery(String) - */ - List findByNamedQueryAndNamedParam(String queryName, String paramName, Object value) - throws DataAccessException; - - /** - * Execute a named query, binding a number of values to ":" named - * parameters in the query string. - *

A named query is defined in a Hibernate mapping file. - * @param queryName the name of a Hibernate query in a mapping file - * @param paramNames the names of the parameters - * @param values the values of the parameters - * @return a {@link List} containing the results of the query execution - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#getNamedQuery(String) - */ - List findByNamedQueryAndNamedParam(String queryName, String[] paramNames, Object[] values) - throws DataAccessException; - - /** - * Execute a named query, binding the properties of the given bean to - * ":" named parameters in the query string. - *

A named query is defined in a Hibernate mapping file. - * @param queryName the name of a Hibernate query in a mapping file - * @param valueBean the values of the parameters - * @return a {@link List} containing the results of the query execution - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Query#setProperties - * @see org.hibernate.Session#getNamedQuery(String) - */ - List findByNamedQueryAndValueBean(String queryName, Object valueBean) throws DataAccessException; - - - //------------------------------------------------------------------------- - // Convenience finder methods for detached criteria - //------------------------------------------------------------------------- - - /** - * Execute a query based on a given Hibernate criteria object. - * @param criteria the detached Hibernate criteria object. - * Note: Do not reuse criteria objects! They need to recreated per execution, - * due to the suboptimal design of Hibernate's criteria facility. - * @return a {@link List} containing 0 or more persistent instances - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.criterion.DetachedCriteria#getExecutableCriteria(org.hibernate.Session) - */ - List findByCriteria(DetachedCriteria criteria) throws DataAccessException; - - /** - * Execute a query based on the given Hibernate criteria object. - * @param criteria the detached Hibernate criteria object. - * Note: Do not reuse criteria objects! They need to recreated per execution, - * due to the suboptimal design of Hibernate's criteria facility. - * @param firstResult the index of the first result object to be retrieved - * (numbered from 0) - * @param maxResults the maximum number of result objects to retrieve - * (or <=0 for no limit) - * @return a {@link List} containing 0 or more persistent instances - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.criterion.DetachedCriteria#getExecutableCriteria(org.hibernate.Session) - * @see org.hibernate.Criteria#setFirstResult(int) - * @see org.hibernate.Criteria#setMaxResults(int) - */ - List findByCriteria(DetachedCriteria criteria, int firstResult, int maxResults) throws DataAccessException; - - /** - * Execute a query based on the given example entity object. - * @param exampleEntity an instance of the desired entity, - * serving as example for "query-by-example" - * @return a {@link List} containing 0 or more persistent instances - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.criterion.Example#create(Object) - */ - List findByExample(T exampleEntity) throws DataAccessException; - - /** - * Execute a query based on the given example entity object. - * @param entityName the name of the persistent entity - * @param exampleEntity an instance of the desired entity, - * serving as example for "query-by-example" - * @return a {@link List} containing 0 or more persistent instances - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.criterion.Example#create(Object) - */ - List findByExample(String entityName, T exampleEntity) throws DataAccessException; - - /** - * Execute a query based on a given example entity object. - * @param exampleEntity an instance of the desired entity, - * serving as example for "query-by-example" - * @param firstResult the index of the first result object to be retrieved - * (numbered from 0) - * @param maxResults the maximum number of result objects to retrieve - * (or <=0 for no limit) - * @return a {@link List} containing 0 or more persistent instances - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.criterion.Example#create(Object) - * @see org.hibernate.Criteria#setFirstResult(int) - * @see org.hibernate.Criteria#setMaxResults(int) - */ - List findByExample(T exampleEntity, int firstResult, int maxResults) throws DataAccessException; - - /** - * Execute a query based on a given example entity object. - * @param entityName the name of the persistent entity - * @param exampleEntity an instance of the desired entity, - * serving as example for "query-by-example" - * @param firstResult the index of the first result object to be retrieved - * (numbered from 0) - * @param maxResults the maximum number of result objects to retrieve - * (or <=0 for no limit) - * @return a {@link List} containing 0 or more persistent instances - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.criterion.Example#create(Object) - * @see org.hibernate.Criteria#setFirstResult(int) - * @see org.hibernate.Criteria#setMaxResults(int) - */ - List findByExample(String entityName, T exampleEntity, int firstResult, int maxResults) - throws DataAccessException; - - - //------------------------------------------------------------------------- - // Convenience query methods for iteration and bulk updates/deletes - //------------------------------------------------------------------------- - - /** - * Execute a query for persistent instances. - *

Returns the results as an {@link Iterator}. Entities returned are - * initialized on demand. See the Hibernate API documentation for details. - * @param queryString a query expressed in Hibernate's query language - * @return an {@link Iterator} containing 0 or more persistent instances - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#createQuery - * @see org.hibernate.Query#iterate - */ - Iterator iterate(String queryString) throws DataAccessException; - - /** - * Execute a query for persistent instances, binding one value - * to a "?" parameter in the query string. - *

Returns the results as an {@link Iterator}. Entities returned are - * initialized on demand. See the Hibernate API documentation for details. - * @param queryString a query expressed in Hibernate's query language - * @param value the value of the parameter - * @return an {@link Iterator} containing 0 or more persistent instances - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#createQuery - * @see org.hibernate.Query#iterate - */ - Iterator iterate(String queryString, Object value) throws DataAccessException; - - /** - * Execute a query for persistent instances, binding a number of - * values to "?" parameters in the query string. - *

Returns the results as an {@link Iterator}. Entities returned are - * initialized on demand. See the Hibernate API documentation for details. - * @param queryString a query expressed in Hibernate's query language - * @param values the values of the parameters - * @return an {@link Iterator} containing 0 or more persistent instances - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#createQuery - * @see org.hibernate.Query#iterate - */ - Iterator iterate(String queryString, Object... values) throws DataAccessException; - - /** - * Immediately close an {@link Iterator} created by any of the various - * {@code iterate(..)} operations, instead of waiting until the - * session is closed or disconnected. - * @param it the {@code Iterator} to close - * @throws DataAccessException if the {@code Iterator} could not be closed - * @see org.hibernate.Hibernate#close - */ - void closeIterator(Iterator it) throws DataAccessException; - - /** - * Update/delete all objects according to the given query. - * @param queryString an update/delete query expressed in Hibernate's query language - * @return the number of instances updated/deleted - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#createQuery - * @see org.hibernate.Query#executeUpdate - */ - int bulkUpdate(String queryString) throws DataAccessException; - - /** - * Update/delete all objects according to the given query, binding one value - * to a "?" parameter in the query string. - * @param queryString an update/delete query expressed in Hibernate's query language - * @param value the value of the parameter - * @return the number of instances updated/deleted - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#createQuery - * @see org.hibernate.Query#executeUpdate - */ - int bulkUpdate(String queryString, Object value) throws DataAccessException; - - /** - * Update/delete all objects according to the given query, binding a number of - * values to "?" parameters in the query string. - * @param queryString an update/delete query expressed in Hibernate's query language - * @param values the values of the parameters - * @return the number of instances updated/deleted - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - * @see org.hibernate.Session#createQuery - * @see org.hibernate.Query#executeUpdate - */ - int bulkUpdate(String queryString, Object... values) throws DataAccessException; - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateOptimisticLockingFailureException.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateOptimisticLockingFailureException.java deleted file mode 100644 index 47ff23a281..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateOptimisticLockingFailureException.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import org.hibernate.OptimisticLockException; -import org.hibernate.StaleObjectStateException; -import org.hibernate.StaleStateException; - -import org.springframework.orm.ObjectOptimisticLockingFailureException; - -/** - * Hibernate-specific subclass of ObjectOptimisticLockingFailureException. - * Converts Hibernate's StaleObjectStateException, StaleStateException - * and OptimisticLockException. - * - * @author Juergen Hoeller - * @since 1.2 - * @see SessionFactoryUtils#convertHibernateAccessException - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -@SuppressWarnings("serial") -public class HibernateOptimisticLockingFailureException extends ObjectOptimisticLockingFailureException { - - public HibernateOptimisticLockingFailureException(StaleObjectStateException ex) { - super(ex.getEntityName(), ex.getIdentifier(), ex); - } - - public HibernateOptimisticLockingFailureException(StaleStateException ex) { - super(ex.getMessage(), ex); - } - - public HibernateOptimisticLockingFailureException(OptimisticLockException ex) { - super(ex.getMessage(), ex); - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateQueryException.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateQueryException.java deleted file mode 100644 index 81b82ffff5..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateQueryException.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import org.hibernate.QueryException; - -import org.springframework.dao.InvalidDataAccessResourceUsageException; - -/** - * Hibernate-specific subclass of InvalidDataAccessResourceUsageException, - * thrown on invalid HQL query syntax. - * - * @author Juergen Hoeller - * @since 1.2 - * @see SessionFactoryUtils#convertHibernateAccessException - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -@SuppressWarnings("serial") -public class HibernateQueryException extends InvalidDataAccessResourceUsageException { - - public HibernateQueryException(QueryException ex) { - super(ex.getMessage(), ex); - } - - /** - * Return the HQL query string that was invalid. - */ - public String getQueryString() { - return ((QueryException) getCause()).getQueryString(); - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateSystemException.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateSystemException.java deleted file mode 100644 index ddc5a2e17f..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateSystemException.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import org.hibernate.HibernateException; - -import org.springframework.dao.UncategorizedDataAccessException; - -/** - * Hibernate-specific subclass of UncategorizedDataAccessException, - * for Hibernate system errors that do not match any concrete - * {@code org.springframework.dao} exceptions. - * - * @author Juergen Hoeller - * @since 1.2 - * @see SessionFactoryUtils#convertHibernateAccessException - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -@SuppressWarnings("serial") -public class HibernateSystemException extends UncategorizedDataAccessException { - - /** - * Create a new HibernateSystemException, - * wrapping an arbitrary HibernateException. - * @param cause the HibernateException thrown - */ - public HibernateSystemException(HibernateException cause) { - super(cause != null ? cause.getMessage() : null, cause); - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateTemplate.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateTemplate.java deleted file mode 100644 index 1c1d0ad562..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateTemplate.java +++ /dev/null @@ -1,1398 +0,0 @@ -/* - * Copyright 2002-2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import java.io.Serializable; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.sql.SQLException; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; - -import org.hibernate.Criteria; -import org.hibernate.Filter; -import org.hibernate.FlushMode; -import org.hibernate.Hibernate; -import org.hibernate.HibernateException; -import org.hibernate.LockMode; -import org.hibernate.Query; -import org.hibernate.ReplicationMode; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.criterion.DetachedCriteria; -import org.hibernate.criterion.Example; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.event.EventSource; - -import org.springframework.dao.DataAccessException; -import org.springframework.dao.DataAccessResourceFailureException; -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.util.Assert; - -/** - * Helper class that simplifies Hibernate data access code. Automatically - * converts HibernateExceptions into DataAccessExceptions, following the - * {@code org.springframework.dao} exception hierarchy. - * - *

The central method is {@code execute}, supporting Hibernate access code - * implementing the {@link HibernateCallback} interface. It provides Hibernate Session - * handling such that neither the HibernateCallback implementation nor the calling - * code needs to explicitly care about retrieving/closing Hibernate Sessions, - * or handling Session lifecycle exceptions. For typical single step actions, - * there are various convenience methods (find, load, saveOrUpdate, delete). - * - *

Can be used within a service implementation via direct instantiation - * with a SessionFactory reference, or get prepared in an application context - * and given to services as bean reference. Note: The SessionFactory should - * always be configured as bean in the application context, in the first case - * given to the service directly, in the second case to the prepared template. - * - *

NOTE: As of Hibernate 3.0.1, transactional Hibernate access code can - * also be coded in plain Hibernate style. Hence, for newly started projects, - * consider adopting the standard Hibernate3 style of coding data access objects - * instead, based on {@link org.hibernate.SessionFactory#getCurrentSession()}. - * - *

This class can be considered as direct alternative to working with the raw - * Hibernate3 Session API (through {@code SessionFactory.getCurrentSession()}). - * The major advantage is its automatic conversion to DataAccessExceptions as well - * as its capability to fall back to 'auto-commit' style behavior when used outside - * of transactions. Note that HibernateTemplate will perform its own Session - * management, not participating in a custom Hibernate CurrentSessionContext - * unless you explicitly switch {@link #setAllowCreate "allowCreate"} to "false". - * - *

{@link LocalSessionFactoryBean} is the preferred way of obtaining a reference - * to a specific Hibernate SessionFactory, at least in a non-EJB environment. - * The Spring application context will manage its lifecycle, initializing and - * shutting down the factory as part of the application. - * - *

Note that operations that return an Iterator (i.e. {@code iterate}) - * are supposed to be used within Spring-driven or JTA-driven transactions - * (with HibernateTransactionManager, JtaTransactionManager, or EJB CMT). - * Else, the Iterator won't be able to read results from its ResultSet anymore, - * as the underlying Hibernate Session will already have been closed. - * - *

Lazy loading will also just work with an open Hibernate Session, - * either within a transaction or within OpenSessionInViewFilter/Interceptor. - * Furthermore, some operations just make sense within transactions, - * for example: {@code contains}, {@code evict}, {@code lock}, - * {@code flush}, {@code clear}. - * - * @author Juergen Hoeller - * @since 1.2 - * @see #setSessionFactory - * @see HibernateCallback - * @see org.hibernate.Session - * @see LocalSessionFactoryBean - * @see HibernateTransactionManager - * @see org.springframework.transaction.jta.JtaTransactionManager - * @see org.springframework.orm.hibernate3.support.OpenSessionInViewFilter - * @see org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public class HibernateTemplate extends HibernateAccessor implements HibernateOperations { - - private boolean allowCreate = true; - - private boolean alwaysUseNewSession = false; - - private boolean exposeNativeSession = false; - - private boolean checkWriteOperations = true; - - private boolean cacheQueries = false; - - private String queryCacheRegion; - - private int fetchSize = 0; - - private int maxResults = 0; - - - /** - * Create a new HibernateTemplate instance. - */ - public HibernateTemplate() { - } - - /** - * Create a new HibernateTemplate instance. - * @param sessionFactory the SessionFactory to create Sessions with - */ - public HibernateTemplate(SessionFactory sessionFactory) { - setSessionFactory(sessionFactory); - afterPropertiesSet(); - } - - /** - * Create a new HibernateTemplate instance. - * @param sessionFactory the SessionFactory to create Sessions with - * @param allowCreate if a non-transactional Session should be created when no - * transactional Session can be found for the current thread - */ - public HibernateTemplate(SessionFactory sessionFactory, boolean allowCreate) { - setSessionFactory(sessionFactory); - setAllowCreate(allowCreate); - afterPropertiesSet(); - } - - - /** - * Set if a new {@link Session} should be created when no transactional - * {@code Session} can be found for the current thread. - * The default value is {@code true}. - *

{@code HibernateTemplate} is aware of a corresponding - * {@code Session} bound to the current thread, for example when using - * {@link HibernateTransactionManager}. If {@code allowCreate} is - * {@code true}, a new non-transactional {@code Session} will be - * created if none is found, which needs to be closed at the end of the operation. - * If {@code false}, an {@link IllegalStateException} will get thrown in - * this case. - *

NOTE: As of Spring 2.5, switching {@code allowCreate} - * to {@code false} will delegate to Hibernate's - * {@link org.hibernate.SessionFactory#getCurrentSession()} method, - * which - with Spring-based setup - will by default delegate to Spring's - * {@code SessionFactoryUtils.getSession(sessionFactory, false)}. - * This mode also allows for custom Hibernate CurrentSessionContext strategies - * to be plugged in, whereas {@code allowCreate} set to {@code true} - * will always use a Spring-managed Hibernate Session. - * @see SessionFactoryUtils#getSession(SessionFactory, boolean) - */ - public void setAllowCreate(boolean allowCreate) { - this.allowCreate = allowCreate; - } - - /** - * Return if a new Session should be created if no thread-bound found. - */ - public boolean isAllowCreate() { - return this.allowCreate; - } - - /** - * Set whether to always use a new Hibernate Session for this template. - * Default is "false"; if activated, all operations on this template will - * work on a new Hibernate Session even in case of a pre-bound Session - * (for example, within a transaction or OpenSessionInViewFilter). - *

Within a transaction, a new Hibernate Session used by this template - * will participate in the transaction through using the same JDBC - * Connection. In such a scenario, multiple Sessions will participate - * in the same database transaction. - *

Turn this on for operations that are supposed to always execute - * independently, without side effects caused by a shared Hibernate Session. - */ - public void setAlwaysUseNewSession(boolean alwaysUseNewSession) { - this.alwaysUseNewSession = alwaysUseNewSession; - } - - /** - * Return whether to always use a new Hibernate Session for this template. - */ - public boolean isAlwaysUseNewSession() { - return this.alwaysUseNewSession; - } - - /** - * Set whether to expose the native Hibernate Session to - * HibernateCallback code. - *

Default is "false": a Session proxy will be returned, suppressing - * {@code close} calls and automatically applying query cache - * settings and transaction timeouts. - * @see HibernateCallback - * @see org.hibernate.Session - * @see #setCacheQueries - * @see #setQueryCacheRegion - * @see #prepareQuery - * @see #prepareCriteria - */ - public void setExposeNativeSession(boolean exposeNativeSession) { - this.exposeNativeSession = exposeNativeSession; - } - - /** - * Return whether to expose the native Hibernate Session to - * HibernateCallback code, or rather a Session proxy. - */ - public boolean isExposeNativeSession() { - return this.exposeNativeSession; - } - - /** - * Set whether to check that the Hibernate Session is not in read-only mode - * in case of write operations (save/update/delete). - *

Default is "true", for fail-fast behavior when attempting write operations - * within a read-only transaction. Turn this off to allow save/update/delete - * on a Session with flush mode NEVER. - * @see #setFlushMode - * @see #checkWriteOperationAllowed - * @see org.springframework.transaction.TransactionDefinition#isReadOnly - */ - public void setCheckWriteOperations(boolean checkWriteOperations) { - this.checkWriteOperations = checkWriteOperations; - } - - /** - * Return whether to check that the Hibernate Session is not in read-only - * mode in case of write operations (save/update/delete). - */ - public boolean isCheckWriteOperations() { - return this.checkWriteOperations; - } - - /** - * Set whether to cache all queries executed by this template. - *

If this is "true", all Query and Criteria objects created by - * this template will be marked as cacheable (including all - * queries through find methods). - *

To specify the query region to be used for queries cached - * by this template, set the "queryCacheRegion" property. - * @see #setQueryCacheRegion - * @see org.hibernate.Query#setCacheable - * @see org.hibernate.Criteria#setCacheable - */ - public void setCacheQueries(boolean cacheQueries) { - this.cacheQueries = cacheQueries; - } - - /** - * Return whether to cache all queries executed by this template. - */ - public boolean isCacheQueries() { - return this.cacheQueries; - } - - /** - * Set the name of the cache region for queries executed by this template. - *

If this is specified, it will be applied to all Query and Criteria objects - * created by this template (including all queries through find methods). - *

The cache region will not take effect unless queries created by this - * template are configured to be cached via the "cacheQueries" property. - * @see #setCacheQueries - * @see org.hibernate.Query#setCacheRegion - * @see org.hibernate.Criteria#setCacheRegion - */ - public void setQueryCacheRegion(String queryCacheRegion) { - this.queryCacheRegion = queryCacheRegion; - } - - /** - * Return the name of the cache region for queries executed by this template. - */ - public String getQueryCacheRegion() { - return this.queryCacheRegion; - } - - /** - * Set the fetch size for this HibernateTemplate. This is important for processing - * large result sets: Setting this higher than the default value will increase - * processing speed at the cost of memory consumption; setting this lower can - * avoid transferring row data that will never be read by the application. - *

Default is 0, indicating to use the JDBC driver's default. - */ - public void setFetchSize(int fetchSize) { - this.fetchSize = fetchSize; - } - - /** - * Return the fetch size specified for this HibernateTemplate. - */ - public int getFetchSize() { - return this.fetchSize; - } - - /** - * Set the maximum number of rows for this HibernateTemplate. This is important - * for processing subsets of large result sets, avoiding to read and hold - * the entire result set in the database or in the JDBC driver if we're - * never interested in the entire result in the first place (for example, - * when performing searches that might return a large number of matches). - *

Default is 0, indicating to use the JDBC driver's default. - */ - public void setMaxResults(int maxResults) { - this.maxResults = maxResults; - } - - /** - * Return the maximum number of rows specified for this HibernateTemplate. - */ - public int getMaxResults() { - return this.maxResults; - } - - - @Override - public T execute(HibernateCallback action) throws DataAccessException { - return doExecute(action, false, false); - } - - @Override - @Deprecated - public List executeFind(HibernateCallback action) throws DataAccessException { - Object result = doExecute(action, false, false); - if (result != null && !(result instanceof List)) { - throw new InvalidDataAccessApiUsageException( - "Result object returned from HibernateCallback isn't a List: [" + result + "]"); - } - return (List) result; - } - - /** - * Execute the action specified by the given action object within a - * new {@link org.hibernate.Session}. - *

This execute variant overrides the template-wide - * {@link #isAlwaysUseNewSession() "alwaysUseNewSession"} setting. - * @param action callback object that specifies the Hibernate action - * @return a result object returned by the action, or {@code null} - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - */ - public T executeWithNewSession(HibernateCallback action) { - return doExecute(action, true, false); - } - - /** - * Execute the action specified by the given action object within a - * native {@link org.hibernate.Session}. - *

This execute variant overrides the template-wide - * {@link #isExposeNativeSession() "exposeNativeSession"} setting. - * @param action callback object that specifies the Hibernate action - * @return a result object returned by the action, or {@code null} - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - */ - public T executeWithNativeSession(HibernateCallback action) { - return doExecute(action, false, true); - } - - /** - * Execute the action specified by the given action object within a Session. - * @param action callback object that specifies the Hibernate action - * @param enforceNewSession whether to enforce a new Session for this template - * even if there is a pre-bound transactional Session - * @param enforceNativeSession whether to enforce exposure of the native - * Hibernate Session to callback code - * @return a result object returned by the action, or {@code null} - * @throws org.springframework.dao.DataAccessException in case of Hibernate errors - */ - protected T doExecute(HibernateCallback action, boolean enforceNewSession, boolean enforceNativeSession) - throws DataAccessException { - - Assert.notNull(action, "Callback object must not be null"); - - Session session = (enforceNewSession ? - SessionFactoryUtils.getNewSession(getSessionFactory(), getEntityInterceptor()) : getSession()); - boolean existingTransaction = (!enforceNewSession && - (!isAllowCreate() || SessionFactoryUtils.isSessionTransactional(session, getSessionFactory()))); - if (existingTransaction) { - logger.debug("Found thread-bound Session for HibernateTemplate"); - } - - FlushMode previousFlushMode = null; - try { - previousFlushMode = applyFlushMode(session, existingTransaction); - enableFilters(session); - Session sessionToExpose = - (enforceNativeSession || isExposeNativeSession() ? session : createSessionProxy(session)); - T result = action.doInHibernate(sessionToExpose); - flushIfNecessary(session, existingTransaction); - return result; - } - catch (HibernateException ex) { - throw convertHibernateAccessException(ex); - } - catch (SQLException ex) { - throw convertJdbcAccessException(ex); - } - catch (RuntimeException ex) { - // Callback code threw application exception... - throw ex; - } - finally { - if (existingTransaction) { - logger.debug("Not closing pre-bound Hibernate Session after HibernateTemplate"); - disableFilters(session); - if (previousFlushMode != null) { - session.setFlushMode(previousFlushMode); - } - } - else { - // Never use deferred close for an explicitly new Session. - if (isAlwaysUseNewSession()) { - SessionFactoryUtils.closeSession(session); - } - else { - SessionFactoryUtils.closeSessionOrRegisterDeferredClose(session, getSessionFactory()); - } - } - } - } - - /** - * Return a Session for use by this template. - *

Returns a new Session in case of "alwaysUseNewSession" (using the same - * JDBC Connection as a transactional Session, if applicable), a pre-bound - * Session in case of "allowCreate" turned off, and a pre-bound or new Session - * otherwise (new only if no transactional or otherwise pre-bound Session exists). - * @return the Session to use (never {@code null}) - * @see SessionFactoryUtils#getSession - * @see SessionFactoryUtils#getNewSession - * @see #setAlwaysUseNewSession - * @see #setAllowCreate - */ - protected Session getSession() { - if (isAlwaysUseNewSession()) { - return SessionFactoryUtils.getNewSession(getSessionFactory(), getEntityInterceptor()); - } - else if (isAllowCreate()) { - return SessionFactoryUtils.getSession( - getSessionFactory(), getEntityInterceptor(), getJdbcExceptionTranslator()); - } - else if (SessionFactoryUtils.hasTransactionalSession(getSessionFactory())) { - return SessionFactoryUtils.getSession(getSessionFactory(), false); - } - else { - try { - return getSessionFactory().getCurrentSession(); - } - catch (HibernateException ex) { - throw new DataAccessResourceFailureException("Could not obtain current Hibernate Session", ex); - } - } - } - - /** - * Create a close-suppressing proxy for the given Hibernate Session. - * The proxy also prepares returned Query and Criteria objects. - * @param session the Hibernate Session to create a proxy for - * @return the Session proxy - * @see org.hibernate.Session#close() - * @see #prepareQuery - * @see #prepareCriteria - */ - protected Session createSessionProxy(Session session) { - Class[] sessionIfcs; - Class mainIfc = (session instanceof org.hibernate.classic.Session ? - org.hibernate.classic.Session.class : Session.class); - if (session instanceof EventSource) { - sessionIfcs = new Class[] {mainIfc, EventSource.class}; - } - else if (session instanceof SessionImplementor) { - sessionIfcs = new Class[] {mainIfc, SessionImplementor.class}; - } - else { - sessionIfcs = new Class[] {mainIfc}; - } - return (Session) Proxy.newProxyInstance( - session.getClass().getClassLoader(), sessionIfcs, - new CloseSuppressingInvocationHandler(session)); - } - - - //------------------------------------------------------------------------- - // Convenience methods for loading individual objects - //------------------------------------------------------------------------- - - @Override - public T get(Class entityClass, Serializable id) throws DataAccessException { - return get(entityClass, id, null); - } - - @Override - public T get(final Class entityClass, final Serializable id, final LockMode lockMode) - throws DataAccessException { - - return executeWithNativeSession(new HibernateCallback() { - @Override - @SuppressWarnings("unchecked") - public T doInHibernate(Session session) throws HibernateException { - if (lockMode != null) { - return (T) session.get(entityClass, id, lockMode); - } - else { - return (T) session.get(entityClass, id); - } - } - }); - } - - @Override - public Object get(String entityName, Serializable id) throws DataAccessException { - return get(entityName, id, null); - } - - @Override - public Object get(final String entityName, final Serializable id, final LockMode lockMode) - throws DataAccessException { - - return executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - if (lockMode != null) { - return session.get(entityName, id, lockMode); - } - else { - return session.get(entityName, id); - } - } - }); - } - - @Override - public T load(Class entityClass, Serializable id) throws DataAccessException { - return load(entityClass, id, null); - } - - @Override - public T load(final Class entityClass, final Serializable id, final LockMode lockMode) - throws DataAccessException { - - return executeWithNativeSession(new HibernateCallback() { - @Override - @SuppressWarnings("unchecked") - public T doInHibernate(Session session) throws HibernateException { - if (lockMode != null) { - return (T) session.load(entityClass, id, lockMode); - } - else { - return (T) session.load(entityClass, id); - } - } - }); - } - - @Override - public Object load(String entityName, Serializable id) throws DataAccessException { - return load(entityName, id, null); - } - - @Override - public Object load(final String entityName, final Serializable id, final LockMode lockMode) - throws DataAccessException { - - return executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - if (lockMode != null) { - return session.load(entityName, id, lockMode); - } - else { - return session.load(entityName, id); - } - } - }); - } - - @Override - public List loadAll(final Class entityClass) throws DataAccessException { - return executeWithNativeSession(new HibernateCallback>() { - @Override - @SuppressWarnings("unchecked") - public List doInHibernate(Session session) throws HibernateException { - Criteria criteria = session.createCriteria(entityClass); - criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); - prepareCriteria(criteria); - return criteria.list(); - } - }); - } - - @Override - public void load(final Object entity, final Serializable id) throws DataAccessException { - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - session.load(entity, id); - return null; - } - }); - } - - @Override - public void refresh(final Object entity) throws DataAccessException { - refresh(entity, null); - } - - @Override - public void refresh(final Object entity, final LockMode lockMode) throws DataAccessException { - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - if (lockMode != null) { - session.refresh(entity, lockMode); - } - else { - session.refresh(entity); - } - return null; - } - }); - } - - @Override - public boolean contains(final Object entity) throws DataAccessException { - return executeWithNativeSession(new HibernateCallback() { - @Override - public Boolean doInHibernate(Session session) { - return session.contains(entity); - } - }); - } - - @Override - public void evict(final Object entity) throws DataAccessException { - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - session.evict(entity); - return null; - } - }); - } - - @Override - public void initialize(Object proxy) throws DataAccessException { - try { - Hibernate.initialize(proxy); - } - catch (HibernateException ex) { - throw SessionFactoryUtils.convertHibernateAccessException(ex); - } - } - - @Override - public Filter enableFilter(String filterName) throws IllegalStateException { - Session session = SessionFactoryUtils.getSession(getSessionFactory(), false); - Filter filter = session.getEnabledFilter(filterName); - if (filter == null) { - filter = session.enableFilter(filterName); - } - return filter; - } - - - //------------------------------------------------------------------------- - // Convenience methods for storing individual objects - //------------------------------------------------------------------------- - - @Override - public void lock(final Object entity, final LockMode lockMode) throws DataAccessException { - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - session.lock(entity, lockMode); - return null; - } - }); - } - - @Override - public void lock(final String entityName, final Object entity, final LockMode lockMode) - throws DataAccessException { - - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - session.lock(entityName, entity, lockMode); - return null; - } - }); - } - - @Override - public Serializable save(final Object entity) throws DataAccessException { - return executeWithNativeSession(new HibernateCallback() { - @Override - public Serializable doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - return session.save(entity); - } - }); - } - - @Override - public Serializable save(final String entityName, final Object entity) throws DataAccessException { - return executeWithNativeSession(new HibernateCallback() { - @Override - public Serializable doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - return session.save(entityName, entity); - } - }); - } - - @Override - public void update(Object entity) throws DataAccessException { - update(entity, null); - } - - @Override - public void update(final Object entity, final LockMode lockMode) throws DataAccessException { - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - session.update(entity); - if (lockMode != null) { - session.lock(entity, lockMode); - } - return null; - } - }); - } - - @Override - public void update(String entityName, Object entity) throws DataAccessException { - update(entityName, entity, null); - } - - @Override - public void update(final String entityName, final Object entity, final LockMode lockMode) - throws DataAccessException { - - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - session.update(entityName, entity); - if (lockMode != null) { - session.lock(entity, lockMode); - } - return null; - } - }); - } - - @Override - public void saveOrUpdate(final Object entity) throws DataAccessException { - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - session.saveOrUpdate(entity); - return null; - } - }); - } - - @Override - public void saveOrUpdate(final String entityName, final Object entity) throws DataAccessException { - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - session.saveOrUpdate(entityName, entity); - return null; - } - }); - } - - @Override - public void replicate(final Object entity, final ReplicationMode replicationMode) - throws DataAccessException { - - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - session.replicate(entity, replicationMode); - return null; - } - }); - } - - @Override - public void replicate(final String entityName, final Object entity, final ReplicationMode replicationMode) - throws DataAccessException { - - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - session.replicate(entityName, entity, replicationMode); - return null; - } - }); - } - - @Override - public void persist(final Object entity) throws DataAccessException { - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - session.persist(entity); - return null; - } - }); - } - - @Override - public void persist(final String entityName, final Object entity) throws DataAccessException { - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - session.persist(entityName, entity); - return null; - } - }); - } - - @Override - public T merge(final T entity) throws DataAccessException { - return executeWithNativeSession(new HibernateCallback() { - @Override - @SuppressWarnings("unchecked") - public T doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - return (T) session.merge(entity); - } - }); - } - - @Override - public T merge(final String entityName, final T entity) throws DataAccessException { - return executeWithNativeSession(new HibernateCallback() { - @Override - @SuppressWarnings("unchecked") - public T doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - return (T) session.merge(entityName, entity); - } - }); - } - - @Override - public void delete(Object entity) throws DataAccessException { - delete(entity, null); - } - - @Override - public void delete(final Object entity, final LockMode lockMode) throws DataAccessException { - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - if (lockMode != null) { - session.lock(entity, lockMode); - } - session.delete(entity); - return null; - } - }); - } - - @Override - public void delete(String entityName, Object entity) throws DataAccessException { - delete(entityName, entity, null); - } - - @Override - public void delete(final String entityName, final Object entity, final LockMode lockMode) - throws DataAccessException { - - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - if (lockMode != null) { - session.lock(entityName, entity, lockMode); - } - session.delete(entityName, entity); - return null; - } - }); - } - - @Override - public void deleteAll(final Collection entities) throws DataAccessException { - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - checkWriteOperationAllowed(session); - for (Object entity : entities) { - session.delete(entity); - } - return null; - } - }); - } - - @Override - public void flush() throws DataAccessException { - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - session.flush(); - return null; - } - }); - } - - @Override - public void clear() throws DataAccessException { - executeWithNativeSession(new HibernateCallback() { - @Override - public Object doInHibernate(Session session) { - session.clear(); - return null; - } - }); - } - - - //------------------------------------------------------------------------- - // Convenience finder methods for HQL strings - //------------------------------------------------------------------------- - - @Override - public List find(String queryString) throws DataAccessException { - return find(queryString, (Object[]) null); - } - - @Override - public List find(String queryString, Object value) throws DataAccessException { - return find(queryString, new Object[] {value}); - } - - @Override - public List find(final String queryString, final Object... values) throws DataAccessException { - return executeWithNativeSession(new HibernateCallback>() { - @Override - public List doInHibernate(Session session) throws HibernateException { - Query queryObject = session.createQuery(queryString); - prepareQuery(queryObject); - if (values != null) { - for (int i = 0; i < values.length; i++) { - queryObject.setParameter(i, values[i]); - } - } - return queryObject.list(); - } - }); - } - - @Override - public List findByNamedParam(String queryString, String paramName, Object value) - throws DataAccessException { - - return findByNamedParam(queryString, new String[] {paramName}, new Object[] {value}); - } - - @Override - public List findByNamedParam(final String queryString, final String[] paramNames, final Object[] values) - throws DataAccessException { - - if (paramNames.length != values.length) { - throw new IllegalArgumentException("Length of paramNames array must match length of values array"); - } - return executeWithNativeSession(new HibernateCallback>() { - @Override - public List doInHibernate(Session session) throws HibernateException { - Query queryObject = session.createQuery(queryString); - prepareQuery(queryObject); - if (values != null) { - for (int i = 0; i < values.length; i++) { - applyNamedParameterToQuery(queryObject, paramNames[i], values[i]); - } - } - return queryObject.list(); - } - }); - } - - @Override - public List findByValueBean(final String queryString, final Object valueBean) - throws DataAccessException { - - return executeWithNativeSession(new HibernateCallback>() { - @Override - public List doInHibernate(Session session) throws HibernateException { - Query queryObject = session.createQuery(queryString); - prepareQuery(queryObject); - queryObject.setProperties(valueBean); - return queryObject.list(); - } - }); - } - - - //------------------------------------------------------------------------- - // Convenience finder methods for named queries - //------------------------------------------------------------------------- - - @Override - public List findByNamedQuery(String queryName) throws DataAccessException { - return findByNamedQuery(queryName, (Object[]) null); - } - - @Override - public List findByNamedQuery(String queryName, Object value) throws DataAccessException { - return findByNamedQuery(queryName, new Object[] {value}); - } - - @Override - public List findByNamedQuery(final String queryName, final Object... values) throws DataAccessException { - return executeWithNativeSession(new HibernateCallback>() { - @Override - public List doInHibernate(Session session) throws HibernateException { - Query queryObject = session.getNamedQuery(queryName); - prepareQuery(queryObject); - if (values != null) { - for (int i = 0; i < values.length; i++) { - queryObject.setParameter(i, values[i]); - } - } - return queryObject.list(); - } - }); - } - - @Override - public List findByNamedQueryAndNamedParam(String queryName, String paramName, Object value) - throws DataAccessException { - - return findByNamedQueryAndNamedParam(queryName, new String[] {paramName}, new Object[] {value}); - } - - @Override - public List findByNamedQueryAndNamedParam( - final String queryName, final String[] paramNames, final Object[] values) - throws DataAccessException { - - if (values != null && (paramNames == null || paramNames.length != values.length)) { - throw new IllegalArgumentException("Length of paramNames array must match length of values array"); - } - return executeWithNativeSession(new HibernateCallback>() { - @Override - public List doInHibernate(Session session) throws HibernateException { - Query queryObject = session.getNamedQuery(queryName); - prepareQuery(queryObject); - if (values != null) { - for (int i = 0; i < values.length; i++) { - applyNamedParameterToQuery(queryObject, paramNames[i], values[i]); - } - } - return queryObject.list(); - } - }); - } - - @Override - public List findByNamedQueryAndValueBean(final String queryName, final Object valueBean) - throws DataAccessException { - - return executeWithNativeSession(new HibernateCallback>() { - @Override - public List doInHibernate(Session session) throws HibernateException { - Query queryObject = session.getNamedQuery(queryName); - prepareQuery(queryObject); - queryObject.setProperties(valueBean); - return queryObject.list(); - } - }); - } - - - //------------------------------------------------------------------------- - // Convenience finder methods for detached criteria - //------------------------------------------------------------------------- - - @Override - public List findByCriteria(DetachedCriteria criteria) throws DataAccessException { - return findByCriteria(criteria, -1, -1); - } - - @Override - public List findByCriteria(final DetachedCriteria criteria, final int firstResult, final int maxResults) - throws DataAccessException { - - Assert.notNull(criteria, "DetachedCriteria must not be null"); - return executeWithNativeSession(new HibernateCallback>() { - @Override - public List doInHibernate(Session session) throws HibernateException { - Criteria executableCriteria = criteria.getExecutableCriteria(session); - prepareCriteria(executableCriteria); - if (firstResult >= 0) { - executableCriteria.setFirstResult(firstResult); - } - if (maxResults > 0) { - executableCriteria.setMaxResults(maxResults); - } - return executableCriteria.list(); - } - }); - } - - @Override - public List findByExample(T exampleEntity) throws DataAccessException { - return findByExample(null, exampleEntity, -1, -1); - } - - @Override - public List findByExample(String entityName, T exampleEntity) throws DataAccessException { - return findByExample(entityName, exampleEntity, -1, -1); - } - - @Override - public List findByExample(T exampleEntity, int firstResult, int maxResults) throws DataAccessException { - return findByExample(null, exampleEntity, firstResult, maxResults); - } - - @Override - public List findByExample( - final String entityName, final T exampleEntity, final int firstResult, final int maxResults) - throws DataAccessException { - - Assert.notNull(exampleEntity, "Example entity must not be null"); - return executeWithNativeSession(new HibernateCallback>() { - @Override - @SuppressWarnings("unchecked") - public List doInHibernate(Session session) throws HibernateException { - Criteria executableCriteria = (entityName != null ? - session.createCriteria(entityName) : session.createCriteria(exampleEntity.getClass())); - executableCriteria.add(Example.create(exampleEntity)); - prepareCriteria(executableCriteria); - if (firstResult >= 0) { - executableCriteria.setFirstResult(firstResult); - } - if (maxResults > 0) { - executableCriteria.setMaxResults(maxResults); - } - return executableCriteria.list(); - } - }); - } - - - //------------------------------------------------------------------------- - // Convenience query methods for iteration and bulk updates/deletes - //------------------------------------------------------------------------- - - @Override - public Iterator iterate(String queryString) throws DataAccessException { - return iterate(queryString, (Object[]) null); - } - - @Override - public Iterator iterate(String queryString, Object value) throws DataAccessException { - return iterate(queryString, new Object[] {value}); - } - - @Override - public Iterator iterate(final String queryString, final Object... values) throws DataAccessException { - return executeWithNativeSession(new HibernateCallback>() { - @Override - public Iterator doInHibernate(Session session) throws HibernateException { - Query queryObject = session.createQuery(queryString); - prepareQuery(queryObject); - if (values != null) { - for (int i = 0; i < values.length; i++) { - queryObject.setParameter(i, values[i]); - } - } - return queryObject.iterate(); - } - }); - } - - @Override - public void closeIterator(Iterator it) throws DataAccessException { - try { - Hibernate.close(it); - } - catch (HibernateException ex) { - throw SessionFactoryUtils.convertHibernateAccessException(ex); - } - } - - @Override - public int bulkUpdate(String queryString) throws DataAccessException { - return bulkUpdate(queryString, (Object[]) null); - } - - @Override - public int bulkUpdate(String queryString, Object value) throws DataAccessException { - return bulkUpdate(queryString, new Object[] {value}); - } - - @Override - public int bulkUpdate(final String queryString, final Object... values) throws DataAccessException { - return executeWithNativeSession(new HibernateCallback() { - @Override - public Integer doInHibernate(Session session) throws HibernateException { - Query queryObject = session.createQuery(queryString); - prepareQuery(queryObject); - if (values != null) { - for (int i = 0; i < values.length; i++) { - queryObject.setParameter(i, values[i]); - } - } - return queryObject.executeUpdate(); - } - }); - } - - - //------------------------------------------------------------------------- - // Helper methods used by the operations above - //------------------------------------------------------------------------- - - /** - * Check whether write operations are allowed on the given Session. - *

Default implementation throws an InvalidDataAccessApiUsageException in - * case of {@code FlushMode.MANUAL}. Can be overridden in subclasses. - * @param session current Hibernate Session - * @throws InvalidDataAccessApiUsageException if write operations are not allowed - * @see #setCheckWriteOperations - * @see #getFlushMode() - * @see #FLUSH_EAGER - * @see org.hibernate.Session#getFlushMode() - * @see org.hibernate.FlushMode#MANUAL - */ - protected void checkWriteOperationAllowed(Session session) throws InvalidDataAccessApiUsageException { - if (isCheckWriteOperations() && getFlushMode() != FLUSH_EAGER && - session.getFlushMode().lessThan(FlushMode.COMMIT)) { - throw new InvalidDataAccessApiUsageException( - "Write operations are not allowed in read-only mode (FlushMode.MANUAL): "+ - "Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition."); - } - } - - /** - * Prepare the given Query object, applying cache settings and/or - * a transaction timeout. - * @param queryObject the Query object to prepare - * @see #setCacheQueries - * @see #setQueryCacheRegion - * @see SessionFactoryUtils#applyTransactionTimeout - */ - protected void prepareQuery(Query queryObject) { - if (isCacheQueries()) { - queryObject.setCacheable(true); - if (getQueryCacheRegion() != null) { - queryObject.setCacheRegion(getQueryCacheRegion()); - } - } - if (getFetchSize() > 0) { - queryObject.setFetchSize(getFetchSize()); - } - if (getMaxResults() > 0) { - queryObject.setMaxResults(getMaxResults()); - } - SessionFactoryUtils.applyTransactionTimeout(queryObject, getSessionFactory()); - } - - /** - * Prepare the given Criteria object, applying cache settings and/or - * a transaction timeout. - * @param criteria the Criteria object to prepare - * @see #setCacheQueries - * @see #setQueryCacheRegion - * @see SessionFactoryUtils#applyTransactionTimeout - */ - protected void prepareCriteria(Criteria criteria) { - if (isCacheQueries()) { - criteria.setCacheable(true); - if (getQueryCacheRegion() != null) { - criteria.setCacheRegion(getQueryCacheRegion()); - } - } - if (getFetchSize() > 0) { - criteria.setFetchSize(getFetchSize()); - } - if (getMaxResults() > 0) { - criteria.setMaxResults(getMaxResults()); - } - SessionFactoryUtils.applyTransactionTimeout(criteria, getSessionFactory()); - } - - /** - * Apply the given name parameter to the given Query object. - * @param queryObject the Query object - * @param paramName the name of the parameter - * @param value the value of the parameter - * @throws HibernateException if thrown by the Query object - */ - protected void applyNamedParameterToQuery(Query queryObject, String paramName, Object value) - throws HibernateException { - - if (value instanceof Collection) { - queryObject.setParameterList(paramName, (Collection) value); - } - else if (value instanceof Object[]) { - queryObject.setParameterList(paramName, (Object[]) value); - } - else { - queryObject.setParameter(paramName, value); - } - } - - - /** - * Invocation handler that suppresses close calls on Hibernate Sessions. - * Also prepares returned Query and Criteria objects. - * @see org.hibernate.Session#close - */ - private class CloseSuppressingInvocationHandler implements InvocationHandler { - - private final Session target; - - public CloseSuppressingInvocationHandler(Session target) { - this.target = target; - } - - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - // Invocation on Session interface coming in... - - if (method.getName().equals("equals")) { - // Only consider equal when proxies are identical. - return (proxy == args[0]); - } - else if (method.getName().equals("hashCode")) { - // Use hashCode of Session proxy. - return System.identityHashCode(proxy); - } - else if (method.getName().equals("close")) { - // Handle close method: suppress, not valid. - return null; - } - - // Invoke method on target Session. - try { - Object retVal = method.invoke(this.target, args); - - // If return value is a Query or Criteria, apply transaction timeout. - // Applies to createQuery, getNamedQuery, createCriteria. - if (retVal instanceof Query) { - prepareQuery(((Query) retVal)); - } - if (retVal instanceof Criteria) { - prepareCriteria(((Criteria) retVal)); - } - - return retVal; - } - catch (InvocationTargetException ex) { - throw ex.getTargetException(); - } - } - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateTransactionManager.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateTransactionManager.java deleted file mode 100644 index c6f802e6f6..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateTransactionManager.java +++ /dev/null @@ -1,933 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import java.sql.Connection; -import javax.sql.DataSource; - -import org.hibernate.ConnectionReleaseMode; -import org.hibernate.FlushMode; -import org.hibernate.HibernateException; -import org.hibernate.Interceptor; -import org.hibernate.JDBCException; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.Transaction; -import org.hibernate.exception.GenericJDBCException; -import org.hibernate.impl.SessionImpl; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.dao.DataAccessException; -import org.springframework.dao.DataAccessResourceFailureException; -import org.springframework.jdbc.datasource.ConnectionHolder; -import org.springframework.jdbc.datasource.DataSourceUtils; -import org.springframework.jdbc.datasource.JdbcTransactionObjectSupport; -import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy; -import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator; -import org.springframework.jdbc.support.SQLExceptionTranslator; -import org.springframework.transaction.CannotCreateTransactionException; -import org.springframework.transaction.IllegalTransactionStateException; -import org.springframework.transaction.InvalidIsolationLevelException; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.TransactionSystemException; -import org.springframework.transaction.support.AbstractPlatformTransactionManager; -import org.springframework.transaction.support.DefaultTransactionStatus; -import org.springframework.transaction.support.ResourceTransactionManager; -import org.springframework.transaction.support.TransactionSynchronizationManager; - -/** - * {@link org.springframework.transaction.PlatformTransactionManager} - * implementation for a single Hibernate {@link org.hibernate.SessionFactory}. - * Binds a Hibernate Session from the specified factory to the thread, potentially - * allowing for one thread-bound Session per factory. {@link SessionFactoryUtils} - * and {@link HibernateTemplate} are aware of thread-bound Sessions and participate - * in such transactions automatically. Using either of those or going through - * {@code SessionFactory.getCurrentSession()} is required for Hibernate - * access code that needs to support this transaction handling mechanism. - * - *

Supports custom isolation levels, and timeouts that get applied as - * Hibernate transaction timeouts. - * - *

This transaction manager is appropriate for applications that use a single - * Hibernate SessionFactory for transactional data access, but it also supports - * direct DataSource access within a transaction (i.e. plain JDBC code working - * with the same DataSource). This allows for mixing services which access Hibernate - * and services which use plain JDBC (without being aware of Hibernate)! - * Application code needs to stick to the same simple Connection lookup pattern as - * with {@link org.springframework.jdbc.datasource.DataSourceTransactionManager} - * (i.e. {@link org.springframework.jdbc.datasource.DataSourceUtils#getConnection} - * or going through a - * {@link org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy}). - * - *

Note: To be able to register a DataSource's Connection for plain JDBC code, - * this instance needs to be aware of the DataSource ({@link #setDataSource}). - * The given DataSource should obviously match the one used by the given - * SessionFactory. To achieve this, configure both to the same JNDI DataSource, - * or preferably create the SessionFactory with {@link LocalSessionFactoryBean} and - * a local DataSource (which will be autodetected by this transaction manager). - * - *

JTA (usually through {@link org.springframework.transaction.jta.JtaTransactionManager}) - * is necessary for accessing multiple transactional resources within the same - * transaction. The DataSource that Hibernate uses needs to be JTA-enabled in - * such a scenario (see container setup). Normally, JTA setup for Hibernate is - * somewhat container-specific due to the JTA TransactionManager lookup, required - * for proper transactional handling of the SessionFactory-level read-write cache. - * - *

Fortunately, there is an easier way with Spring: {@link SessionFactoryUtils} - * (and thus {@link HibernateTemplate}) registers synchronizations with Spring's - * {@link org.springframework.transaction.support.TransactionSynchronizationManager} - * (as used by {@link org.springframework.transaction.jta.JtaTransactionManager}), - * for proper after-completion callbacks. Therefore, as long as Spring's - * JtaTransactionManager drives the JTA transactions, Hibernate does not require - * any special configuration for proper JTA participation. Note that there are - * special restrictions with EJB CMT and restrictive JTA subsystems: See - * {@link org.springframework.transaction.jta.JtaTransactionManager}'s javadoc for details. - * - *

This transaction manager supports nested transactions via JDBC 3.0 Savepoints. - * The {@link #setNestedTransactionAllowed} "nestedTransactionAllowed"} flag defaults - * to "false", though, as nested transactions will just apply to the JDBC Connection, - * not to the Hibernate Session and its cached entity objects and related context. - * You can manually set the flag to "true" if you want to use nested transactions - * for JDBC access code which participates in Hibernate transactions (provided that - * your JDBC driver supports Savepoints). Note that Hibernate itself does not - * support nested transactions! Hence, do not expect Hibernate access code to - * semantically participate in a nested transaction. - * - *

Requires Hibernate 3.6.x, as of Spring 4.0. - * - * @author Juergen Hoeller - * @since 1.2 - * @see #setSessionFactory - * @see #setDataSource - * @see LocalSessionFactoryBean - * @see SessionFactoryUtils#getSession - * @see SessionFactoryUtils#applyTransactionTimeout - * @see SessionFactoryUtils#releaseSession - * @see HibernateTemplate - * @see org.hibernate.SessionFactory#getCurrentSession() - * @see org.springframework.jdbc.datasource.DataSourceUtils#getConnection - * @see org.springframework.jdbc.datasource.DataSourceUtils#applyTransactionTimeout - * @see org.springframework.jdbc.datasource.DataSourceUtils#releaseConnection - * @see org.springframework.jdbc.core.JdbcTemplate - * @see org.springframework.jdbc.datasource.DataSourceTransactionManager - * @see org.springframework.transaction.jta.JtaTransactionManager - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -@SuppressWarnings("serial") -public class HibernateTransactionManager extends AbstractPlatformTransactionManager - implements ResourceTransactionManager, BeanFactoryAware, InitializingBean { - - private SessionFactory sessionFactory; - - private DataSource dataSource; - - private boolean autodetectDataSource = true; - - private boolean prepareConnection = true; - - private boolean hibernateManagedSession = false; - - private boolean earlyFlushBeforeCommit = false; - - private Object entityInterceptor; - - private SQLExceptionTranslator jdbcExceptionTranslator; - - private SQLExceptionTranslator defaultJdbcExceptionTranslator; - - /** - * Just needed for entityInterceptorBeanName. - * @see #setEntityInterceptorBeanName - */ - private BeanFactory beanFactory; - - - /** - * Create a new HibernateTransactionManager instance. - * A SessionFactory has to be set to be able to use it. - * @see #setSessionFactory - */ - public HibernateTransactionManager() { - } - - /** - * Create a new HibernateTransactionManager instance. - * @param sessionFactory SessionFactory to manage transactions for - */ - public HibernateTransactionManager(SessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; - afterPropertiesSet(); - } - - - /** - * Set the SessionFactory that this instance should manage transactions for. - */ - public void setSessionFactory(SessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; - } - - /** - * Return the SessionFactory that this instance should manage transactions for. - */ - public SessionFactory getSessionFactory() { - return this.sessionFactory; - } - - /** - * Set the JDBC DataSource that this instance should manage transactions for. - * The DataSource should match the one used by the Hibernate SessionFactory: - * for example, you could specify the same JNDI DataSource for both. - *

If the SessionFactory was configured with LocalDataSourceConnectionProvider, - * i.e. by Spring's LocalSessionFactoryBean with a specified "dataSource", - * the DataSource will be auto-detected: You can still explicitly specify the - * DataSource, but you don't need to in this case. - *

A transactional JDBC Connection for this DataSource will be provided to - * application code accessing this DataSource directly via DataSourceUtils - * or JdbcTemplate. The Connection will be taken from the Hibernate Session. - *

The DataSource specified here should be the target DataSource to manage - * transactions for, not a TransactionAwareDataSourceProxy. Only data access - * code may work with TransactionAwareDataSourceProxy, while the transaction - * manager needs to work on the underlying target DataSource. If there's - * nevertheless a TransactionAwareDataSourceProxy passed in, it will be - * unwrapped to extract its target DataSource. - * @see #setAutodetectDataSource - * @see LocalDataSourceConnectionProvider - * @see LocalSessionFactoryBean#setDataSource - * @see org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy - * @see org.springframework.jdbc.datasource.DataSourceUtils - * @see org.springframework.jdbc.core.JdbcTemplate - */ - public void setDataSource(DataSource dataSource) { - if (dataSource instanceof TransactionAwareDataSourceProxy) { - // If we got a TransactionAwareDataSourceProxy, we need to perform transactions - // for its underlying target DataSource, else data access code won't see - // properly exposed transactions (i.e. transactions for the target DataSource). - this.dataSource = ((TransactionAwareDataSourceProxy) dataSource).getTargetDataSource(); - } - else { - this.dataSource = dataSource; - } - } - - /** - * Return the JDBC DataSource that this instance manages transactions for. - */ - public DataSource getDataSource() { - return this.dataSource; - } - - /** - * Set whether to autodetect a JDBC DataSource used by the Hibernate SessionFactory, - * if set via LocalSessionFactoryBean's {@code setDataSource}. Default is "true". - *

Can be turned off to deliberately ignore an available DataSource, in order - * to not expose Hibernate transactions as JDBC transactions for that DataSource. - * @see #setDataSource - * @see LocalSessionFactoryBean#setDataSource - */ - public void setAutodetectDataSource(boolean autodetectDataSource) { - this.autodetectDataSource = autodetectDataSource; - } - - /** - * Set whether to prepare the underlying JDBC Connection of a transactional - * Hibernate Session, that is, whether to apply a transaction-specific - * isolation level and/or the transaction's read-only flag to the underlying - * JDBC Connection. - *

Default is "true". If you turn this flag off, the transaction manager - * will not support per-transaction isolation levels anymore. It will not - * call {@code Connection.setReadOnly(true)} for read-only transactions - * anymore either. If this flag is turned off, no cleanup of a JDBC Connection - * is required after a transaction, since no Connection settings will get modified. - * @see java.sql.Connection#setTransactionIsolation - * @see java.sql.Connection#setReadOnly - */ - public void setPrepareConnection(boolean prepareConnection) { - this.prepareConnection = prepareConnection; - } - - /** - * Set whether to operate on a Hibernate-managed Session instead of a - * Spring-managed Session, that is, whether to obtain the Session through - * Hibernate's {@link org.hibernate.SessionFactory#getCurrentSession()} - * instead of {@link org.hibernate.SessionFactory#openSession()} (with a Spring - * {@link org.springframework.transaction.support.TransactionSynchronizationManager} - * check preceding it). - *

Default is "false", i.e. using a Spring-managed Session: taking the current - * thread-bound Session if available (e.g. in an Open-Session-in-View scenario), - * creating a new Session for the current transaction otherwise. - *

Switch this flag to "true" in order to enforce use of a Hibernate-managed Session. - * Note that this requires {@link org.hibernate.SessionFactory#getCurrentSession()} - * to always return a proper Session when called for a Spring-managed transaction; - * transaction begin will fail if the {@code getCurrentSession()} call fails. - *

This mode will typically be used in combination with a custom Hibernate - * {@link org.hibernate.context.CurrentSessionContext} implementation that stores - * Sessions in a place other than Spring's TransactionSynchronizationManager. - * It may also be used in combination with Spring's Open-Session-in-View support - * (using Spring's default {@link SpringSessionContext}), in which case it subtly - * differs from the Spring-managed Session mode: The pre-bound Session will not - * receive a {@code clear()} call (on rollback) or a {@code disconnect()} - * call (on transaction completion) in such a scenario; this is rather left up - * to a custom CurrentSessionContext implementation (if desired). - */ - public void setHibernateManagedSession(boolean hibernateManagedSession) { - this.hibernateManagedSession = hibernateManagedSession; - } - - /** - * Set whether to perform an early flush before proceeding with a commit. - *

Default is "false", performing an implicit flush as part of the actual - * commit step. Switch this to "true" in order to enforce an explicit early - * flush right before the actual commit step. - *

An early flush happens before the before-commit synchronization phase, - * making flushed state visible to {@code beforeCommit} callbacks of registered - * {@link org.springframework.transaction.support.TransactionSynchronization} - * objects. Such explicit flush behavior is consistent with Spring-driven - * flushing in a JTA transaction environment, so may also get enforced for - * consistency with JTA transaction behavior. - * @see #prepareForCommit - */ - public void setEarlyFlushBeforeCommit(boolean earlyFlushBeforeCommit) { - this.earlyFlushBeforeCommit = earlyFlushBeforeCommit; - } - - /** - * Set the bean name of a Hibernate entity interceptor that allows to inspect - * and change property values before writing to and reading from the database. - * Will get applied to any new Session created by this transaction manager. - *

Requires the bean factory to be known, to be able to resolve the bean - * name to an interceptor instance on session creation. Typically used for - * prototype interceptors, i.e. a new interceptor instance per session. - *

Can also be used for shared interceptor instances, but it is recommended - * to set the interceptor reference directly in such a scenario. - * @param entityInterceptorBeanName the name of the entity interceptor in - * the bean factory - * @see #setBeanFactory - * @see #setEntityInterceptor - */ - public void setEntityInterceptorBeanName(String entityInterceptorBeanName) { - this.entityInterceptor = entityInterceptorBeanName; - } - - /** - * Set a Hibernate entity interceptor that allows to inspect and change - * property values before writing to and reading from the database. - * Will get applied to any new Session created by this transaction manager. - *

Such an interceptor can either be set at the SessionFactory level, - * i.e. on LocalSessionFactoryBean, or at the Session level, i.e. on - * HibernateTemplate, HibernateInterceptor, and HibernateTransactionManager. - * It's preferable to set it on LocalSessionFactoryBean or HibernateTransactionManager - * to avoid repeated configuration and guarantee consistent behavior in transactions. - * @see LocalSessionFactoryBean#setEntityInterceptor - * @see HibernateTemplate#setEntityInterceptor - * @see HibernateInterceptor#setEntityInterceptor - */ - public void setEntityInterceptor(Interceptor entityInterceptor) { - this.entityInterceptor = entityInterceptor; - } - - /** - * Return the current Hibernate entity interceptor, or {@code null} if none. - * Resolves an entity interceptor bean name via the bean factory, - * if necessary. - * @throws IllegalStateException if bean name specified but no bean factory set - * @throws BeansException if bean name resolution via the bean factory failed - * @see #setEntityInterceptor - * @see #setEntityInterceptorBeanName - * @see #setBeanFactory - */ - public Interceptor getEntityInterceptor() throws IllegalStateException, BeansException { - if (this.entityInterceptor instanceof Interceptor) { - return (Interceptor) entityInterceptor; - } - else if (this.entityInterceptor instanceof String) { - if (this.beanFactory == null) { - throw new IllegalStateException("Cannot get entity interceptor via bean name if no bean factory set"); - } - String beanName = (String) this.entityInterceptor; - return this.beanFactory.getBean(beanName, Interceptor.class); - } - else { - return null; - } - } - - /** - * Set the JDBC exception translator for this transaction manager. - *

Applied to any SQLException root cause of a Hibernate JDBCException that - * is thrown on flush, overriding Hibernate's default SQLException translation - * (which is based on Hibernate's Dialect for a specific target database). - * @param jdbcExceptionTranslator the exception translator - * @see java.sql.SQLException - * @see org.hibernate.JDBCException - * @see org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator - * @see org.springframework.jdbc.support.SQLStateSQLExceptionTranslator - */ - public void setJdbcExceptionTranslator(SQLExceptionTranslator jdbcExceptionTranslator) { - this.jdbcExceptionTranslator = jdbcExceptionTranslator; - } - - /** - * Return the JDBC exception translator for this transaction manager, if any. - */ - public SQLExceptionTranslator getJdbcExceptionTranslator() { - return this.jdbcExceptionTranslator; - } - - /** - * The bean factory just needs to be known for resolving entity interceptor - * bean names. It does not need to be set for any other mode of operation. - * @see #setEntityInterceptorBeanName - */ - @Override - public void setBeanFactory(BeanFactory beanFactory) { - this.beanFactory = beanFactory; - } - - @Override - public void afterPropertiesSet() { - if (getSessionFactory() == null) { - throw new IllegalArgumentException("Property 'sessionFactory' is required"); - } - if (this.entityInterceptor instanceof String && this.beanFactory == null) { - throw new IllegalArgumentException("Property 'beanFactory' is required for 'entityInterceptorBeanName'"); - } - - // Check for SessionFactory's DataSource. - if (this.autodetectDataSource && getDataSource() == null) { - DataSource sfds = SessionFactoryUtils.getDataSource(getSessionFactory()); - if (sfds != null) { - // Use the SessionFactory's DataSource for exposing transactions to JDBC code. - if (logger.isInfoEnabled()) { - logger.info("Using DataSource [" + sfds + - "] of Hibernate SessionFactory for HibernateTransactionManager"); - } - setDataSource(sfds); - } - } - } - - - @Override - public Object getResourceFactory() { - return getSessionFactory(); - } - - @Override - protected Object doGetTransaction() { - HibernateTransactionObject txObject = new HibernateTransactionObject(); - txObject.setSavepointAllowed(isNestedTransactionAllowed()); - - SessionHolder sessionHolder = - (SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory()); - if (sessionHolder != null) { - if (logger.isDebugEnabled()) { - logger.debug("Found thread-bound Session [" + - SessionFactoryUtils.toString(sessionHolder.getSession()) + "] for Hibernate transaction"); - } - txObject.setSessionHolder(sessionHolder); - } - else if (this.hibernateManagedSession) { - try { - Session session = getSessionFactory().getCurrentSession(); - if (logger.isDebugEnabled()) { - logger.debug("Found Hibernate-managed Session [" + - SessionFactoryUtils.toString(session) + "] for Spring-managed transaction"); - } - txObject.setExistingSession(session); - } - catch (HibernateException ex) { - throw new DataAccessResourceFailureException( - "Could not obtain Hibernate-managed Session for Spring-managed transaction", ex); - } - } - - if (getDataSource() != null) { - ConnectionHolder conHolder = (ConnectionHolder) - TransactionSynchronizationManager.getResource(getDataSource()); - txObject.setConnectionHolder(conHolder); - } - - return txObject; - } - - @Override - protected boolean isExistingTransaction(Object transaction) { - HibernateTransactionObject txObject = (HibernateTransactionObject) transaction; - return (txObject.hasSpringManagedTransaction() || - (this.hibernateManagedSession && txObject.hasHibernateManagedTransaction())); - } - - @Override - protected void doBegin(Object transaction, TransactionDefinition definition) { - HibernateTransactionObject txObject = (HibernateTransactionObject) transaction; - - if (txObject.hasConnectionHolder() && !txObject.getConnectionHolder().isSynchronizedWithTransaction()) { - throw new IllegalTransactionStateException( - "Pre-bound JDBC Connection found! HibernateTransactionManager does not support " + - "running within DataSourceTransactionManager if told to manage the DataSource itself. " + - "It is recommended to use a single HibernateTransactionManager for all transactions " + - "on a single DataSource, no matter whether Hibernate or JDBC access."); - } - - Session session = null; - - try { - if (txObject.getSessionHolder() == null || txObject.getSessionHolder().isSynchronizedWithTransaction()) { - Interceptor entityInterceptor = getEntityInterceptor(); - Session newSession = (entityInterceptor != null ? - getSessionFactory().openSession(entityInterceptor) : getSessionFactory().openSession()); - if (logger.isDebugEnabled()) { - logger.debug("Opened new Session [" + SessionFactoryUtils.toString(newSession) + - "] for Hibernate transaction"); - } - txObject.setSession(newSession); - } - - session = txObject.getSessionHolder().getSession(); - - if (this.prepareConnection && isSameConnectionForEntireSession(session)) { - // We're allowed to change the transaction settings of the JDBC Connection. - if (logger.isDebugEnabled()) { - logger.debug( - "Preparing JDBC Connection of Hibernate Session [" + SessionFactoryUtils.toString(session) + "]"); - } - Connection con = session.connection(); - Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition); - txObject.setPreviousIsolationLevel(previousIsolationLevel); - } - else { - // Not allowed to change the transaction settings of the JDBC Connection. - if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) { - // We should set a specific isolation level but are not allowed to... - throw new InvalidIsolationLevelException( - "HibernateTransactionManager is not allowed to support custom isolation levels: " + - "make sure that its 'prepareConnection' flag is on (the default) and that the " + - "Hibernate connection release mode is set to 'on_close' (SpringTransactionFactory's default). " + - "Make sure that your LocalSessionFactoryBean actually uses SpringTransactionFactory: Your " + - "Hibernate properties should *not* include a 'hibernate.transaction.factory_class' property!"); - } - if (logger.isDebugEnabled()) { - logger.debug( - "Not preparing JDBC Connection of Hibernate Session [" + SessionFactoryUtils.toString(session) + "]"); - } - } - - if (definition.isReadOnly() && txObject.isNewSession()) { - // Just set to MANUAL in case of a new Session for this transaction. - session.setFlushMode(FlushMode.MANUAL); - } - - if (!definition.isReadOnly() && !txObject.isNewSession()) { - // We need AUTO or COMMIT for a non-read-only transaction. - FlushMode flushMode = session.getFlushMode(); - if (flushMode.lessThan(FlushMode.COMMIT)) { - session.setFlushMode(FlushMode.AUTO); - txObject.getSessionHolder().setPreviousFlushMode(flushMode); - } - } - - Transaction hibTx; - - // Register transaction timeout. - int timeout = determineTimeout(definition); - if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) { - // Use Hibernate's own transaction timeout mechanism on Hibernate 3.1+ - // Applies to all statements, also to inserts, updates and deletes! - hibTx = session.getTransaction(); - hibTx.setTimeout(timeout); - hibTx.begin(); - } - else { - // Open a plain Hibernate transaction without specified timeout. - hibTx = session.beginTransaction(); - } - - // Add the Hibernate transaction to the session holder. - txObject.getSessionHolder().setTransaction(hibTx); - - // Register the Hibernate Session's JDBC Connection for the DataSource, if set. - if (getDataSource() != null) { - Connection con = session.connection(); - ConnectionHolder conHolder = new ConnectionHolder(con); - if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) { - conHolder.setTimeoutInSeconds(timeout); - } - if (logger.isDebugEnabled()) { - logger.debug("Exposing Hibernate transaction as JDBC transaction [" + con + "]"); - } - TransactionSynchronizationManager.bindResource(getDataSource(), conHolder); - txObject.setConnectionHolder(conHolder); - } - - // Bind the session holder to the thread. - if (txObject.isNewSessionHolder()) { - TransactionSynchronizationManager.bindResource(getSessionFactory(), txObject.getSessionHolder()); - } - txObject.getSessionHolder().setSynchronizedWithTransaction(true); - } - - catch (Throwable ex) { - if (txObject.isNewSession()) { - try { - if (session.getTransaction().isActive()) { - session.getTransaction().rollback(); - } - } - catch (Throwable ex2) { - logger.debug("Could not rollback Session after failed transaction begin", ex); - } - finally { - SessionFactoryUtils.closeSession(session); - txObject.setSessionHolder(null); - } - } - throw new CannotCreateTransactionException("Could not open Hibernate Session for transaction", ex); - } - } - - @Override - protected Object doSuspend(Object transaction) { - HibernateTransactionObject txObject = (HibernateTransactionObject) transaction; - txObject.setSessionHolder(null); - SessionHolder sessionHolder = - (SessionHolder) TransactionSynchronizationManager.unbindResource(getSessionFactory()); - txObject.setConnectionHolder(null); - ConnectionHolder connectionHolder = null; - if (getDataSource() != null) { - connectionHolder = (ConnectionHolder) TransactionSynchronizationManager.unbindResource(getDataSource()); - } - return new SuspendedResourcesHolder(sessionHolder, connectionHolder); - } - - @Override - protected void doResume(Object transaction, Object suspendedResources) { - SuspendedResourcesHolder resourcesHolder = (SuspendedResourcesHolder) suspendedResources; - if (TransactionSynchronizationManager.hasResource(getSessionFactory())) { - // From non-transactional code running in active transaction synchronization - // -> can be safely removed, will be closed on transaction completion. - TransactionSynchronizationManager.unbindResource(getSessionFactory()); - } - TransactionSynchronizationManager.bindResource(getSessionFactory(), resourcesHolder.getSessionHolder()); - if (getDataSource() != null) { - TransactionSynchronizationManager.bindResource(getDataSource(), resourcesHolder.getConnectionHolder()); - } - } - - @Override - protected void prepareForCommit(DefaultTransactionStatus status) { - if (this.earlyFlushBeforeCommit && status.isNewTransaction()) { - HibernateTransactionObject txObject = (HibernateTransactionObject) status.getTransaction(); - Session session = txObject.getSessionHolder().getSession(); - if (!session.getFlushMode().lessThan(FlushMode.COMMIT)) { - logger.debug("Performing an early flush for Hibernate transaction"); - try { - session.flush(); - } - catch (HibernateException ex) { - throw convertHibernateAccessException(ex); - } - finally { - session.setFlushMode(FlushMode.MANUAL); - } - } - } - } - - @Override - protected void doCommit(DefaultTransactionStatus status) { - HibernateTransactionObject txObject = (HibernateTransactionObject) status.getTransaction(); - if (status.isDebug()) { - logger.debug("Committing Hibernate transaction on Session [" + - SessionFactoryUtils.toString(txObject.getSessionHolder().getSession()) + "]"); - } - try { - txObject.getSessionHolder().getTransaction().commit(); - } - catch (org.hibernate.TransactionException ex) { - // assumably from commit call to the underlying JDBC connection - throw new TransactionSystemException("Could not commit Hibernate transaction", ex); - } - catch (HibernateException ex) { - // assumably failed to flush changes to database - throw convertHibernateAccessException(ex); - } - } - - @Override - protected void doRollback(DefaultTransactionStatus status) { - HibernateTransactionObject txObject = (HibernateTransactionObject) status.getTransaction(); - if (status.isDebug()) { - logger.debug("Rolling back Hibernate transaction on Session [" + - SessionFactoryUtils.toString(txObject.getSessionHolder().getSession()) + "]"); - } - try { - txObject.getSessionHolder().getTransaction().rollback(); - } - catch (org.hibernate.TransactionException ex) { - throw new TransactionSystemException("Could not roll back Hibernate transaction", ex); - } - catch (HibernateException ex) { - // Shouldn't really happen, as a rollback doesn't cause a flush. - throw convertHibernateAccessException(ex); - } - finally { - if (!txObject.isNewSession() && !this.hibernateManagedSession) { - // Clear all pending inserts/updates/deletes in the Session. - // Necessary for pre-bound Sessions, to avoid inconsistent state. - txObject.getSessionHolder().getSession().clear(); - } - } - } - - @Override - protected void doSetRollbackOnly(DefaultTransactionStatus status) { - HibernateTransactionObject txObject = (HibernateTransactionObject) status.getTransaction(); - if (status.isDebug()) { - logger.debug("Setting Hibernate transaction on Session [" + - SessionFactoryUtils.toString(txObject.getSessionHolder().getSession()) + "] rollback-only"); - } - txObject.setRollbackOnly(); - } - - @Override - protected void doCleanupAfterCompletion(Object transaction) { - HibernateTransactionObject txObject = (HibernateTransactionObject) transaction; - - // Remove the session holder from the thread. - if (txObject.isNewSessionHolder()) { - TransactionSynchronizationManager.unbindResource(getSessionFactory()); - } - - // Remove the JDBC connection holder from the thread, if exposed. - if (getDataSource() != null) { - TransactionSynchronizationManager.unbindResource(getDataSource()); - } - - Session session = txObject.getSessionHolder().getSession(); - if (this.prepareConnection && session.isConnected() && isSameConnectionForEntireSession(session)) { - // We're running with connection release mode "on_close": We're able to reset - // the isolation level and/or read-only flag of the JDBC Connection here. - // Else, we need to rely on the connection pool to perform proper cleanup. - try { - Connection con = session.connection(); - DataSourceUtils.resetConnectionAfterTransaction(con, txObject.getPreviousIsolationLevel()); - } - catch (HibernateException ex) { - logger.debug("Could not access JDBC Connection of Hibernate Session", ex); - } - } - - if (txObject.isNewSession()) { - if (logger.isDebugEnabled()) { - logger.debug("Closing Hibernate Session [" + SessionFactoryUtils.toString(session) + - "] after transaction"); - } - SessionFactoryUtils.closeSessionOrRegisterDeferredClose(session, getSessionFactory()); - } - else { - if (logger.isDebugEnabled()) { - logger.debug("Not closing pre-bound Hibernate Session [" + - SessionFactoryUtils.toString(session) + "] after transaction"); - } - if (txObject.getSessionHolder().getPreviousFlushMode() != null) { - session.setFlushMode(txObject.getSessionHolder().getPreviousFlushMode()); - } - if (!this.hibernateManagedSession) { - session.disconnect(); - } - } - txObject.getSessionHolder().clear(); - } - - /** - * Return whether the given Hibernate Session will always hold the same - * JDBC Connection. This is used to check whether the transaction manager - * can safely prepare and clean up the JDBC Connection used for a transaction. - *

Default implementation checks the Session's connection release mode - * to be "on_close". Unfortunately, this requires casting to SessionImpl, - * as of Hibernate 3.1. If that cast doesn't work, we'll simply assume - * we're safe and return {@code true}. - * @param session the Hibernate Session to check - * @see org.hibernate.impl.SessionImpl#getConnectionReleaseMode() - * @see org.hibernate.ConnectionReleaseMode#ON_CLOSE - */ - protected boolean isSameConnectionForEntireSession(Session session) { - if (!(session instanceof SessionImpl)) { - // The best we can do is to assume we're safe. - return true; - } - ConnectionReleaseMode releaseMode = ((SessionImpl) session).getConnectionReleaseMode(); - return ConnectionReleaseMode.ON_CLOSE.equals(releaseMode); - } - - - /** - * Convert the given HibernateException to an appropriate exception - * from the {@code org.springframework.dao} hierarchy. - *

Will automatically apply a specified SQLExceptionTranslator to a - * Hibernate JDBCException, else rely on Hibernate's default translation. - * @param ex HibernateException that occurred - * @return a corresponding DataAccessException - * @see SessionFactoryUtils#convertHibernateAccessException - * @see #setJdbcExceptionTranslator - */ - protected DataAccessException convertHibernateAccessException(HibernateException ex) { - if (getJdbcExceptionTranslator() != null && ex instanceof JDBCException) { - return convertJdbcAccessException((JDBCException) ex, getJdbcExceptionTranslator()); - } - else if (GenericJDBCException.class == ex.getClass()) { - return convertJdbcAccessException((GenericJDBCException) ex, getDefaultJdbcExceptionTranslator()); - } - return SessionFactoryUtils.convertHibernateAccessException(ex); - } - - /** - * Convert the given Hibernate JDBCException to an appropriate exception - * from the {@code org.springframework.dao} hierarchy, using the - * given SQLExceptionTranslator. - * @param ex Hibernate JDBCException that occurred - * @param translator the SQLExceptionTranslator to use - * @return a corresponding DataAccessException - */ - protected DataAccessException convertJdbcAccessException(JDBCException ex, SQLExceptionTranslator translator) { - return translator.translate("Hibernate flushing: " + ex.getMessage(), ex.getSQL(), ex.getSQLException()); - } - - /** - * Obtain a default SQLExceptionTranslator, lazily creating it if necessary. - *

Creates a default - * {@link org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator} - * for the SessionFactory's underlying DataSource. - */ - protected synchronized SQLExceptionTranslator getDefaultJdbcExceptionTranslator() { - if (this.defaultJdbcExceptionTranslator == null) { - if (getDataSource() != null) { - this.defaultJdbcExceptionTranslator = new SQLErrorCodeSQLExceptionTranslator(getDataSource()); - } - else { - this.defaultJdbcExceptionTranslator = SessionFactoryUtils.newJdbcExceptionTranslator(getSessionFactory()); - } - } - return this.defaultJdbcExceptionTranslator; - } - - - /** - * Hibernate transaction object, representing a SessionHolder. - * Used as transaction object by HibernateTransactionManager. - */ - private class HibernateTransactionObject extends JdbcTransactionObjectSupport { - - private SessionHolder sessionHolder; - - private boolean newSessionHolder; - - private boolean newSession; - - public void setSession(Session session) { - this.sessionHolder = new SessionHolder(session); - this.newSessionHolder = true; - this.newSession = true; - } - - public void setExistingSession(Session session) { - this.sessionHolder = new SessionHolder(session); - this.newSessionHolder = true; - this.newSession = false; - } - - public void setSessionHolder(SessionHolder sessionHolder) { - this.sessionHolder = sessionHolder; - this.newSessionHolder = false; - this.newSession = false; - } - - public SessionHolder getSessionHolder() { - return this.sessionHolder; - } - - public boolean isNewSessionHolder() { - return this.newSessionHolder; - } - - public boolean isNewSession() { - return this.newSession; - } - - public boolean hasSpringManagedTransaction() { - return (this.sessionHolder != null && this.sessionHolder.getTransaction() != null); - } - - public boolean hasHibernateManagedTransaction() { - return (this.sessionHolder != null && this.sessionHolder.getSession().getTransaction().isActive()); - } - - public void setRollbackOnly() { - this.sessionHolder.setRollbackOnly(); - if (hasConnectionHolder()) { - getConnectionHolder().setRollbackOnly(); - } - } - - @Override - public boolean isRollbackOnly() { - return this.sessionHolder.isRollbackOnly() || - (hasConnectionHolder() && getConnectionHolder().isRollbackOnly()); - } - - @Override - public void flush() { - try { - this.sessionHolder.getSession().flush(); - } - catch (HibernateException ex) { - throw convertHibernateAccessException(ex); - } - } - } - - - /** - * Holder for suspended resources. - * Used internally by {@code doSuspend} and {@code doResume}. - */ - private static class SuspendedResourcesHolder { - - private final SessionHolder sessionHolder; - - private final ConnectionHolder connectionHolder; - - private SuspendedResourcesHolder(SessionHolder sessionHolder, ConnectionHolder conHolder) { - this.sessionHolder = sessionHolder; - this.connectionHolder = conHolder; - } - - private SessionHolder getSessionHolder() { - return this.sessionHolder; - } - - private ConnectionHolder getConnectionHolder() { - return this.connectionHolder; - } - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/LocalDataSourceConnectionProvider.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/LocalDataSourceConnectionProvider.java deleted file mode 100644 index 411d3857d2..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/LocalDataSourceConnectionProvider.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import java.sql.Connection; -import java.sql.SQLException; -import java.util.Properties; -import javax.sql.DataSource; - -import org.hibernate.HibernateException; -import org.hibernate.connection.ConnectionProvider; -import org.hibernate.util.JDBCExceptionReporter; - -import org.springframework.jdbc.datasource.DataSourceUtils; - -/** - * Hibernate connection provider for local DataSource instances - * in an application context. This provider will be used if - * LocalSessionFactoryBean's "dataSource" property is set - * without a Hibernate TransactionManagerLookup. - * - * @author Juergen Hoeller - * @since 1.2 - * @see LocalSessionFactoryBean#setDataSource - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public class LocalDataSourceConnectionProvider implements ConnectionProvider { - - private DataSource dataSource; - - private DataSource dataSourceToUse; - - - @Override - public void configure(Properties props) throws HibernateException { - this.dataSource = LocalSessionFactoryBean.getConfigTimeDataSource(); - // absolutely needs thread-bound DataSource to initialize - if (this.dataSource == null) { - throw new HibernateException("No local DataSource found for configuration - " + - "'dataSource' property must be set on LocalSessionFactoryBean"); - } - this.dataSourceToUse = getDataSourceToUse(this.dataSource); - } - - /** - * Return the DataSource to use for retrieving Connections. - *

This implementation returns the passed-in DataSource as-is. - * @param originalDataSource the DataSource as configured by the user - * on LocalSessionFactoryBean - * @return the DataSource to actually retrieve Connections from - * (potentially wrapped) - * @see LocalSessionFactoryBean#setDataSource - */ - protected DataSource getDataSourceToUse(DataSource originalDataSource) { - return originalDataSource; - } - - /** - * Return the DataSource that this ConnectionProvider wraps. - */ - public DataSource getDataSource() { - return this.dataSource; - } - - /** - * This implementation delegates to the underlying DataSource. - * @see javax.sql.DataSource#getConnection() - */ - @Override - public Connection getConnection() throws SQLException { - try { - return this.dataSourceToUse.getConnection(); - } - catch (SQLException ex) { - JDBCExceptionReporter.logExceptions(ex); - throw ex; - } - } - - /** - * This implementation calls {@link DataSourceUtils#doCloseConnection}, - * checking against a {@link org.springframework.jdbc.datasource.SmartDataSource}. - */ - @Override - public void closeConnection(Connection con) throws SQLException { - try { - DataSourceUtils.doCloseConnection(con, this.dataSourceToUse); - } - catch (SQLException ex) { - JDBCExceptionReporter.logExceptions(ex); - throw ex; - } - } - - /** - * This implementation does nothing: - * We're dealing with an externally managed DataSource. - */ - @Override - public void close() { - } - - /** - * This implementation returns {@code false}: We cannot guarantee - * to receive the same Connection within a transaction, not even when - * dealing with a JNDI DataSource. - */ - @Override - public boolean supportsAggressiveRelease() { - return false; - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/LocalJtaDataSourceConnectionProvider.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/LocalJtaDataSourceConnectionProvider.java deleted file mode 100644 index 817be9d7cb..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/LocalJtaDataSourceConnectionProvider.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -/** - * Subclass of LocalDataSourceConnectionProvider that will be used - * if LocalSessionFactoryBean's "dataSource" property is set - * in combination with a Hibernate TransactionManagerLookup. - * - * @author Juergen Hoeller - * @since 2.5.1 - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public class LocalJtaDataSourceConnectionProvider extends LocalDataSourceConnectionProvider { - - /** - * This implementation returns {@code true}, - * since we're assuming a JTA DataSource. - */ - @Override - public boolean supportsAggressiveRelease() { - return true; - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/LocalRegionFactoryProxy.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/LocalRegionFactoryProxy.java deleted file mode 100644 index 73e0b5bf76..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/LocalRegionFactoryProxy.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import java.util.Properties; - -import org.hibernate.cache.CacheDataDescription; -import org.hibernate.cache.CacheException; -import org.hibernate.cache.CollectionRegion; -import org.hibernate.cache.EntityRegion; -import org.hibernate.cache.QueryResultsRegion; -import org.hibernate.cache.RegionFactory; -import org.hibernate.cache.TimestampsRegion; -import org.hibernate.cache.access.AccessType; -import org.hibernate.cfg.Settings; - -/** - * Proxy for a Hibernate RegionFactory, delegating to a Spring-managed - * RegionFactory instance, determined by LocalSessionFactoryBean's - * "cacheRegionFactory" property. - * - * @author Juergen Hoeller - * @since 3.0 - * @see LocalSessionFactoryBean#setCacheRegionFactory - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public class LocalRegionFactoryProxy implements RegionFactory { - - private final RegionFactory regionFactory; - - - /** - * Standard constructor. - */ - public LocalRegionFactoryProxy() { - RegionFactory rf = (RegionFactory) LocalSessionFactoryBean.getConfigTimeRegionFactory(); - // absolutely needs thread-bound RegionFactory to initialize - if (rf == null) { - throw new IllegalStateException("No Hibernate RegionFactory found - " + - "'cacheRegionFactory' property must be set on LocalSessionFactoryBean"); - } - this.regionFactory = rf; - } - - /** - * Properties constructor: not used by this class or formally required, - * but enforced by Hibernate when reflectively instantiating a RegionFactory. - */ - public LocalRegionFactoryProxy(Properties properties) { - this(); - } - - - @Override - public void start(Settings settings, Properties properties) throws CacheException { - this.regionFactory.start(settings, properties); - } - - @Override - public void stop() { - this.regionFactory.stop(); - } - - @Override - public boolean isMinimalPutsEnabledByDefault() { - return this.regionFactory.isMinimalPutsEnabledByDefault(); - } - - @Override - public AccessType getDefaultAccessType() { - return this.regionFactory.getDefaultAccessType(); - } - - @Override - public long nextTimestamp() { - return this.regionFactory.nextTimestamp(); - } - - @Override - public EntityRegion buildEntityRegion(String regionName, Properties properties, CacheDataDescription metadata) - throws CacheException { - - return this.regionFactory.buildEntityRegion(regionName, properties, metadata); - } - - @Override - public CollectionRegion buildCollectionRegion(String regionName, Properties properties, - CacheDataDescription metadata) throws CacheException { - - return this.regionFactory.buildCollectionRegion(regionName, properties, metadata); - } - - @Override - public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) - throws CacheException { - - return this.regionFactory.buildQueryResultsRegion(regionName, properties); - } - - @Override - public TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) - throws CacheException { - - return this.regionFactory.buildTimestampsRegion(regionName, properties); - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/LocalSessionFactoryBean.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/LocalSessionFactoryBean.java deleted file mode 100644 index 81b3b246bf..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/LocalSessionFactoryBean.java +++ /dev/null @@ -1,1067 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import java.io.File; -import java.lang.reflect.Array; -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Collection; -import java.util.Enumeration; -import java.util.Map; -import java.util.Properties; -import javax.sql.DataSource; -import javax.transaction.TransactionManager; - -import org.hibernate.HibernateException; -import org.hibernate.Interceptor; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.cache.RegionFactory; -import org.hibernate.cfg.Configuration; -import org.hibernate.cfg.Environment; -import org.hibernate.cfg.Mappings; -import org.hibernate.cfg.NamingStrategy; -import org.hibernate.dialect.Dialect; -import org.hibernate.engine.FilterDefinition; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.event.EventListeners; -import org.hibernate.tool.hbm2ddl.DatabaseMetadata; -import org.hibernate.transaction.JTATransactionFactory; - -import org.springframework.beans.BeanUtils; -import org.springframework.beans.factory.BeanClassLoaderAware; -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; -import org.springframework.dao.DataAccessException; -import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy; -import org.springframework.jdbc.support.JdbcUtils; -import org.springframework.jdbc.support.lob.LobHandler; -import org.springframework.util.ClassUtils; -import org.springframework.util.StringUtils; - -/** - * {@link org.springframework.beans.factory.FactoryBean} that creates a - * Hibernate {@link org.hibernate.SessionFactory}. This is the usual way to - * set up a shared Hibernate SessionFactory in a Spring application context; - * the SessionFactory can then be passed to Hibernate-based DAOs via - * dependency injection. - * - *

Configuration settings can either be read from a Hibernate XML file, - * specified as "configLocation", or completely via this class. A typical - * local configuration consists of one or more "mappingResources", various - * "hibernateProperties" (not strictly necessary), and a "dataSource" that the - * SessionFactory should use. The latter can also be specified via Hibernate - * properties, but "dataSource" supports any Spring-configured DataSource, - * instead of relying on Hibernate's own connection providers. - * - *

This SessionFactory handling strategy is appropriate for most types of - * applications, from Hibernate-only single database apps to ones that need - * distributed transactions. Either {@link HibernateTransactionManager} or - * {@link org.springframework.transaction.jta.JtaTransactionManager} can be - * used for transaction demarcation, with the latter only necessary for - * transactions which span multiple databases. - * - *

This factory bean will by default expose a transaction-aware SessionFactory - * proxy, letting data access code work with the plain Hibernate SessionFactory - * and its {@code getCurrentSession()} method, while still being able to - * participate in current Spring-managed transactions: with any transaction - * management strategy, either local or JTA / EJB CMT, and any transaction - * synchronization mechanism, either Spring or JTA. Furthermore, - * {@code getCurrentSession()} will also seamlessly work with - * a request-scoped Session managed by - * {@link org.springframework.orm.hibernate3.support.OpenSessionInViewFilter} / - * {@link org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor}. - * - *

Requires Hibernate 3.6.x, as of Spring 4.0. - * Note that this factory will use "on_close" as default Hibernate connection - * release mode, unless in the case of a "jtaTransactionManager" specified, - * for the reason that this is appropriate for most Spring-based applications - * (in particular when using Spring's HibernateTransactionManager). - * - * @author Juergen Hoeller - * @since 1.2 - * @see HibernateTemplate#setSessionFactory - * @see HibernateTransactionManager#setSessionFactory - * @see #setExposeTransactionAwareSessionFactory - * @see #setJtaTransactionManager - * @see org.hibernate.SessionFactory#getCurrentSession() - * @see HibernateTransactionManager - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public class LocalSessionFactoryBean extends AbstractSessionFactoryBean implements BeanClassLoaderAware { - - private static final ThreadLocal configTimeDataSourceHolder = - new ThreadLocal(); - - private static final ThreadLocal configTimeTransactionManagerHolder = - new ThreadLocal(); - - private static final ThreadLocal configTimeRegionFactoryHolder = - new ThreadLocal(); - - private static final ThreadLocal configTimeLobHandlerHolder = - new ThreadLocal(); - - /** - * Return the DataSource for the currently configured Hibernate SessionFactory, - * to be used by LocalDataSourceConnectionProvoder. - *

This instance will be set before initialization of the corresponding - * SessionFactory, and reset immediately afterwards. It is thus only available - * during configuration. - * @see #setDataSource - * @see LocalDataSourceConnectionProvider - */ - public static DataSource getConfigTimeDataSource() { - return configTimeDataSourceHolder.get(); - } - - /** - * Return the JTA TransactionManager for the currently configured Hibernate - * SessionFactory, to be used by LocalTransactionManagerLookup. - *

This instance will be set before initialization of the corresponding - * SessionFactory, and reset immediately afterwards. It is thus only available - * during configuration. - * @see #setJtaTransactionManager - * @see LocalTransactionManagerLookup - */ - public static TransactionManager getConfigTimeTransactionManager() { - return configTimeTransactionManagerHolder.get(); - } - - /** - * Return the RegionFactory for the currently configured Hibernate SessionFactory, - * to be used by LocalRegionFactoryProxy. - *

This instance will be set before initialization of the corresponding - * SessionFactory, and reset immediately afterwards. It is thus only available - * during configuration. - * @see #setCacheRegionFactory - */ - static Object getConfigTimeRegionFactory() { - return configTimeRegionFactoryHolder.get(); - } - - /** - * Return the LobHandler for the currently configured Hibernate SessionFactory, - * to be used by UserType implementations like ClobStringType. - *

This instance will be set before initialization of the corresponding - * SessionFactory, and reset immediately afterwards. It is thus only available - * during configuration. - * @see #setLobHandler - * @see org.springframework.orm.hibernate3.support.ClobStringType - * @see org.springframework.orm.hibernate3.support.BlobByteArrayType - * @see org.springframework.orm.hibernate3.support.BlobSerializableType - */ - public static LobHandler getConfigTimeLobHandler() { - return configTimeLobHandlerHolder.get(); - } - - - private Class configurationClass = Configuration.class; - - private Resource[] configLocations; - - private String[] mappingResources; - - private Resource[] mappingLocations; - - private Resource[] cacheableMappingLocations; - - private Resource[] mappingJarLocations; - - private Resource[] mappingDirectoryLocations; - - private Properties hibernateProperties; - - private TransactionManager jtaTransactionManager; - - private RegionFactory cacheRegionFactory; - - private LobHandler lobHandler; - - private Interceptor entityInterceptor; - - private NamingStrategy namingStrategy; - - private TypeDefinitionBean[] typeDefinitions; - - private FilterDefinition[] filterDefinitions; - - private Properties entityCacheStrategies; - - private Properties collectionCacheStrategies; - - private Map eventListeners; - - private boolean schemaUpdate = false; - - private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); - - private Configuration configuration; - - - /** - * Specify the Hibernate Configuration class to use. - *

Default is {@link org.hibernate.cfg.Configuration}; any subclass - * of this default Hibernate Configuration class can be specified. - */ - @SuppressWarnings("unchecked") - public void setConfigurationClass(Class configurationClass) { - if (configurationClass == null || !Configuration.class.isAssignableFrom(configurationClass)) { - throw new IllegalArgumentException( - "'configurationClass' must be assignable to [org.hibernate.cfg.Configuration]"); - } - this.configurationClass = (Class) configurationClass; - } - - /** - * Set the location of a single Hibernate XML config file, for example as - * classpath resource "classpath:hibernate.cfg.xml". - *

Note: Can be omitted when all necessary properties and mapping - * resources are specified locally via this bean. - * @see org.hibernate.cfg.Configuration#configure(java.net.URL) - */ - public void setConfigLocation(Resource configLocation) { - this.configLocations = new Resource[] {configLocation}; - } - - /** - * Set the locations of multiple Hibernate XML config files, for example as - * classpath resources "classpath:hibernate.cfg.xml,classpath:extension.cfg.xml". - *

Note: Can be omitted when all necessary properties and mapping - * resources are specified locally via this bean. - * @see org.hibernate.cfg.Configuration#configure(java.net.URL) - */ - public void setConfigLocations(Resource... configLocations) { - this.configLocations = configLocations; - } - - /** - * Set Hibernate mapping resources to be found in the class path, - * like "example.hbm.xml" or "mypackage/example.hbm.xml". - * Analogous to mapping entries in a Hibernate XML config file. - * Alternative to the more generic setMappingLocations method. - *

Can be used to add to mappings from a Hibernate XML config file, - * or to specify all mappings locally. - * @see #setMappingLocations - * @see org.hibernate.cfg.Configuration#addResource - */ - public void setMappingResources(String... mappingResources) { - this.mappingResources = mappingResources; - } - - /** - * Set locations of Hibernate mapping files, for example as classpath - * resource "classpath:example.hbm.xml". Supports any resource location - * via Spring's resource abstraction, for example relative paths like - * "WEB-INF/mappings/example.hbm.xml" when running in an application context. - *

Can be used to add to mappings from a Hibernate XML config file, - * or to specify all mappings locally. - * @see org.hibernate.cfg.Configuration#addInputStream - */ - public void setMappingLocations(Resource... mappingLocations) { - this.mappingLocations = mappingLocations; - } - - /** - * Set locations of cacheable Hibernate mapping files, for example as web app - * resource "/WEB-INF/mapping/example.hbm.xml". Supports any resource location - * via Spring's resource abstraction, as long as the resource can be resolved - * in the file system. - *

Can be used to add to mappings from a Hibernate XML config file, - * or to specify all mappings locally. - * @see org.hibernate.cfg.Configuration#addCacheableFile(java.io.File) - */ - public void setCacheableMappingLocations(Resource... cacheableMappingLocations) { - this.cacheableMappingLocations = cacheableMappingLocations; - } - - /** - * Set locations of jar files that contain Hibernate mapping resources, - * like "WEB-INF/lib/example.hbm.jar". - *

Can be used to add to mappings from a Hibernate XML config file, - * or to specify all mappings locally. - * @see org.hibernate.cfg.Configuration#addJar(java.io.File) - */ - public void setMappingJarLocations(Resource... mappingJarLocations) { - this.mappingJarLocations = mappingJarLocations; - } - - /** - * Set locations of directories that contain Hibernate mapping resources, - * like "WEB-INF/mappings". - *

Can be used to add to mappings from a Hibernate XML config file, - * or to specify all mappings locally. - * @see org.hibernate.cfg.Configuration#addDirectory(java.io.File) - */ - public void setMappingDirectoryLocations(Resource... mappingDirectoryLocations) { - this.mappingDirectoryLocations = mappingDirectoryLocations; - } - - /** - * Set Hibernate properties, such as "hibernate.dialect". - *

Can be used to override values in a Hibernate XML config file, - * or to specify all necessary properties locally. - *

Note: Do not specify a transaction provider here when using - * Spring-driven transactions. It is also advisable to omit connection - * provider settings and use a Spring-set DataSource instead. - * @see #setDataSource - */ - public void setHibernateProperties(Properties hibernateProperties) { - this.hibernateProperties = hibernateProperties; - } - - /** - * Return the Hibernate properties, if any. Mainly available for - * configuration through property paths that specify individual keys. - */ - public Properties getHibernateProperties() { - if (this.hibernateProperties == null) { - this.hibernateProperties = new Properties(); - } - return this.hibernateProperties; - } - - /** - * Set the JTA TransactionManager to be used for Hibernate's - * TransactionManagerLookup. Allows for using a Spring-managed - * JTA TransactionManager for Hibernate's cache synchronization. - *

Note: If this is set, the Hibernate settings should not define a - * transaction manager lookup to avoid meaningless double configuration. - * @see LocalTransactionManagerLookup - */ - public void setJtaTransactionManager(TransactionManager jtaTransactionManager) { - this.jtaTransactionManager = jtaTransactionManager; - } - - /** - * Set the Hibernate RegionFactory to use for the SessionFactory. - * Allows for using a Spring-managed RegionFactory instance. - *

Note: If this is set, the Hibernate settings should not define a - * cache provider to avoid meaningless double configuration. - * @see org.hibernate.cache.RegionFactory - */ - public void setCacheRegionFactory(RegionFactory cacheRegionFactory) { - this.cacheRegionFactory = cacheRegionFactory; - } - - /** - * Set the LobHandler to be used by the SessionFactory. - * Will be exposed at config time for UserType implementations. - * @see #getConfigTimeLobHandler - * @see org.hibernate.usertype.UserType - * @see org.springframework.orm.hibernate3.support.ClobStringType - * @see org.springframework.orm.hibernate3.support.BlobByteArrayType - * @see org.springframework.orm.hibernate3.support.BlobSerializableType - */ - public void setLobHandler(LobHandler lobHandler) { - this.lobHandler = lobHandler; - } - - /** - * Set a Hibernate entity interceptor that allows to inspect and change - * property values before writing to and reading from the database. - * Will get applied to any new Session created by this factory. - *

Such an interceptor can either be set at the SessionFactory level, i.e. on - * LocalSessionFactoryBean, or at the Session level, i.e. on HibernateTemplate, - * HibernateInterceptor, and HibernateTransactionManager. It's preferable to set - * it on LocalSessionFactoryBean or HibernateTransactionManager to avoid repeated - * configuration and guarantee consistent behavior in transactions. - * @see HibernateTemplate#setEntityInterceptor - * @see HibernateInterceptor#setEntityInterceptor - * @see HibernateTransactionManager#setEntityInterceptor - * @see org.hibernate.cfg.Configuration#setInterceptor - */ - public void setEntityInterceptor(Interceptor entityInterceptor) { - this.entityInterceptor = entityInterceptor; - } - - /** - * Set a Hibernate NamingStrategy for the SessionFactory, determining the - * physical column and table names given the info in the mapping document. - * @see org.hibernate.cfg.Configuration#setNamingStrategy - */ - public void setNamingStrategy(NamingStrategy namingStrategy) { - this.namingStrategy = namingStrategy; - } - - /** - * Specify the Hibernate type definitions to register with the SessionFactory, - * as Spring TypeDefinitionBean instances. This is an alternative to specifying - * <<typedef> elements in Hibernate mapping files. - *

Unfortunately, Hibernate itself does not define a complete object that - * represents a type definition, hence the need for Spring's TypeDefinitionBean. - * @see TypeDefinitionBean - * @see org.hibernate.cfg.Mappings#addTypeDef(String, String, java.util.Properties) - */ - public void setTypeDefinitions(TypeDefinitionBean... typeDefinitions) { - this.typeDefinitions = typeDefinitions; - } - - /** - * Specify the Hibernate FilterDefinitions to register with the SessionFactory. - * This is an alternative to specifying <<filter-def> elements in - * Hibernate mapping files. - *

Typically, the passed-in FilterDefinition objects will have been defined - * as Spring FilterDefinitionFactoryBeans, probably as inner beans within the - * LocalSessionFactoryBean definition. - * @see FilterDefinitionFactoryBean - * @see org.hibernate.cfg.Configuration#addFilterDefinition - */ - public void setFilterDefinitions(FilterDefinition... filterDefinitions) { - this.filterDefinitions = filterDefinitions; - } - - /** - * Specify the cache strategies for entities (persistent classes or named entities). - * This configuration setting corresponds to the <class-cache> entry - * in the "hibernate.cfg.xml" configuration format. - *

For example: - *

-	 * <property name="entityCacheStrategies">
-	 *   <props>
-	 *     <prop key="com.mycompany.Customer">read-write</prop>
-	 *     <prop key="com.mycompany.Product">read-only,myRegion</prop>
-	 *   </props>
-	 * </property>
- * @param entityCacheStrategies properties that define entity cache strategies, - * with class names as keys and cache concurrency strategies as values - * @see org.hibernate.cfg.Configuration#setCacheConcurrencyStrategy(String, String) - */ - public void setEntityCacheStrategies(Properties entityCacheStrategies) { - this.entityCacheStrategies = entityCacheStrategies; - } - - /** - * Specify the cache strategies for persistent collections (with specific roles). - * This configuration setting corresponds to the <collection-cache> entry - * in the "hibernate.cfg.xml" configuration format. - *

For example: - *

-	 * <property name="collectionCacheStrategies">
-	 *   <props>
-	 *     <prop key="com.mycompany.Order.items">read-write</prop>
-	 *     <prop key="com.mycompany.Product.categories">read-only,myRegion</prop>
-	 *   </props>
-	 * </property>
- * @param collectionCacheStrategies properties that define collection cache strategies, - * with collection roles as keys and cache concurrency strategies as values - * @see org.hibernate.cfg.Configuration#setCollectionCacheConcurrencyStrategy(String, String) - */ - public void setCollectionCacheStrategies(Properties collectionCacheStrategies) { - this.collectionCacheStrategies = collectionCacheStrategies; - } - - /** - * Specify the Hibernate event listeners to register, with listener types - * as keys and listener objects as values. Instead of a single listener object, - * you can also pass in a list or set of listeners objects as value. - *

See the Hibernate documentation for further details on listener types - * and associated listener interfaces. - *

See {@code org.hibernate.cfg.Configuration#setListener(String, Object)} - * @param eventListeners Map with listener type Strings as keys and - * listener objects as values - */ - public void setEventListeners(Map eventListeners) { - this.eventListeners = eventListeners; - } - - /** - * Set whether to execute a schema update after SessionFactory initialization. - *

For details on how to make schema update scripts work, see the Hibernate - * documentation, as this class leverages the same schema update script support - * in org.hibernate.cfg.Configuration as Hibernate's own SchemaUpdate tool. - * @see org.hibernate.cfg.Configuration#generateSchemaUpdateScript - * @see org.hibernate.tool.hbm2ddl.SchemaUpdate - */ - public void setSchemaUpdate(boolean schemaUpdate) { - this.schemaUpdate = schemaUpdate; - } - - @Override - public void setBeanClassLoader(ClassLoader beanClassLoader) { - this.beanClassLoader = beanClassLoader; - } - - - @Override - @SuppressWarnings("unchecked") - protected SessionFactory buildSessionFactory() throws Exception { - // Create Configuration instance. - Configuration config = newConfiguration(); - - DataSource dataSource = getDataSource(); - if (dataSource != null) { - // Make given DataSource available for SessionFactory configuration. - configTimeDataSourceHolder.set(dataSource); - } - if (this.jtaTransactionManager != null) { - // Make Spring-provided JTA TransactionManager available. - configTimeTransactionManagerHolder.set(this.jtaTransactionManager); - } - if (this.cacheRegionFactory != null) { - // Make Spring-provided Hibernate RegionFactory available. - configTimeRegionFactoryHolder.set(this.cacheRegionFactory); - } - if (this.lobHandler != null) { - // Make given LobHandler available for SessionFactory configuration. - // Do early because mapping resource might refer to custom types. - configTimeLobHandlerHolder.set(this.lobHandler); - } - - // Analogous to Hibernate EntityManager's Ejb3Configuration: - // Hibernate doesn't allow setting the bean ClassLoader explicitly, - // so we need to expose it as thread context ClassLoader accordingly. - Thread currentThread = Thread.currentThread(); - ClassLoader threadContextClassLoader = currentThread.getContextClassLoader(); - boolean overrideClassLoader = - (this.beanClassLoader != null && !this.beanClassLoader.equals(threadContextClassLoader)); - if (overrideClassLoader) { - currentThread.setContextClassLoader(this.beanClassLoader); - } - - try { - if (isExposeTransactionAwareSessionFactory()) { - // Set Hibernate 3.1+ CurrentSessionContext implementation, - // providing the Spring-managed Session as current Session. - // Can be overridden by a custom value for the corresponding Hibernate property. - config.setProperty( - Environment.CURRENT_SESSION_CONTEXT_CLASS, SpringSessionContext.class.getName()); - } - - if (this.jtaTransactionManager != null) { - // Set Spring-provided JTA TransactionManager as Hibernate property. - config.setProperty( - Environment.TRANSACTION_STRATEGY, JTATransactionFactory.class.getName()); - config.setProperty( - Environment.TRANSACTION_MANAGER_STRATEGY, LocalTransactionManagerLookup.class.getName()); - } - else { - // Makes the Hibernate Session aware of the presence of a Spring-managed transaction. - // Also sets connection release mode to ON_CLOSE by default. - config.setProperty( - Environment.TRANSACTION_STRATEGY, SpringTransactionFactory.class.getName()); - } - - if (this.entityInterceptor != null) { - // Set given entity interceptor at SessionFactory level. - config.setInterceptor(this.entityInterceptor); - } - - if (this.namingStrategy != null) { - // Pass given naming strategy to Hibernate Configuration. - config.setNamingStrategy(this.namingStrategy); - } - - if (this.typeDefinitions != null) { - // Register specified Hibernate type definitions. - Mappings mappings = config.createMappings(); - for (TypeDefinitionBean typeDef : this.typeDefinitions) { - mappings.addTypeDef(typeDef.getTypeName(), typeDef.getTypeClass(), typeDef.getParameters()); - } - } - - if (this.filterDefinitions != null) { - // Register specified Hibernate FilterDefinitions. - for (FilterDefinition filterDef : this.filterDefinitions) { - config.addFilterDefinition(filterDef); - } - } - - if (this.configLocations != null) { - for (Resource resource : this.configLocations) { - // Load Hibernate configuration from given location. - config.configure(resource.getURL()); - } - } - - if (this.hibernateProperties != null) { - // Add given Hibernate properties to Configuration. - config.addProperties(this.hibernateProperties); - } - - if (dataSource != null) { - Class providerClass = LocalDataSourceConnectionProvider.class; - if (isUseTransactionAwareDataSource() || dataSource instanceof TransactionAwareDataSourceProxy) { - providerClass = TransactionAwareDataSourceConnectionProvider.class; - } - else if (config.getProperty(Environment.TRANSACTION_MANAGER_STRATEGY) != null) { - providerClass = LocalJtaDataSourceConnectionProvider.class; - } - // Set Spring-provided DataSource as Hibernate ConnectionProvider. - config.setProperty(Environment.CONNECTION_PROVIDER, providerClass.getName()); - } - - if (this.cacheRegionFactory != null) { - // Expose Spring-provided Hibernate RegionFactory. - config.setProperty(Environment.CACHE_REGION_FACTORY, LocalRegionFactoryProxy.class.getName()); - } - - if (this.mappingResources != null) { - // Register given Hibernate mapping definitions, contained in resource files. - for (String mapping : this.mappingResources) { - Resource resource = new ClassPathResource(mapping.trim(), this.beanClassLoader); - config.addInputStream(resource.getInputStream()); - } - } - - if (this.mappingLocations != null) { - // Register given Hibernate mapping definitions, contained in resource files. - for (Resource resource : this.mappingLocations) { - config.addInputStream(resource.getInputStream()); - } - } - - if (this.cacheableMappingLocations != null) { - // Register given cacheable Hibernate mapping definitions, read from the file system. - for (Resource resource : this.cacheableMappingLocations) { - config.addCacheableFile(resource.getFile()); - } - } - - if (this.mappingJarLocations != null) { - // Register given Hibernate mapping definitions, contained in jar files. - for (Resource resource : this.mappingJarLocations) { - config.addJar(resource.getFile()); - } - } - - if (this.mappingDirectoryLocations != null) { - // Register all Hibernate mapping definitions in the given directories. - for (Resource resource : this.mappingDirectoryLocations) { - File file = resource.getFile(); - if (!file.isDirectory()) { - throw new IllegalArgumentException( - "Mapping directory location [" + resource + "] does not denote a directory"); - } - config.addDirectory(file); - } - } - - // Tell Hibernate to eagerly compile the mappings that we registered, - // for availability of the mapping information in further processing. - postProcessMappings(config); - config.buildMappings(); - - if (this.entityCacheStrategies != null) { - // Register cache strategies for mapped entities. - for (Enumeration classNames = this.entityCacheStrategies.propertyNames(); classNames.hasMoreElements();) { - String className = (String) classNames.nextElement(); - String[] strategyAndRegion = - StringUtils.commaDelimitedListToStringArray(this.entityCacheStrategies.getProperty(className)); - if (strategyAndRegion.length > 1) { - config.setCacheConcurrencyStrategy(className, strategyAndRegion[0], strategyAndRegion[1]); - } - else if (strategyAndRegion.length > 0) { - config.setCacheConcurrencyStrategy(className, strategyAndRegion[0]); - } - } - } - - if (this.collectionCacheStrategies != null) { - // Register cache strategies for mapped collections. - for (Enumeration collRoles = this.collectionCacheStrategies.propertyNames(); collRoles.hasMoreElements();) { - String collRole = (String) collRoles.nextElement(); - String[] strategyAndRegion = - StringUtils.commaDelimitedListToStringArray(this.collectionCacheStrategies.getProperty(collRole)); - if (strategyAndRegion.length > 1) { - config.setCollectionCacheConcurrencyStrategy(collRole, strategyAndRegion[0], strategyAndRegion[1]); - } - else if (strategyAndRegion.length > 0) { - config.setCollectionCacheConcurrencyStrategy(collRole, strategyAndRegion[0]); - } - } - } - - if (this.eventListeners != null) { - // Register specified Hibernate event listeners. - for (Map.Entry entry : this.eventListeners.entrySet()) { - String listenerType = entry.getKey(); - Object listenerObject = entry.getValue(); - if (listenerObject instanceof Collection) { - Collection listeners = (Collection) listenerObject; - EventListeners listenerRegistry = config.getEventListeners(); - Object[] listenerArray = - (Object[]) Array.newInstance(listenerRegistry.getListenerClassFor(listenerType), listeners.size()); - listenerArray = listeners.toArray(listenerArray); - config.setListeners(listenerType, listenerArray); - } - else { - config.setListener(listenerType, listenerObject); - } - } - } - - // Perform custom post-processing in subclasses. - postProcessConfiguration(config); - - // Build SessionFactory instance. - logger.info("Building new Hibernate SessionFactory"); - this.configuration = config; - return newSessionFactory(config); - } - - finally { - if (dataSource != null) { - configTimeDataSourceHolder.remove(); - } - if (this.jtaTransactionManager != null) { - configTimeTransactionManagerHolder.remove(); - } - if (this.cacheRegionFactory != null) { - configTimeRegionFactoryHolder.remove(); - } - if (this.lobHandler != null) { - configTimeLobHandlerHolder.remove(); - } - if (overrideClassLoader) { - // Reset original thread context ClassLoader. - currentThread.setContextClassLoader(threadContextClassLoader); - } - } - } - - /** - * Subclasses can override this method to perform custom initialization - * of the Configuration instance used for SessionFactory creation. - * The properties of this LocalSessionFactoryBean will be applied to - * the Configuration object that gets returned here. - *

The default implementation creates a new Configuration instance. - * A custom implementation could prepare the instance in a specific way, - * or use a custom Configuration subclass. - * @return the Configuration instance - * @throws HibernateException in case of Hibernate initialization errors - * @see org.hibernate.cfg.Configuration#Configuration() - */ - protected Configuration newConfiguration() throws HibernateException { - return BeanUtils.instantiateClass(this.configurationClass); - } - - /** - * To be implemented by subclasses that want to register further mappings - * on the Configuration object after this FactoryBean registered its specified - * mappings. - *

Invoked before the {@code Configuration.buildMappings()} call, - * so that it can still extend and modify the mapping information. - * @param config the current Configuration object - * @throws HibernateException in case of Hibernate initialization errors - * @see org.hibernate.cfg.Configuration#buildMappings() - */ - protected void postProcessMappings(Configuration config) throws HibernateException { - } - - /** - * To be implemented by subclasses that want to perform custom - * post-processing of the Configuration object after this FactoryBean - * performed its default initialization. - *

Invoked after the {@code Configuration.buildMappings()} call, - * so that it can operate on the completed and fully parsed mapping information. - * @param config the current Configuration object - * @throws HibernateException in case of Hibernate initialization errors - * @see org.hibernate.cfg.Configuration#buildMappings() - */ - protected void postProcessConfiguration(Configuration config) throws HibernateException { - } - - /** - * Subclasses can override this method to perform custom initialization - * of the SessionFactory instance, creating it via the given Configuration - * object that got prepared by this LocalSessionFactoryBean. - *

The default implementation invokes Configuration's buildSessionFactory. - * A custom implementation could prepare the instance in a specific way, - * or use a custom SessionFactoryImpl subclass. - * @param config Configuration prepared by this LocalSessionFactoryBean - * @return the SessionFactory instance - * @throws HibernateException in case of Hibernate initialization errors - * @see org.hibernate.cfg.Configuration#buildSessionFactory - */ - protected SessionFactory newSessionFactory(Configuration config) throws HibernateException { - return config.buildSessionFactory(); - } - - /** - * Return the Configuration object used to build the SessionFactory. - * Allows for access to configuration metadata stored there (rarely needed). - * @throws IllegalStateException if the Configuration object has not been initialized yet - */ - public final Configuration getConfiguration() { - if (this.configuration == null) { - throw new IllegalStateException("Configuration not initialized yet"); - } - return this.configuration; - } - - /** - * Executes schema update if requested. - * @see #setSchemaUpdate - * @see #updateDatabaseSchema() - */ - @Override - protected void afterSessionFactoryCreation() throws Exception { - if (this.schemaUpdate) { - updateDatabaseSchema(); - } - } - - /** - * Allows for schema export on shutdown. - */ - @Override - public void destroy() throws HibernateException { - DataSource dataSource = getDataSource(); - if (dataSource != null) { - // Make given DataSource available for potential SchemaExport, - // which unfortunately reinstantiates a ConnectionProvider. - configTimeDataSourceHolder.set(dataSource); - } - try { - super.destroy(); - } - finally { - if (dataSource != null) { - // Reset DataSource holder. - configTimeDataSourceHolder.remove(); - } - } - } - - - /** - * Execute schema update script, determined by the Configuration object - * used for creating the SessionFactory. A replacement for Hibernate's - * SchemaUpdate class, for automatically executing schema update scripts - * on application startup. Can also be invoked manually. - *

Fetch the LocalSessionFactoryBean itself rather than the exposed - * SessionFactory to be able to invoke this method, e.g. via - * {@code LocalSessionFactoryBean lsfb = (LocalSessionFactoryBean) ctx.getBean("&mySessionFactory");}. - *

Uses the SessionFactory that this bean generates for accessing a - * JDBC connection to perform the script. - * @throws DataAccessException in case of script execution errors - * @see #setSchemaUpdate - * @see org.hibernate.cfg.Configuration#generateSchemaUpdateScript - * @see org.hibernate.tool.hbm2ddl.SchemaUpdate - */ - public void updateDatabaseSchema() throws DataAccessException { - logger.info("Updating database schema for Hibernate SessionFactory"); - DataSource dataSource = getDataSource(); - if (dataSource != null) { - // Make given DataSource available for the schema update. - configTimeDataSourceHolder.set(dataSource); - } - try { - SessionFactory sessionFactory = getSessionFactory(); - final Dialect dialect = ((SessionFactoryImplementor) sessionFactory).getDialect(); - HibernateTemplate hibernateTemplate = new HibernateTemplate(sessionFactory); - hibernateTemplate.setFlushMode(HibernateTemplate.FLUSH_NEVER); - hibernateTemplate.execute( - new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException, SQLException { - Connection con = session.connection(); - DatabaseMetadata metadata = new DatabaseMetadata(con, dialect); - String[] sql = getConfiguration().generateSchemaUpdateScript(dialect, metadata); - executeSchemaScript(con, sql); - return null; - } - } - ); - } - finally { - if (dataSource != null) { - configTimeDataSourceHolder.remove(); - } - } - } - - /** - * Execute schema creation script, determined by the Configuration object - * used for creating the SessionFactory. A replacement for Hibernate's - * SchemaValidator class, to be invoked after application startup. - *

Fetch the LocalSessionFactoryBean itself rather than the exposed - * SessionFactory to be able to invoke this method, e.g. via - * {@code LocalSessionFactoryBean lsfb = (LocalSessionFactoryBean) ctx.getBean("&mySessionFactory");}. - *

Uses the SessionFactory that this bean generates for accessing a - * JDBC connection to perform the script. - * @throws DataAccessException in case of script execution errors - * @see org.hibernate.cfg.Configuration#validateSchema - * @see org.hibernate.tool.hbm2ddl.SchemaValidator - */ - public void validateDatabaseSchema() throws DataAccessException { - logger.info("Validating database schema for Hibernate SessionFactory"); - DataSource dataSource = getDataSource(); - if (dataSource != null) { - // Make given DataSource available for the schema update. - configTimeDataSourceHolder.set(dataSource); - } - try { - SessionFactory sessionFactory = getSessionFactory(); - final Dialect dialect = ((SessionFactoryImplementor) sessionFactory).getDialect(); - HibernateTemplate hibernateTemplate = new HibernateTemplate(sessionFactory); - hibernateTemplate.setFlushMode(HibernateTemplate.FLUSH_NEVER); - hibernateTemplate.execute( - new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException, SQLException { - Connection con = session.connection(); - DatabaseMetadata metadata = new DatabaseMetadata(con, dialect, false); - getConfiguration().validateSchema(dialect, metadata); - return null; - } - } - ); - } - finally { - if (dataSource != null) { - configTimeDataSourceHolder.remove(); - } - } - } - - /** - * Execute schema drop script, determined by the Configuration object - * used for creating the SessionFactory. A replacement for Hibernate's - * SchemaExport class, to be invoked on application setup. - *

Fetch the LocalSessionFactoryBean itself rather than the exposed - * SessionFactory to be able to invoke this method, e.g. via - * {@code LocalSessionFactoryBean lsfb = (LocalSessionFactoryBean) ctx.getBean("&mySessionFactory");}. - *

Uses the SessionFactory that this bean generates for accessing a - * JDBC connection to perform the script. - * @throws org.springframework.dao.DataAccessException in case of script execution errors - * @see org.hibernate.cfg.Configuration#generateDropSchemaScript - * @see org.hibernate.tool.hbm2ddl.SchemaExport#drop - */ - public void dropDatabaseSchema() throws DataAccessException { - logger.info("Dropping database schema for Hibernate SessionFactory"); - SessionFactory sessionFactory = getSessionFactory(); - final Dialect dialect = ((SessionFactoryImplementor) sessionFactory).getDialect(); - HibernateTemplate hibernateTemplate = new HibernateTemplate(sessionFactory); - hibernateTemplate.execute( - new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException, SQLException { - Connection con = session.connection(); - String[] sql = getConfiguration().generateDropSchemaScript(dialect); - executeSchemaScript(con, sql); - return null; - } - } - ); - } - - /** - * Execute schema creation script, determined by the Configuration object - * used for creating the SessionFactory. A replacement for Hibernate's - * SchemaExport class, to be invoked on application setup. - *

Fetch the LocalSessionFactoryBean itself rather than the exposed - * SessionFactory to be able to invoke this method, e.g. via - * {@code LocalSessionFactoryBean lsfb = (LocalSessionFactoryBean) ctx.getBean("&mySessionFactory");}. - *

Uses the SessionFactory that this bean generates for accessing a - * JDBC connection to perform the script. - * @throws DataAccessException in case of script execution errors - * @see org.hibernate.cfg.Configuration#generateSchemaCreationScript - * @see org.hibernate.tool.hbm2ddl.SchemaExport#create - */ - public void createDatabaseSchema() throws DataAccessException { - logger.info("Creating database schema for Hibernate SessionFactory"); - DataSource dataSource = getDataSource(); - if (dataSource != null) { - // Make given DataSource available for the schema update. - configTimeDataSourceHolder.set(dataSource); - } - try { - SessionFactory sessionFactory = getSessionFactory(); - final Dialect dialect = ((SessionFactoryImplementor) sessionFactory).getDialect(); - HibernateTemplate hibernateTemplate = new HibernateTemplate(sessionFactory); - hibernateTemplate.execute( - new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException, SQLException { - Connection con = session.connection(); - String[] sql = getConfiguration().generateSchemaCreationScript(dialect); - executeSchemaScript(con, sql); - return null; - } - } - ); - } - finally { - if (dataSource != null) { - configTimeDataSourceHolder.remove(); - } - } - } - - /** - * Execute the given schema script on the given JDBC Connection. - *

Note that the default implementation will log unsuccessful statements - * and continue to execute. Override the {@code executeSchemaStatement} - * method to treat failures differently. - * @param con the JDBC Connection to execute the script on - * @param sql the SQL statements to execute - * @throws SQLException if thrown by JDBC methods - * @see #executeSchemaStatement - */ - protected void executeSchemaScript(Connection con, String[] sql) throws SQLException { - if (sql != null && sql.length > 0) { - boolean oldAutoCommit = con.getAutoCommit(); - if (!oldAutoCommit) { - con.setAutoCommit(true); - } - try { - Statement stmt = con.createStatement(); - try { - for (String sqlStmt : sql) { - executeSchemaStatement(stmt, sqlStmt); - } - } - finally { - JdbcUtils.closeStatement(stmt); - } - } - finally { - if (!oldAutoCommit) { - con.setAutoCommit(false); - } - } - } - } - - /** - * Execute the given schema SQL on the given JDBC Statement. - *

Note that the default implementation will log unsuccessful statements - * and continue to execute. Override this method to treat failures differently. - * @param stmt the JDBC Statement to execute the SQL on - * @param sql the SQL statement to execute - * @throws SQLException if thrown by JDBC methods (and considered fatal) - */ - protected void executeSchemaStatement(Statement stmt, String sql) throws SQLException { - if (logger.isDebugEnabled()) { - logger.debug("Executing schema statement: " + sql); - } - try { - stmt.executeUpdate(sql); - } - catch (SQLException ex) { - if (logger.isWarnEnabled()) { - logger.warn("Unsuccessful schema statement: " + sql, ex); - } - } - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/LocalTransactionManagerLookup.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/LocalTransactionManagerLookup.java deleted file mode 100644 index fbfcf3c593..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/LocalTransactionManagerLookup.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import java.util.Properties; -import javax.transaction.Transaction; -import javax.transaction.TransactionManager; - -import org.hibernate.transaction.TransactionManagerLookup; - -/** - * Implementation of Hibernate's {@link TransactionManagerLookup} interface - * that returns a Spring-managed JTA {@link TransactionManager}, determined - * by LocalSessionFactoryBean's "jtaTransactionManager" property. - * - *

The main advantage of this TransactionManagerLookup is that it avoids - * double configuration of JTA specifics. A single TransactionManager bean can - * be used for both JtaTransactionManager and LocalSessionFactoryBean, with no - * JTA setup in Hibernate configuration. - * - *

Alternatively, use Hibernate's own TransactionManagerLookup implementations: - * Spring's JtaTransactionManager only requires a TransactionManager for suspending - * and resuming transactions, so you might not need to apply such special Spring - * configuration at all. - * - * @author Juergen Hoeller - * @since 1.2 - * @see LocalSessionFactoryBean#setJtaTransactionManager - * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public class LocalTransactionManagerLookup implements TransactionManagerLookup { - - private final TransactionManager transactionManager; - - - public LocalTransactionManagerLookup() { - TransactionManager tm = LocalSessionFactoryBean.getConfigTimeTransactionManager(); - // absolutely needs thread-bound TransactionManager to initialize - if (tm == null) { - throw new IllegalStateException("No JTA TransactionManager found - " + - "'jtaTransactionManager' property must be set on LocalSessionFactoryBean"); - } - this.transactionManager = tm; - } - - @Override - public TransactionManager getTransactionManager(Properties props) { - return this.transactionManager; - } - - @Override - public String getUserTransactionName() { - return null; - } - - @Override - public Object getTransactionIdentifier(Transaction transaction) { - return transaction; - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/SessionFactoryUtils.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/SessionFactoryUtils.java deleted file mode 100644 index 2286a904c3..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/SessionFactoryUtils.java +++ /dev/null @@ -1,832 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; -import javax.sql.DataSource; -import javax.transaction.Status; -import javax.transaction.Transaction; -import javax.transaction.TransactionManager; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.hibernate.Criteria; -import org.hibernate.FlushMode; -import org.hibernate.HibernateException; -import org.hibernate.Interceptor; -import org.hibernate.JDBCException; -import org.hibernate.NonUniqueObjectException; -import org.hibernate.NonUniqueResultException; -import org.hibernate.ObjectDeletedException; -import org.hibernate.OptimisticLockException; -import org.hibernate.PersistentObjectException; -import org.hibernate.PessimisticLockException; -import org.hibernate.PropertyValueException; -import org.hibernate.Query; -import org.hibernate.QueryException; -import org.hibernate.QueryTimeoutException; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.StaleObjectStateException; -import org.hibernate.StaleStateException; -import org.hibernate.TransientObjectException; -import org.hibernate.UnresolvableObjectException; -import org.hibernate.WrongClassException; -import org.hibernate.connection.ConnectionProvider; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.exception.ConstraintViolationException; -import org.hibernate.exception.DataException; -import org.hibernate.exception.JDBCConnectionException; -import org.hibernate.exception.LockAcquisitionException; -import org.hibernate.exception.SQLGrammarException; - -import org.springframework.core.NamedThreadLocal; -import org.springframework.dao.CannotAcquireLockException; -import org.springframework.dao.DataAccessException; -import org.springframework.dao.DataAccessResourceFailureException; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.dao.DuplicateKeyException; -import org.springframework.dao.IncorrectResultSizeDataAccessException; -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.dao.InvalidDataAccessResourceUsageException; -import org.springframework.dao.PessimisticLockingFailureException; -import org.springframework.jdbc.datasource.DataSourceUtils; -import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator; -import org.springframework.jdbc.support.SQLExceptionTranslator; -import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator; -import org.springframework.transaction.jta.SpringJtaSynchronizationAdapter; -import org.springframework.transaction.support.TransactionSynchronizationManager; -import org.springframework.util.Assert; - -/** - * Helper class featuring methods for Hibernate Session handling, - * allowing for reuse of Hibernate Session instances within transactions. - * Also provides support for exception translation. - * - *

Supports synchronization with both Spring-managed JTA transactions - * (see {@link org.springframework.transaction.jta.JtaTransactionManager}) - * and non-Spring JTA transactions (i.e. plain JTA or EJB CMT), - * transparently providing transaction-scoped Hibernate Sessions. - * Note that for non-Spring JTA transactions, a JTA TransactionManagerLookup - * has to be specified in the Hibernate configuration. - * - *

Used internally by {@link HibernateTemplate}, {@link HibernateInterceptor} - * and {@link HibernateTransactionManager}. Can also be used directly in - * application code. - * - *

Requires Hibernate 3.6.x, as of Spring 4.0. - * - * @author Juergen Hoeller - * @since 1.2 - * @see #getSession - * @see #releaseSession - * @see HibernateTransactionManager - * @see org.springframework.transaction.jta.JtaTransactionManager - * @see org.springframework.transaction.support.TransactionSynchronizationManager - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public abstract class SessionFactoryUtils { - - /** - * Order value for TransactionSynchronization objects that clean up Hibernate Sessions. - * Returns {@code DataSourceUtils.CONNECTION_SYNCHRONIZATION_ORDER - 100} - * to execute Session cleanup before JDBC Connection cleanup, if any. - * @see org.springframework.jdbc.datasource.DataSourceUtils#CONNECTION_SYNCHRONIZATION_ORDER - */ - public static final int SESSION_SYNCHRONIZATION_ORDER = - DataSourceUtils.CONNECTION_SYNCHRONIZATION_ORDER - 100; - - static final Log logger = LogFactory.getLog(SessionFactoryUtils.class); - - private static final ThreadLocal>> deferredCloseHolder = - new NamedThreadLocal>>("Hibernate Sessions registered for deferred close"); - - - /** - * Determine the DataSource of the given SessionFactory. - * @param sessionFactory the SessionFactory to check - * @return the DataSource, or {@code null} if none found - * @see org.hibernate.engine.SessionFactoryImplementor#getConnectionProvider - * @see LocalDataSourceConnectionProvider - */ - public static DataSource getDataSource(SessionFactory sessionFactory) { - if (sessionFactory instanceof SessionFactoryImplementor) { - ConnectionProvider cp = ((SessionFactoryImplementor) sessionFactory).getConnectionProvider(); - if (cp instanceof LocalDataSourceConnectionProvider) { - return ((LocalDataSourceConnectionProvider) cp).getDataSource(); - } - } - return null; - } - - /** - * Create an appropriate SQLExceptionTranslator for the given SessionFactory. - * If a DataSource is found, a SQLErrorCodeSQLExceptionTranslator for the DataSource - * is created; else, a SQLStateSQLExceptionTranslator as fallback. - * @param sessionFactory the SessionFactory to create the translator for - * @return the SQLExceptionTranslator - * @see #getDataSource - * @see org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator - * @see org.springframework.jdbc.support.SQLStateSQLExceptionTranslator - */ - public static SQLExceptionTranslator newJdbcExceptionTranslator(SessionFactory sessionFactory) { - DataSource ds = getDataSource(sessionFactory); - if (ds != null) { - return new SQLErrorCodeSQLExceptionTranslator(ds); - } - return new SQLStateSQLExceptionTranslator(); - } - - /** - * Try to retrieve the JTA TransactionManager from the given SessionFactory - * and/or Session. Check the passed-in SessionFactory for implementing - * SessionFactoryImplementor (the usual case), falling back to the - * SessionFactory reference that the Session itself carries. - * @param sessionFactory Hibernate SessionFactory - * @param session Hibernate Session (can also be {@code null}) - * @return the JTA TransactionManager, if any - * @see javax.transaction.TransactionManager - * @see SessionFactoryImplementor#getTransactionManager - * @see Session#getSessionFactory - * @see org.hibernate.impl.SessionFactoryImpl - */ - public static TransactionManager getJtaTransactionManager(SessionFactory sessionFactory, Session session) { - SessionFactoryImplementor sessionFactoryImpl = null; - if (sessionFactory instanceof SessionFactoryImplementor) { - sessionFactoryImpl = ((SessionFactoryImplementor) sessionFactory); - } - else if (session != null) { - SessionFactory internalFactory = session.getSessionFactory(); - if (internalFactory instanceof SessionFactoryImplementor) { - sessionFactoryImpl = (SessionFactoryImplementor) internalFactory; - } - } - return (sessionFactoryImpl != null ? sessionFactoryImpl.getTransactionManager() : null); - } - - - /** - * Get a Hibernate Session for the given SessionFactory. Is aware of and will - * return any existing corresponding Session bound to the current thread, for - * example when using {@link HibernateTransactionManager}. Will create a new - * Session otherwise, if "allowCreate" is {@code true}. - *

This is the {@code getSession} method used by typical data access code, - * in combination with {@code releaseSession} called when done with - * the Session. Note that HibernateTemplate allows to write data access code - * without caring about such resource handling. - * @param sessionFactory Hibernate SessionFactory to create the session with - * @param allowCreate whether a non-transactional Session should be created - * when no transactional Session can be found for the current thread - * @return the Hibernate Session - * @throws DataAccessResourceFailureException if the Session couldn't be created - * @throws IllegalStateException if no thread-bound Session found and - * "allowCreate" is {@code false} - * @see #getSession(SessionFactory, Interceptor, SQLExceptionTranslator) - * @see #releaseSession - * @see HibernateTemplate - */ - public static Session getSession(SessionFactory sessionFactory, boolean allowCreate) - throws DataAccessResourceFailureException, IllegalStateException { - - try { - return doGetSession(sessionFactory, null, null, allowCreate); - } - catch (HibernateException ex) { - throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex); - } - } - - /** - * Get a Hibernate Session for the given SessionFactory. Is aware of and will - * return any existing corresponding Session bound to the current thread, for - * example when using {@link HibernateTransactionManager}. Will always create - * a new Session otherwise. - *

Supports setting a Session-level Hibernate entity interceptor that allows - * to inspect and change property values before writing to and reading from the - * database. Such an interceptor can also be set at the SessionFactory level - * (i.e. on LocalSessionFactoryBean), on HibernateTransactionManager, etc. - * @param sessionFactory Hibernate SessionFactory to create the session with - * @param entityInterceptor Hibernate entity interceptor, or {@code null} if none - * @param jdbcExceptionTranslator SQLExcepionTranslator to use for flushing the - * Session on transaction synchronization (may be {@code null}; only used - * when actually registering a transaction synchronization) - * @return the Hibernate Session - * @throws DataAccessResourceFailureException if the Session couldn't be created - * @see LocalSessionFactoryBean#setEntityInterceptor - * @see HibernateTemplate#setEntityInterceptor - */ - public static Session getSession( - SessionFactory sessionFactory, Interceptor entityInterceptor, - SQLExceptionTranslator jdbcExceptionTranslator) throws DataAccessResourceFailureException { - - try { - return doGetSession(sessionFactory, entityInterceptor, jdbcExceptionTranslator, true); - } - catch (HibernateException ex) { - throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex); - } - } - - /** - * Get a Hibernate Session for the given SessionFactory. Is aware of and will - * return any existing corresponding Session bound to the current thread, for - * example when using {@link HibernateTransactionManager}. Will create a new - * Session otherwise, if "allowCreate" is {@code true}. - *

Throws the original HibernateException, in contrast to {@link #getSession}. - * @param sessionFactory Hibernate SessionFactory to create the session with - * @param allowCreate whether a non-transactional Session should be created - * when no transactional Session can be found for the current thread - * @return the Hibernate Session - * @throws HibernateException if the Session couldn't be created - * @throws IllegalStateException if no thread-bound Session found and allowCreate false - */ - public static Session doGetSession(SessionFactory sessionFactory, boolean allowCreate) - throws HibernateException, IllegalStateException { - - return doGetSession(sessionFactory, null, null, allowCreate); - } - - /** - * Get a Hibernate Session for the given SessionFactory. Is aware of and will - * return any existing corresponding Session bound to the current thread, for - * example when using {@link HibernateTransactionManager}. Will create a new - * Session otherwise, if "allowCreate" is {@code true}. - *

Same as {@link #getSession}, but throwing the original HibernateException. - * @param sessionFactory Hibernate SessionFactory to create the session with - * @param entityInterceptor Hibernate entity interceptor, or {@code null} if none - * @param jdbcExceptionTranslator SQLExcepionTranslator to use for flushing the - * Session on transaction synchronization (may be {@code null}) - * @param allowCreate whether a non-transactional Session should be created - * when no transactional Session can be found for the current thread - * @return the Hibernate Session - * @throws HibernateException if the Session couldn't be created - * @throws IllegalStateException if no thread-bound Session found and - * "allowCreate" is {@code false} - */ - private static Session doGetSession( - SessionFactory sessionFactory, Interceptor entityInterceptor, - SQLExceptionTranslator jdbcExceptionTranslator, boolean allowCreate) - throws HibernateException, IllegalStateException { - - Assert.notNull(sessionFactory, "No SessionFactory specified"); - - Object resource = TransactionSynchronizationManager.getResource(sessionFactory); - if (resource instanceof Session) { - return (Session) resource; - } - SessionHolder sessionHolder = (SessionHolder) resource; - if (sessionHolder != null && !sessionHolder.isEmpty()) { - // pre-bound Hibernate Session - Session session = null; - if (TransactionSynchronizationManager.isSynchronizationActive() && - sessionHolder.doesNotHoldNonDefaultSession()) { - // Spring transaction management is active -> - // register pre-bound Session with it for transactional flushing. - session = sessionHolder.getValidatedSession(); - if (session != null && !sessionHolder.isSynchronizedWithTransaction()) { - logger.debug("Registering Spring transaction synchronization for existing Hibernate Session"); - TransactionSynchronizationManager.registerSynchronization( - new SpringSessionSynchronization(sessionHolder, sessionFactory, jdbcExceptionTranslator, false)); - sessionHolder.setSynchronizedWithTransaction(true); - // Switch to FlushMode.AUTO, as we have to assume a thread-bound Session - // with FlushMode.MANUAL, which needs to allow flushing within the transaction. - FlushMode flushMode = session.getFlushMode(); - if (flushMode.lessThan(FlushMode.COMMIT) && - !TransactionSynchronizationManager.isCurrentTransactionReadOnly()) { - session.setFlushMode(FlushMode.AUTO); - sessionHolder.setPreviousFlushMode(flushMode); - } - } - } - else { - // No Spring transaction management active -> try JTA transaction synchronization. - session = getJtaSynchronizedSession(sessionHolder, sessionFactory, jdbcExceptionTranslator); - } - if (session != null) { - return session; - } - } - - logger.debug("Opening Hibernate Session"); - Session session = (entityInterceptor != null ? - sessionFactory.openSession(entityInterceptor) : sessionFactory.openSession()); - - // Use same Session for further Hibernate actions within the transaction. - // Thread object will get removed by synchronization at transaction completion. - if (TransactionSynchronizationManager.isSynchronizationActive()) { - // We're within a Spring-managed transaction, possibly from JtaTransactionManager. - logger.debug("Registering Spring transaction synchronization for new Hibernate Session"); - SessionHolder holderToUse = sessionHolder; - if (holderToUse == null) { - holderToUse = new SessionHolder(session); - } - else { - holderToUse.addSession(session); - } - if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) { - session.setFlushMode(FlushMode.MANUAL); - } - TransactionSynchronizationManager.registerSynchronization( - new SpringSessionSynchronization(holderToUse, sessionFactory, jdbcExceptionTranslator, true)); - holderToUse.setSynchronizedWithTransaction(true); - if (holderToUse != sessionHolder) { - TransactionSynchronizationManager.bindResource(sessionFactory, holderToUse); - } - } - else { - // No Spring transaction management active -> try JTA transaction synchronization. - registerJtaSynchronization(session, sessionFactory, jdbcExceptionTranslator, sessionHolder); - } - - // Check whether we are allowed to return the Session. - if (!allowCreate && !isSessionTransactional(session, sessionFactory)) { - closeSession(session); - throw new IllegalStateException("No Hibernate Session bound to thread, " + - "and configuration does not allow creation of non-transactional one here"); - } - - return session; - } - - /** - * Retrieve a Session from the given SessionHolder, potentially from a - * JTA transaction synchronization. - * @param sessionHolder the SessionHolder to check - * @param sessionFactory the SessionFactory to get the JTA TransactionManager from - * @param jdbcExceptionTranslator SQLExcepionTranslator to use for flushing the - * Session on transaction synchronization (may be {@code null}) - * @return the associated Session, if any - * @throws DataAccessResourceFailureException if the Session couldn't be created - */ - private static Session getJtaSynchronizedSession( - SessionHolder sessionHolder, SessionFactory sessionFactory, - SQLExceptionTranslator jdbcExceptionTranslator) throws DataAccessResourceFailureException { - - // JTA synchronization is only possible with a javax.transaction.TransactionManager. - // We'll check the Hibernate SessionFactory: If a TransactionManagerLookup is specified - // in Hibernate configuration, it will contain a TransactionManager reference. - TransactionManager jtaTm = getJtaTransactionManager(sessionFactory, sessionHolder.getAnySession()); - if (jtaTm != null) { - // Check whether JTA transaction management is active -> - // fetch pre-bound Session for the current JTA transaction, if any. - // (just necessary for JTA transaction suspension, with an individual - // Hibernate Session per currently active/suspended transaction) - try { - // Look for transaction-specific Session. - Transaction jtaTx = jtaTm.getTransaction(); - if (jtaTx != null) { - int jtaStatus = jtaTx.getStatus(); - if (jtaStatus == Status.STATUS_ACTIVE || jtaStatus == Status.STATUS_MARKED_ROLLBACK) { - Session session = sessionHolder.getValidatedSession(jtaTx); - if (session == null && !sessionHolder.isSynchronizedWithTransaction()) { - // No transaction-specific Session found: If not already marked as - // synchronized with transaction, register the default thread-bound - // Session as JTA-transactional. If there is no default Session, - // we're a new inner JTA transaction with an outer one being suspended: - // In that case, we'll return null to trigger opening of a new Session. - session = sessionHolder.getValidatedSession(); - if (session != null) { - logger.debug("Registering JTA transaction synchronization for existing Hibernate Session"); - sessionHolder.addSession(jtaTx, session); - jtaTx.registerSynchronization( - new SpringJtaSynchronizationAdapter( - new SpringSessionSynchronization(sessionHolder, sessionFactory, jdbcExceptionTranslator, false), - jtaTm)); - sessionHolder.setSynchronizedWithTransaction(true); - // Switch to FlushMode.AUTO, as we have to assume a thread-bound Session - // with FlushMode.NEVER, which needs to allow flushing within the transaction. - FlushMode flushMode = session.getFlushMode(); - if (flushMode.lessThan(FlushMode.COMMIT)) { - session.setFlushMode(FlushMode.AUTO); - sessionHolder.setPreviousFlushMode(flushMode); - } - } - } - return session; - } - } - // No transaction active -> simply return default thread-bound Session, if any - // (possibly from OpenSessionInViewFilter/Interceptor). - return sessionHolder.getValidatedSession(); - } - catch (Throwable ex) { - throw new DataAccessResourceFailureException("Could not check JTA transaction", ex); - } - } - else { - // No JTA TransactionManager -> simply return default thread-bound Session, if any - // (possibly from OpenSessionInViewFilter/Interceptor). - return sessionHolder.getValidatedSession(); - } - } - - /** - * Register a JTA synchronization for the given Session, if any. - * @param sessionHolder the existing thread-bound SessionHolder, if any - * @param session the Session to register - * @param sessionFactory the SessionFactory that the Session was created with - * @param jdbcExceptionTranslator SQLExcepionTranslator to use for flushing the - * Session on transaction synchronization (may be {@code null}) - */ - private static void registerJtaSynchronization(Session session, SessionFactory sessionFactory, - SQLExceptionTranslator jdbcExceptionTranslator, SessionHolder sessionHolder) { - - // JTA synchronization is only possible with a javax.transaction.TransactionManager. - // We'll check the Hibernate SessionFactory: If a TransactionManagerLookup is specified - // in Hibernate configuration, it will contain a TransactionManager reference. - TransactionManager jtaTm = getJtaTransactionManager(sessionFactory, session); - if (jtaTm != null) { - try { - Transaction jtaTx = jtaTm.getTransaction(); - if (jtaTx != null) { - int jtaStatus = jtaTx.getStatus(); - if (jtaStatus == Status.STATUS_ACTIVE || jtaStatus == Status.STATUS_MARKED_ROLLBACK) { - logger.debug("Registering JTA transaction synchronization for new Hibernate Session"); - SessionHolder holderToUse = sessionHolder; - // Register JTA Transaction with existing SessionHolder. - // Create a new SessionHolder if none existed before. - if (holderToUse == null) { - holderToUse = new SessionHolder(jtaTx, session); - } - else { - holderToUse.addSession(jtaTx, session); - } - jtaTx.registerSynchronization( - new SpringJtaSynchronizationAdapter( - new SpringSessionSynchronization(holderToUse, sessionFactory, jdbcExceptionTranslator, true), - jtaTm)); - holderToUse.setSynchronizedWithTransaction(true); - if (holderToUse != sessionHolder) { - TransactionSynchronizationManager.bindResource(sessionFactory, holderToUse); - } - } - } - } - catch (Throwable ex) { - throw new DataAccessResourceFailureException( - "Could not register synchronization with JTA TransactionManager", ex); - } - } - } - - - /** - * Get a new Hibernate Session from the given SessionFactory. - * Will return a new Session even if there already is a pre-bound - * Session for the given SessionFactory. - *

Within a transaction, this method will create a new Session - * that shares the transaction's JDBC Connection. More specifically, - * it will use the same JDBC Connection as the pre-bound Hibernate Session. - * @param sessionFactory Hibernate SessionFactory to create the session with - * @return the new Session - */ - public static Session getNewSession(SessionFactory sessionFactory) { - return getNewSession(sessionFactory, null); - } - - /** - * Get a new Hibernate Session from the given SessionFactory. - * Will return a new Session even if there already is a pre-bound - * Session for the given SessionFactory. - *

Within a transaction, this method will create a new Session - * that shares the transaction's JDBC Connection. More specifically, - * it will use the same JDBC Connection as the pre-bound Hibernate Session. - * @param sessionFactory Hibernate SessionFactory to create the session with - * @param entityInterceptor Hibernate entity interceptor, or {@code null} if none - * @return the new Session - */ - public static Session getNewSession(SessionFactory sessionFactory, Interceptor entityInterceptor) { - Assert.notNull(sessionFactory, "No SessionFactory specified"); - - try { - SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory); - if (sessionHolder != null && !sessionHolder.isEmpty()) { - if (entityInterceptor != null) { - return sessionFactory.openSession(sessionHolder.getAnySession().connection(), entityInterceptor); - } - else { - return sessionFactory.openSession(sessionHolder.getAnySession().connection()); - } - } - else { - if (entityInterceptor != null) { - return sessionFactory.openSession(entityInterceptor); - } - else { - return sessionFactory.openSession(); - } - } - } - catch (HibernateException ex) { - throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex); - } - } - - - /** - * Stringify the given Session for debug logging. - * Returns output equivalent to {@code Object.toString()}: - * the fully qualified class name + "@" + the identity hash code. - *

The sole reason why this is necessary is because Hibernate3's - * {@code Session.toString()} implementation is broken (and won't be fixed): - * it logs the toString representation of all persistent objects in the Session, - * which might lead to ConcurrentModificationExceptions if the persistent objects - * in turn refer to the Session (for example, for lazy loading). - * @param session the Hibernate Session to stringify - * @return the String representation of the given Session - */ - public static String toString(Session session) { - return session.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(session)); - } - - /** - * Return whether there is a transactional Hibernate Session for the current thread, - * that is, a Session bound to the current thread by Spring's transaction facilities. - * @param sessionFactory Hibernate SessionFactory to check (may be {@code null}) - * @return whether there is a transactional Session for current thread - */ - public static boolean hasTransactionalSession(SessionFactory sessionFactory) { - if (sessionFactory == null) { - return false; - } - SessionHolder sessionHolder = - (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory); - return (sessionHolder != null && !sessionHolder.isEmpty()); - } - - /** - * Return whether the given Hibernate Session is transactional, that is, - * bound to the current thread by Spring's transaction facilities. - * @param session the Hibernate Session to check - * @param sessionFactory Hibernate SessionFactory that the Session was created with - * (may be {@code null}) - * @return whether the Session is transactional - */ - public static boolean isSessionTransactional(Session session, SessionFactory sessionFactory) { - if (sessionFactory == null) { - return false; - } - SessionHolder sessionHolder = - (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory); - return (sessionHolder != null && sessionHolder.containsSession(session)); - } - - /** - * Apply the current transaction timeout, if any, to the given - * Hibernate Query object. - * @param query the Hibernate Query object - * @param sessionFactory Hibernate SessionFactory that the Query was created for - * (may be {@code null}) - * @see org.hibernate.Query#setTimeout - */ - public static void applyTransactionTimeout(Query query, SessionFactory sessionFactory) { - Assert.notNull(query, "No Query object specified"); - if (sessionFactory != null) { - SessionHolder sessionHolder = - (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory); - if (sessionHolder != null && sessionHolder.hasTimeout()) { - query.setTimeout(sessionHolder.getTimeToLiveInSeconds()); - } - } - } - - /** - * Apply the current transaction timeout, if any, to the given - * Hibernate Criteria object. - * @param criteria the Hibernate Criteria object - * @param sessionFactory Hibernate SessionFactory that the Criteria was created for - * @see org.hibernate.Criteria#setTimeout - */ - public static void applyTransactionTimeout(Criteria criteria, SessionFactory sessionFactory) { - Assert.notNull(criteria, "No Criteria object specified"); - if (sessionFactory != null) { - SessionHolder sessionHolder = - (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory); - if (sessionHolder != null && sessionHolder.hasTimeout()) { - criteria.setTimeout(sessionHolder.getTimeToLiveInSeconds()); - } - } - } - - /** - * Convert the given HibernateException to an appropriate exception - * from the {@code org.springframework.dao} hierarchy. - * @param ex HibernateException that occurred - * @return the corresponding DataAccessException instance - * @see HibernateAccessor#convertHibernateAccessException - * @see HibernateTransactionManager#convertHibernateAccessException - */ - public static DataAccessException convertHibernateAccessException(HibernateException ex) { - if (ex instanceof JDBCConnectionException) { - return new DataAccessResourceFailureException(ex.getMessage(), ex); - } - if (ex instanceof SQLGrammarException) { - SQLGrammarException jdbcEx = (SQLGrammarException) ex; - return new InvalidDataAccessResourceUsageException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]", ex); - } - if (ex instanceof QueryTimeoutException) { - QueryTimeoutException jdbcEx = (QueryTimeoutException) ex; - return new org.springframework.dao.QueryTimeoutException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]", ex); - } - if (ex instanceof LockAcquisitionException) { - LockAcquisitionException jdbcEx = (LockAcquisitionException) ex; - return new CannotAcquireLockException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]", ex); - } - if (ex instanceof PessimisticLockException) { - PessimisticLockException jdbcEx = (PessimisticLockException) ex; - return new PessimisticLockingFailureException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]", ex); - } - if (ex instanceof ConstraintViolationException) { - ConstraintViolationException jdbcEx = (ConstraintViolationException) ex; - return new DataIntegrityViolationException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + - "]; constraint [" + jdbcEx.getConstraintName() + "]", ex); - } - if (ex instanceof DataException) { - DataException jdbcEx = (DataException) ex; - return new DataIntegrityViolationException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]", ex); - } - if (ex instanceof JDBCException) { - return new HibernateJdbcException((JDBCException) ex); - } - // end of JDBCException (subclass) handling - - if (ex instanceof QueryException) { - return new HibernateQueryException((QueryException) ex); - } - if (ex instanceof NonUniqueResultException) { - return new IncorrectResultSizeDataAccessException(ex.getMessage(), 1, ex); - } - if (ex instanceof NonUniqueObjectException) { - return new DuplicateKeyException(ex.getMessage(), ex); - } - if (ex instanceof PropertyValueException) { - return new DataIntegrityViolationException(ex.getMessage(), ex); - } - if (ex instanceof PersistentObjectException) { - return new InvalidDataAccessApiUsageException(ex.getMessage(), ex); - } - if (ex instanceof TransientObjectException) { - return new InvalidDataAccessApiUsageException(ex.getMessage(), ex); - } - if (ex instanceof ObjectDeletedException) { - return new InvalidDataAccessApiUsageException(ex.getMessage(), ex); - } - if (ex instanceof UnresolvableObjectException) { - return new HibernateObjectRetrievalFailureException((UnresolvableObjectException) ex); - } - if (ex instanceof WrongClassException) { - return new HibernateObjectRetrievalFailureException((WrongClassException) ex); - } - if (ex instanceof StaleObjectStateException) { - return new HibernateOptimisticLockingFailureException((StaleObjectStateException) ex); - } - if (ex instanceof StaleStateException) { - return new HibernateOptimisticLockingFailureException((StaleStateException) ex); - } - if (ex instanceof OptimisticLockException) { - return new HibernateOptimisticLockingFailureException((OptimisticLockException) ex); - } - - // fallback - return new HibernateSystemException(ex); - } - - - /** - * Determine whether deferred close is active for the current thread - * and the given SessionFactory. - * @param sessionFactory the Hibernate SessionFactory to check - * @return whether deferred close is active - */ - public static boolean isDeferredCloseActive(SessionFactory sessionFactory) { - Assert.notNull(sessionFactory, "No SessionFactory specified"); - Map> holderMap = deferredCloseHolder.get(); - return (holderMap != null && holderMap.containsKey(sessionFactory)); - } - - /** - * Initialize deferred close for the current thread and the given SessionFactory. - * Sessions will not be actually closed on close calls then, but rather at a - * {@link #processDeferredClose} call at a finishing point (like request completion). - *

Used by {@link org.springframework.orm.hibernate3.support.OpenSessionInViewFilter} - * and {@link org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor} - * when not configured for a single session. - * @param sessionFactory the Hibernate SessionFactory to initialize deferred close for - * @see #processDeferredClose - * @see #releaseSession - * @see org.springframework.orm.hibernate3.support.OpenSessionInViewFilter#setSingleSession - * @see org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor#setSingleSession - */ - public static void initDeferredClose(SessionFactory sessionFactory) { - Assert.notNull(sessionFactory, "No SessionFactory specified"); - logger.debug("Initializing deferred close of Hibernate Sessions"); - Map> holderMap = deferredCloseHolder.get(); - if (holderMap == null) { - holderMap = new HashMap>(); - deferredCloseHolder.set(holderMap); - } - holderMap.put(sessionFactory, new LinkedHashSet(4)); - } - - /** - * Process all Hibernate Sessions that have been registered for deferred close - * for the given SessionFactory. - * @param sessionFactory the Hibernate SessionFactory to process deferred close for - * @see #initDeferredClose - * @see #releaseSession - */ - public static void processDeferredClose(SessionFactory sessionFactory) { - Assert.notNull(sessionFactory, "No SessionFactory specified"); - Map> holderMap = deferredCloseHolder.get(); - if (holderMap == null || !holderMap.containsKey(sessionFactory)) { - throw new IllegalStateException("Deferred close not active for SessionFactory [" + sessionFactory + "]"); - } - logger.debug("Processing deferred close of Hibernate Sessions"); - Set sessions = holderMap.remove(sessionFactory); - for (Session session : sessions) { - closeSession(session); - } - if (holderMap.isEmpty()) { - deferredCloseHolder.remove(); - } - } - - /** - * Close the given Session, created via the given factory, - * if it is not managed externally (i.e. not bound to the thread). - * @param session the Hibernate Session to close (may be {@code null}) - * @param sessionFactory Hibernate SessionFactory that the Session was created with - * (may be {@code null}) - */ - public static void releaseSession(Session session, SessionFactory sessionFactory) { - if (session == null) { - return; - } - // Only close non-transactional Sessions. - if (!isSessionTransactional(session, sessionFactory)) { - closeSessionOrRegisterDeferredClose(session, sessionFactory); - } - } - - /** - * Close the given Session or register it for deferred close. - * @param session the Hibernate Session to close - * @param sessionFactory Hibernate SessionFactory that the Session was created with - * (may be {@code null}) - * @see #initDeferredClose - * @see #processDeferredClose - */ - static void closeSessionOrRegisterDeferredClose(Session session, SessionFactory sessionFactory) { - Map> holderMap = deferredCloseHolder.get(); - if (holderMap != null && sessionFactory != null && holderMap.containsKey(sessionFactory)) { - logger.debug("Registering Hibernate Session for deferred close"); - // Switch Session to FlushMode.MANUAL for remaining lifetime. - session.setFlushMode(FlushMode.MANUAL); - Set sessions = holderMap.get(sessionFactory); - sessions.add(session); - } - else { - closeSession(session); - } - } - - /** - * Perform actual closing of the Hibernate Session, - * catching and logging any cleanup exceptions thrown. - * @param session the Hibernate Session to close (may be {@code null}) - * @see org.hibernate.Session#close() - */ - public static void closeSession(Session session) { - if (session != null) { - logger.debug("Closing Hibernate Session"); - try { - session.close(); - } - catch (HibernateException ex) { - logger.debug("Could not close Hibernate Session", ex); - } - catch (Throwable ex) { - logger.debug("Unexpected exception on closing Hibernate Session", ex); - } - } - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/SessionHolder.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/SessionHolder.java deleted file mode 100644 index abfb36c513..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/SessionHolder.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.hibernate.FlushMode; -import org.hibernate.Session; -import org.hibernate.Transaction; - -import org.springframework.transaction.support.ResourceHolderSupport; -import org.springframework.util.Assert; - -/** - * Session holder, wrapping a Hibernate Session and a Hibernate Transaction. - * HibernateTransactionManager binds instances of this class to the thread, - * for a given SessionFactory. - * - *

Note: This is an SPI class, not intended to be used by applications. - * - * @author Juergen Hoeller - * @since 1.2 - * @see HibernateTransactionManager - * @see SessionFactoryUtils - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public class SessionHolder extends ResourceHolderSupport { - - private static final Object DEFAULT_KEY = new Object(); - - /** - * This Map needs to be concurrent because there might be multi-threaded - * access in the case of JTA with remote transaction propagation. - */ - private final Map sessionMap = new ConcurrentHashMap(1); - - private Transaction transaction; - - private FlushMode previousFlushMode; - - - public SessionHolder(Session session) { - addSession(session); - } - - public SessionHolder(Object key, Session session) { - addSession(key, session); - } - - - public Session getSession() { - return getSession(DEFAULT_KEY); - } - - public Session getSession(Object key) { - return this.sessionMap.get(key); - } - - public Session getValidatedSession() { - return getValidatedSession(DEFAULT_KEY); - } - - public Session getValidatedSession(Object key) { - Session session = this.sessionMap.get(key); - // Check for dangling Session that's around but already closed. - // Effectively an assertion: that should never happen in practice. - // We'll seamlessly remove the Session here, to not let it cause - // any side effects. - if (session != null && !session.isOpen()) { - this.sessionMap.remove(key); - session = null; - } - return session; - } - - public Session getAnySession() { - if (!this.sessionMap.isEmpty()) { - return this.sessionMap.values().iterator().next(); - } - return null; - } - - public void addSession(Session session) { - addSession(DEFAULT_KEY, session); - } - - public void addSession(Object key, Session session) { - Assert.notNull(key, "Key must not be null"); - Assert.notNull(session, "Session must not be null"); - this.sessionMap.put(key, session); - } - - public Session removeSession(Object key) { - return this.sessionMap.remove(key); - } - - public boolean containsSession(Session session) { - return this.sessionMap.containsValue(session); - } - - public boolean isEmpty() { - return this.sessionMap.isEmpty(); - } - - public boolean doesNotHoldNonDefaultSession() { - return this.sessionMap.isEmpty() || - (this.sessionMap.size() == 1 && this.sessionMap.containsKey(DEFAULT_KEY)); - } - - - public void setTransaction(Transaction transaction) { - this.transaction = transaction; - } - - public Transaction getTransaction() { - return this.transaction; - } - - public void setPreviousFlushMode(FlushMode previousFlushMode) { - this.previousFlushMode = previousFlushMode; - } - - public FlushMode getPreviousFlushMode() { - return this.previousFlushMode; - } - - - @Override - public void clear() { - super.clear(); - this.transaction = null; - this.previousFlushMode = null; - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/SpringSessionContext.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/SpringSessionContext.java deleted file mode 100644 index f0c1199eda..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/SpringSessionContext.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import org.hibernate.HibernateException; -import org.hibernate.classic.Session; -import org.hibernate.context.CurrentSessionContext; -import org.hibernate.engine.SessionFactoryImplementor; - -/** - * Implementation of Hibernate 3.1's CurrentSessionContext interface - * that delegates to Spring's SessionFactoryUtils for providing a - * Spring-managed current Session. - * - *

Used by Spring's {@link LocalSessionFactoryBean} when told to expose a - * transaction-aware SessionFactory. This is the default as of Spring 2.5. - * - *

This CurrentSessionContext implementation can also be specified in custom - * SessionFactory setup through the "hibernate.current_session_context_class" - * property, with the fully qualified name of this class as value. - * - * @author Juergen Hoeller - * @since 2.0 - * @see SessionFactoryUtils#doGetSession - * @see LocalSessionFactoryBean#setExposeTransactionAwareSessionFactory - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -@SuppressWarnings("serial") -public class SpringSessionContext implements CurrentSessionContext { - - private final SessionFactoryImplementor sessionFactory; - - - /** - * Create a new SpringSessionContext for the given Hibernate SessionFactory. - * @param sessionFactory the SessionFactory to provide current Sessions for - */ - public SpringSessionContext(SessionFactoryImplementor sessionFactory) { - this.sessionFactory = sessionFactory; - } - - - /** - * Retrieve the Spring-managed Session for the current thread, if any. - */ - @Override - public Session currentSession() throws HibernateException { - try { - return (org.hibernate.classic.Session) SessionFactoryUtils.doGetSession(this.sessionFactory, false); - } - catch (IllegalStateException ex) { - throw new HibernateException(ex.getMessage()); - } - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/SpringSessionSynchronization.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/SpringSessionSynchronization.java deleted file mode 100644 index 70f8beffed..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/SpringSessionSynchronization.java +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import javax.transaction.SystemException; -import javax.transaction.Transaction; -import javax.transaction.TransactionManager; - -import org.hibernate.FlushMode; -import org.hibernate.HibernateException; -import org.hibernate.JDBCException; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.engine.SessionImplementor; - -import org.springframework.core.Ordered; -import org.springframework.dao.DataAccessException; -import org.springframework.dao.DataAccessResourceFailureException; -import org.springframework.jdbc.support.SQLExceptionTranslator; -import org.springframework.transaction.support.TransactionSynchronization; -import org.springframework.transaction.support.TransactionSynchronizationManager; - -/** - * Callback for resource cleanup at the end of a Spring-managed JTA transaction, - * that is, when participating in a JtaTransactionManager transaction. - * - * @author Juergen Hoeller - * @since 1.2 - * @see SessionFactoryUtils - * @see org.springframework.transaction.jta.JtaTransactionManager - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -class SpringSessionSynchronization implements TransactionSynchronization, Ordered { - - private final SessionHolder sessionHolder; - - private final SessionFactory sessionFactory; - - private final SQLExceptionTranslator jdbcExceptionTranslator; - - private final boolean newSession; - - /** - * Whether Hibernate has a looked-up JTA TransactionManager that it will - * automatically register CacheSynchronizations with on Session connect. - */ - private boolean hibernateTransactionCompletion = false; - - private Transaction jtaTransaction; - - private boolean holderActive = true; - - - public SpringSessionSynchronization( - SessionHolder sessionHolder, SessionFactory sessionFactory, - SQLExceptionTranslator jdbcExceptionTranslator, boolean newSession) { - - this.sessionHolder = sessionHolder; - this.sessionFactory = sessionFactory; - this.jdbcExceptionTranslator = jdbcExceptionTranslator; - this.newSession = newSession; - - // Check whether the SessionFactory has a JTA TransactionManager. - TransactionManager jtaTm = - SessionFactoryUtils.getJtaTransactionManager(sessionFactory, sessionHolder.getAnySession()); - if (jtaTm != null) { - this.hibernateTransactionCompletion = true; - // Fetch current JTA Transaction object - // (just necessary for JTA transaction suspension, with an individual - // Hibernate Session per currently active/suspended transaction). - try { - this.jtaTransaction = jtaTm.getTransaction(); - } - catch (SystemException ex) { - throw new DataAccessResourceFailureException("Could not access JTA transaction", ex); - } - } - } - - /** - * Check whether there is a Hibernate Session for the current JTA - * transaction. Else, fall back to the default thread-bound Session. - */ - private Session getCurrentSession() { - Session session = null; - if (this.jtaTransaction != null) { - session = this.sessionHolder.getSession(this.jtaTransaction); - } - if (session == null) { - session = this.sessionHolder.getSession(); - } - return session; - } - - - @Override - public int getOrder() { - return SessionFactoryUtils.SESSION_SYNCHRONIZATION_ORDER; - } - - @Override - public void suspend() { - if (this.holderActive) { - TransactionSynchronizationManager.unbindResource(this.sessionFactory); - // Eagerly disconnect the Session here, to make release mode "on_close" work on JBoss. - getCurrentSession().disconnect(); - } - } - - @Override - public void resume() { - if (this.holderActive) { - TransactionSynchronizationManager.bindResource(this.sessionFactory, this.sessionHolder); - } - } - - @Override - public void flush() { - try { - SessionFactoryUtils.logger.debug("Flushing Hibernate Session on explicit request"); - getCurrentSession().flush(); - } - catch (HibernateException ex) { - throw translateException(ex); - } - } - - @Override - public void beforeCommit(boolean readOnly) throws DataAccessException { - if (!readOnly) { - Session session = getCurrentSession(); - // Read-write transaction -> flush the Hibernate Session. - // Further check: only flush when not FlushMode.NEVER/MANUAL. - if (!session.getFlushMode().lessThan(FlushMode.COMMIT)) { - try { - SessionFactoryUtils.logger.debug("Flushing Hibernate Session on transaction synchronization"); - session.flush(); - } - catch (HibernateException ex) { - throw translateException(ex); - } - } - } - } - - private DataAccessException translateException(HibernateException ex) { - if (this.jdbcExceptionTranslator != null && ex instanceof JDBCException) { - JDBCException jdbcEx = (JDBCException) ex; - return this.jdbcExceptionTranslator.translate( - "Hibernate flushing: " + jdbcEx.getMessage(), jdbcEx.getSQL(), jdbcEx.getSQLException()); - } - return SessionFactoryUtils.convertHibernateAccessException(ex); - } - - @Override - public void beforeCompletion() { - if (this.jtaTransaction != null) { - // Typically in case of a suspended JTA transaction: - // Remove the Session for the current JTA transaction, but keep the holder. - Session session = this.sessionHolder.removeSession(this.jtaTransaction); - if (session != null) { - if (this.sessionHolder.isEmpty()) { - // No Sessions for JTA transactions bound anymore -> could remove it. - TransactionSynchronizationManager.unbindResourceIfPossible(this.sessionFactory); - this.holderActive = false; - } - // Do not close a pre-bound Session. In that case, we'll find the - // transaction-specific Session the same as the default Session. - if (session != this.sessionHolder.getSession()) { - SessionFactoryUtils.closeSessionOrRegisterDeferredClose(session, this.sessionFactory); - } - else { - if (this.sessionHolder.getPreviousFlushMode() != null) { - // In case of pre-bound Session, restore previous flush mode. - session.setFlushMode(this.sessionHolder.getPreviousFlushMode()); - } - // Eagerly disconnect the Session here, to make release mode "on_close" work nicely. - session.disconnect(); - } - return; - } - } - // We'll only get here if there was no specific JTA transaction to handle. - if (this.newSession) { - // Default behavior: unbind and close the thread-bound Hibernate Session. - TransactionSynchronizationManager.unbindResource(this.sessionFactory); - this.holderActive = false; - if (this.hibernateTransactionCompletion) { - // Close the Hibernate Session here in case of a Hibernate TransactionManagerLookup: - // Hibernate will automatically defer the actual closing until JTA transaction completion. - // Else, the Session will be closed in the afterCompletion method, to provide the - // correct transaction status for releasing the Session's cache locks. - SessionFactoryUtils.closeSessionOrRegisterDeferredClose(this.sessionHolder.getSession(), this.sessionFactory); - } - } - else { - Session session = this.sessionHolder.getSession(); - if (this.sessionHolder.getPreviousFlushMode() != null) { - // In case of pre-bound Session, restore previous flush mode. - session.setFlushMode(this.sessionHolder.getPreviousFlushMode()); - } - if (this.hibernateTransactionCompletion) { - // Eagerly disconnect the Session here, to make release mode "on_close" work nicely. - // We know that this is appropriate if a TransactionManagerLookup has been specified. - session.disconnect(); - } - } - } - - @Override - public void afterCommit() { - } - - @Override - public void afterCompletion(int status) { - try { - if (!this.hibernateTransactionCompletion || !this.newSession) { - // No Hibernate TransactionManagerLookup: apply afterTransactionCompletion callback. - // Always perform explicit afterTransactionCompletion callback for pre-bound Session, - // even with Hibernate TransactionManagerLookup (which only applies to new Sessions). - Session session = this.sessionHolder.getSession(); - // Provide correct transaction status for releasing the Session's cache locks, - // if possible. Else, closing will release all cache locks assuming a rollback. - try { - if (session instanceof SessionImplementor) { - ((SessionImplementor) session).afterTransactionCompletion(status == STATUS_COMMITTED, null); - } - } - finally { - // Close the Hibernate Session here if necessary - // (closed in beforeCompletion in case of TransactionManagerLookup). - if (this.newSession) { - SessionFactoryUtils.closeSessionOrRegisterDeferredClose(session, this.sessionFactory); - } - else if (!this.hibernateTransactionCompletion) { - session.disconnect(); - } - } - } - if (!this.newSession && status != STATUS_COMMITTED) { - // Clear all pending inserts/updates/deletes in the Session. - // Necessary for pre-bound Sessions, to avoid inconsistent state. - this.sessionHolder.getSession().clear(); - } - } - finally { - if (this.sessionHolder.doesNotHoldNonDefaultSession()) { - this.sessionHolder.setSynchronizedWithTransaction(false); - } - } - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/SpringTransactionFactory.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/SpringTransactionFactory.java deleted file mode 100644 index a381d6de20..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/SpringTransactionFactory.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import java.util.Properties; - -import org.hibernate.ConnectionReleaseMode; -import org.hibernate.Transaction; -import org.hibernate.jdbc.JDBCContext; -import org.hibernate.transaction.JDBCTransaction; -import org.hibernate.transaction.TransactionFactory; - -import org.springframework.transaction.support.TransactionSynchronizationManager; - -/** - * Spring-aware implementation of the Hibernate TransactionFactory interface, aware of - * Spring-synchronized transactions (in particular Spring-managed JTA transactions) - * and asking for default release mode ON_CLOSE. Otherwise identical to Hibernate's - * default {@link org.hibernate.transaction.JDBCTransactionFactory} implementation. - * - * @author Juergen Hoeller - * @since 2.5.4 - * @see org.springframework.transaction.support.TransactionSynchronizationManager - * @see org.hibernate.transaction.JDBCTransactionFactory - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public class SpringTransactionFactory implements TransactionFactory { - - /** - * Sets connection release mode "on_close" as default. - *

This was the case for Hibernate 3.0; Hibernate 3.1 changed - * it to "auto" (i.e. "after_statement" or "after_transaction"). - * However, for Spring's resource management (in particular for - * HibernateTransactionManager), "on_close" is the better default. - */ - @Override - public ConnectionReleaseMode getDefaultReleaseMode() { - return ConnectionReleaseMode.ON_CLOSE; - } - - @Override - public Transaction createTransaction(JDBCContext jdbcContext, Context transactionContext) { - return new JDBCTransaction(jdbcContext, transactionContext); - } - - @Override - public void configure(Properties props) { - } - - @Override - public boolean isTransactionManagerRequired() { - return false; - } - - @Override - public boolean areCallbacksLocalToHibernateTransactions() { - return true; - } - - @Override - public boolean isTransactionInProgress( - JDBCContext jdbcContext, Context transactionContext, Transaction transaction) { - - return (transaction != null && transaction.isActive()) || - TransactionSynchronizationManager.isActualTransactionActive(); - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/TransactionAwareDataSourceConnectionProvider.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/TransactionAwareDataSourceConnectionProvider.java deleted file mode 100644 index c91a03eaf9..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/TransactionAwareDataSourceConnectionProvider.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import javax.sql.DataSource; - -import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy; - -/** - * Subclass of LocalDataSourceConnectionProvider that returns a - * transaction-aware proxy for the exposed DataSource. Used if - * LocalSessionFactoryBean's "useTransactionAwareDataSource" flag is on. - * - * @author Juergen Hoeller - * @since 1.2 - * @see LocalSessionFactoryBean#setUseTransactionAwareDataSource - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public class TransactionAwareDataSourceConnectionProvider extends LocalDataSourceConnectionProvider { - - /** - * Return a TransactionAwareDataSourceProxy for the given DataSource, - * provided that it isn't a TransactionAwareDataSourceProxy already. - */ - @Override - protected DataSource getDataSourceToUse(DataSource originalDataSource) { - if (originalDataSource instanceof TransactionAwareDataSourceProxy) { - return originalDataSource; - } - return new TransactionAwareDataSourceProxy(originalDataSource); - } - - /** - * This implementation returns {@code true}: We can guarantee - * to receive the same Connection within a transaction, as we are - * exposing a TransactionAwareDataSourceProxy. - */ - @Override - public boolean supportsAggressiveRelease() { - return true; - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/TypeDefinitionBean.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/TypeDefinitionBean.java deleted file mode 100644 index ceae3a5d2c..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/TypeDefinitionBean.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import java.util.Properties; - -import org.springframework.beans.factory.BeanNameAware; -import org.springframework.beans.factory.InitializingBean; - -/** - * Bean that encapsulates a Hibernate type definition. - * - *

Typically defined as inner bean within a LocalSessionFactoryBean - * definition, as list element for the "typeDefinitions" bean property. - * For example: - * - *

- * <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
- *   ...
- *   <property name="typeDefinitions">
- *     <list>
- *       <bean class="org.springframework.orm.hibernate3.TypeDefinitionBean">
- *         <property name="typeName" value="myType"/>
- *         <property name="typeClass" value="mypackage.MyTypeClass"/>
- *       </bean>
- *     </list>
- *   </property>
- *   ...
- * </bean>
- * - * Alternatively, specify a bean id (or name) attribute for the inner bean, - * instead of the "typeName" property. - * - * @author Juergen Hoeller - * @since 1.2 - * @see LocalSessionFactoryBean#setTypeDefinitions(TypeDefinitionBean[]) - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public class TypeDefinitionBean implements BeanNameAware, InitializingBean { - - private String typeName; - - private String typeClass; - - private Properties parameters = new Properties(); - - - /** - * Set the name of the type. - * @see org.hibernate.cfg.Mappings#addTypeDef(String, String, java.util.Properties) - */ - public void setTypeName(String typeName) { - this.typeName = typeName; - } - - /** - * Return the name of the type. - */ - public String getTypeName() { - return typeName; - } - - /** - * Set the type implementation class. - * @see org.hibernate.cfg.Mappings#addTypeDef(String, String, java.util.Properties) - */ - public void setTypeClass(String typeClass) { - this.typeClass = typeClass; - } - - /** - * Return the type implementation class. - */ - public String getTypeClass() { - return typeClass; - } - - /** - * Specify default parameters for the type. - * This only applies to parameterized types. - * @see org.hibernate.cfg.Mappings#addTypeDef(String, String, java.util.Properties) - * @see org.hibernate.usertype.ParameterizedType - */ - public void setParameters(Properties parameters) { - this.parameters = parameters; - } - - /** - * Return the default parameters for the type. - */ - public Properties getParameters() { - return parameters; - } - - - /** - * If no explicit type name has been specified, the bean name of - * the TypeDefinitionBean will be used. - * @see #setTypeName - */ - @Override - public void setBeanName(String name) { - if (this.typeName == null) { - this.typeName = name; - } - } - - @Override - public void afterPropertiesSet() { - if (this.typeName == null) { - throw new IllegalArgumentException("typeName is required"); - } - if (this.typeClass == null) { - throw new IllegalArgumentException("typeClass is required"); - } - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/annotation/AnnotationSessionFactoryBean.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/annotation/AnnotationSessionFactoryBean.java deleted file mode 100644 index bc6f044062..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/annotation/AnnotationSessionFactoryBean.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3.annotation; - -import java.io.IOException; -import java.util.Set; -import java.util.TreeSet; -import javax.persistence.Embeddable; -import javax.persistence.Entity; -import javax.persistence.MappedSuperclass; - -import org.hibernate.HibernateException; -import org.hibernate.MappingException; -import org.hibernate.cfg.Configuration; - -import org.springframework.context.ResourceLoaderAware; -import org.springframework.core.io.Resource; -import org.springframework.core.io.ResourceLoader; -import org.springframework.core.io.support.PathMatchingResourcePatternResolver; -import org.springframework.core.io.support.ResourcePatternResolver; -import org.springframework.core.io.support.ResourcePatternUtils; -import org.springframework.core.type.classreading.CachingMetadataReaderFactory; -import org.springframework.core.type.classreading.MetadataReader; -import org.springframework.core.type.classreading.MetadataReaderFactory; -import org.springframework.core.type.filter.AnnotationTypeFilter; -import org.springframework.core.type.filter.TypeFilter; -import org.springframework.util.ClassUtils; - -/** - * Subclass of Spring's standard LocalSessionFactoryBean for Hibernate, - * supporting annotation metadata for mappings. - * - *

Example for an AnnotationSessionFactoryBean bean definition: - * - *

- * <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
- *   <property name="dataSource" ref="dataSource"/>
- *   <property name="annotatedClasses">
- *     <list>
- *       <value>test.package.Foo</value>
- *       <value>test.package.Bar</value>
- *     </list>
- *   </property>
- * </bean>
- * - * Or when using classpath scanning for autodetection of entity classes: - * - *
- * <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
- *   <property name="dataSource" ref="dataSource"/>
- *   <property name="packagesToScan" value="test.package"/>
- * </bean>
- * - *

Requires Hibernate 3.6.x, as of Spring 4.0. - * - * @author Juergen Hoeller - * @since 1.2.2 - * @see #setDataSource - * @see #setHibernateProperties - * @see #setAnnotatedClasses - * @see #setAnnotatedPackages - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public class AnnotationSessionFactoryBean extends org.springframework.orm.hibernate3.LocalSessionFactoryBean - implements ResourceLoaderAware { - - private static final String RESOURCE_PATTERN = "/**/*.class"; - - private static final String PACKAGE_INFO_SUFFIX = ".package-info"; - - - private Class[] annotatedClasses; - - private String[] annotatedPackages; - - private String[] packagesToScan; - - private TypeFilter[] entityTypeFilters = new TypeFilter[] { - new AnnotationTypeFilter(Entity.class, false), - new AnnotationTypeFilter(Embeddable.class, false), - new AnnotationTypeFilter(MappedSuperclass.class, false), - new AnnotationTypeFilter(org.hibernate.annotations.Entity.class, false)}; - - private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver(); - - - /** - * Specify annotated classes, for which mappings will be read from - * class-level annotation metadata. - * @see org.hibernate.cfg.Configuration#addAnnotatedClass(Class) - */ - public void setAnnotatedClasses(Class... annotatedClasses) { - this.annotatedClasses = annotatedClasses; - } - - /** - * Specify the names of annotated packages, for which package-level - * annotation metadata will be read. - * @see org.hibernate.cfg.Configuration#addPackage(String) - */ - public void setAnnotatedPackages(String... annotatedPackages) { - this.annotatedPackages = annotatedPackages; - } - - /** - * Specify packages to search using Spring-based scanning for entity classes in - * the classpath. This is an alternative to listing annotated classes explicitly. - *

Default is none. Specify packages to search for autodetection of your entity - * classes in the classpath. This is analogous to Spring's component-scan feature - * ({@link org.springframework.context.annotation.ClassPathBeanDefinitionScanner}). - */ - public void setPackagesToScan(String... packagesToScan) { - this.packagesToScan = packagesToScan; - } - - /** - * Specify custom type filters for Spring-based scanning for entity classes. - *

Default is to search all specified packages for classes annotated with - * {@code @javax.persistence.Entity}, {@code @javax.persistence.Embeddable} - * or {@code @javax.persistence.MappedSuperclass}, as well as for - * Hibernate's special {@code @org.hibernate.annotations.Entity}. - * @see #setPackagesToScan - */ - public void setEntityTypeFilters(TypeFilter... entityTypeFilters) { - this.entityTypeFilters = entityTypeFilters; - } - - @Override - public void setResourceLoader(ResourceLoader resourceLoader) { - this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader); - } - - - /** - * Reads metadata from annotated classes and packages into the - * AnnotationConfiguration instance. - */ - @Override - protected void postProcessMappings(Configuration config) throws HibernateException { - if (this.annotatedClasses != null) { - for (Class annotatedClass : this.annotatedClasses) { - config.addAnnotatedClass(annotatedClass); - } - } - if (this.annotatedPackages != null) { - for (String annotatedPackage : this.annotatedPackages) { - config.addPackage(annotatedPackage); - } - } - scanPackages(config); - } - - /** - * Perform Spring-based scanning for entity classes. - * @see #setPackagesToScan - */ - protected void scanPackages(Configuration config) { - if (this.packagesToScan != null) { - Set classNames = new TreeSet(); - Set packageNames = new TreeSet(); - try { - for (String pkg : this.packagesToScan) { - String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + - ClassUtils.convertClassNameToResourcePath(pkg) + RESOURCE_PATTERN; - Resource[] resources = this.resourcePatternResolver.getResources(pattern); - MetadataReaderFactory readerFactory = new CachingMetadataReaderFactory(this.resourcePatternResolver); - for (Resource resource : resources) { - if (resource.isReadable()) { - MetadataReader reader = readerFactory.getMetadataReader(resource); - String className = reader.getClassMetadata().getClassName(); - if (matchesEntityTypeFilter(reader, readerFactory)) { - classNames.add(className); - } - else if (className.endsWith(PACKAGE_INFO_SUFFIX)) { - packageNames.add(className.substring(0, className.length() - PACKAGE_INFO_SUFFIX.length())); - } - } - } - } - } - catch (IOException ex) { - throw new MappingException("Failed to scan classpath for unlisted classes", ex); - } - try { - for (String className : classNames) { - config.addAnnotatedClass(this.resourcePatternResolver.getClassLoader().loadClass(className)); - } - for (String packageName : packageNames) { - config.addPackage(packageName); - } - } - catch (ClassNotFoundException ex) { - throw new MappingException("Failed to load annotated classes from classpath", ex); - } - } - } - - /** - * Check whether any of the configured entity type filters matches - * the current class descriptor contained in the metadata reader. - */ - private boolean matchesEntityTypeFilter(MetadataReader reader, MetadataReaderFactory readerFactory) throws IOException { - if (this.entityTypeFilters != null) { - for (TypeFilter filter : this.entityTypeFilters) { - if (filter.match(reader, readerFactory)) { - return true; - } - } - } - return false; - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/annotation/package-info.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/annotation/package-info.java deleted file mode 100644 index 7dca40badd..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/annotation/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -/** - * Support package for the Hibernate 3 Annotation add-on, - * which supports JPA-compliant Java 5+ annotations for mappings. - */ -package org.springframework.orm.hibernate3.annotation; diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/package-info.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/package-info.java deleted file mode 100644 index 347980f8e0..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/package-info.java +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Package providing integration of - * Hibernate 3.x - * with Spring concepts. - * - *

Contains SessionFactory helper classes, a template plus callback - * for Hibernate access, and an implementation of Spring's transaction SPI - * for local Hibernate transactions. - * - *

This package supports Hibernate 3.x only. - * See the {@code org.springframework.orm.hibernate4} package for Hibernate 4.x support. - */ -package org.springframework.orm.hibernate3; diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/AbstractLobType.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/AbstractLobType.java deleted file mode 100644 index 96cb017086..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/AbstractLobType.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3.support; - -import java.io.IOException; -import java.io.Serializable; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import javax.transaction.TransactionManager; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.hibernate.HibernateException; -import org.hibernate.usertype.UserType; -import org.hibernate.util.EqualsHelper; - -import org.springframework.jdbc.support.lob.LobCreator; -import org.springframework.jdbc.support.lob.LobCreatorUtils; -import org.springframework.jdbc.support.lob.LobHandler; - -/** - * Abstract base class for Hibernate UserType implementations that map to LOBs. - * Retrieves the LobHandler to use from LocalSessionFactoryBean at config time. - * - *

For writing LOBs, either an active Spring transaction synchronization - * or an active JTA transaction (with "jtaTransactionManager" specified on - * LocalSessionFactoryBean or a Hibernate TransactionManagerLookup configured - * through the corresponding Hibernate property) is required. - * - *

Offers template methods for setting parameters and getting result values, - * passing in the LobHandler or LobCreator to use. - * - * @author Juergen Hoeller - * @since 1.2 - * @see org.springframework.jdbc.support.lob.LobHandler - * @see org.springframework.jdbc.support.lob.LobCreator - * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#setLobHandler - * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#setJtaTransactionManager - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public abstract class AbstractLobType implements UserType { - - protected final Log logger = LogFactory.getLog(getClass()); - - private final LobHandler lobHandler; - - private final TransactionManager jtaTransactionManager; - - - /** - * Constructor used by Hibernate: fetches config-time LobHandler and - * config-time JTA TransactionManager from LocalSessionFactoryBean. - * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#getConfigTimeLobHandler - * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#getConfigTimeTransactionManager - */ - protected AbstractLobType() { - this(org.springframework.orm.hibernate3.LocalSessionFactoryBean.getConfigTimeLobHandler(), - org.springframework.orm.hibernate3.LocalSessionFactoryBean.getConfigTimeTransactionManager()); - } - - /** - * Constructor used for testing: takes an explicit LobHandler - * and an explicit JTA TransactionManager (can be {@code null}). - */ - protected AbstractLobType(LobHandler lobHandler, TransactionManager jtaTransactionManager) { - this.lobHandler = lobHandler; - this.jtaTransactionManager = jtaTransactionManager; - } - - - /** - * This implementation returns false. - */ - @Override - public boolean isMutable() { - return false; - } - - /** - * This implementation delegates to the Hibernate EqualsHelper. - * @see org.hibernate.util.EqualsHelper#equals - */ - @Override - public boolean equals(Object x, Object y) throws HibernateException { - return EqualsHelper.equals(x, y); - } - - /** - * This implementation returns the hashCode of the given objectz. - */ - @Override - public int hashCode(Object x) throws HibernateException { - return x.hashCode(); - } - - /** - * This implementation returns the passed-in value as-is. - */ - @Override - public Object deepCopy(Object value) throws HibernateException { - return value; - } - - /** - * This implementation returns the passed-in value as-is. - */ - @Override - public Serializable disassemble(Object value) throws HibernateException { - return (Serializable) value; - } - - /** - * This implementation returns the passed-in value as-is. - */ - @Override - public Object assemble(Serializable cached, Object owner) throws HibernateException { - return cached; - } - - /** - * This implementation returns the passed-in original as-is. - */ - @Override - public Object replace(Object original, Object target, Object owner) throws HibernateException { - return original; - } - - - /** - * This implementation delegates to nullSafeGetInternal, - * passing in the LobHandler of this type. - * @see #nullSafeGetInternal - */ - @Override - @Deprecated - public final Object nullSafeGet(ResultSet rs, String[] names, Object owner) - throws HibernateException, SQLException { - - if (this.lobHandler == null) { - throw new IllegalStateException("No LobHandler found for configuration - " + - "lobHandler property must be set on LocalSessionFactoryBean"); - } - - try { - return nullSafeGetInternal(rs, names, owner, this.lobHandler); - } - catch (IOException ex) { - throw new HibernateException("I/O errors during LOB access", ex); - } - } - - /** - * This implementation delegates to nullSafeSetInternal, - * passing in a transaction-synchronized LobCreator for the - * LobHandler of this type. - * @see #nullSafeSetInternal - */ - @Override - @Deprecated - public final void nullSafeSet(PreparedStatement st, Object value, int index) - throws HibernateException, SQLException { - - if (this.lobHandler == null) { - throw new IllegalStateException("No LobHandler found for configuration - " + - "lobHandler property must be set on LocalSessionFactoryBean"); - } - - LobCreator lobCreator = this.lobHandler.getLobCreator(); - try { - nullSafeSetInternal(st, index, value, lobCreator); - } - catch (IOException ex) { - throw new HibernateException("I/O errors during LOB access", ex); - } - LobCreatorUtils.registerTransactionSynchronization(lobCreator, this.jtaTransactionManager); - } - - /** - * Template method to extract a value from the given result set. - * @param rs the ResultSet to extract from - * @param names the column names - * @param owner the containing entity - * @param lobHandler the LobHandler to use - * @return the extracted value - * @throws SQLException if thrown by JDBC methods - * @throws IOException if thrown by streaming methods - * @throws HibernateException in case of any other exceptions - */ - protected abstract Object nullSafeGetInternal( - ResultSet rs, String[] names, Object owner, LobHandler lobHandler) - throws SQLException, IOException, HibernateException; - - /** - * Template method to set the given parameter value on the given statement. - * @param ps the PreparedStatement to set on - * @param index the statement parameter index - * @param value the value to set - * @param lobCreator the LobCreator to use - * @throws SQLException if thrown by JDBC methods - * @throws IOException if thrown by streaming methods - * @throws HibernateException in case of any other exceptions - */ - protected abstract void nullSafeSetInternal( - PreparedStatement ps, int index, Object value, LobCreator lobCreator) - throws SQLException, IOException, HibernateException; - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/AsyncRequestInterceptor.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/AsyncRequestInterceptor.java deleted file mode 100644 index 844e2f3f47..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/AsyncRequestInterceptor.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2002-2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3.support; - -import java.util.concurrent.Callable; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.hibernate.SessionFactory; - -import org.springframework.transaction.support.TransactionSynchronizationManager; -import org.springframework.web.context.request.NativeWebRequest; -import org.springframework.web.context.request.async.CallableProcessingInterceptorAdapter; -import org.springframework.web.context.request.async.DeferredResult; -import org.springframework.web.context.request.async.DeferredResultProcessingInterceptor; - -/** - * An interceptor with asynchronous web requests used in OpenSessionInViewFilter and - * OpenSessionInViewInterceptor. - * - * Ensures the following: - * 1) The session is bound/unbound when "callable processing" is started - * 2) The session is closed if an async request times out - * - * @author Rossen Stoyanchev - * @since 3.2.5 - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -class AsyncRequestInterceptor extends CallableProcessingInterceptorAdapter implements DeferredResultProcessingInterceptor { - - private static final Log logger = LogFactory.getLog(AsyncRequestInterceptor.class); - - private final SessionFactory sessionFactory; - - private final org.springframework.orm.hibernate3.SessionHolder sessionHolder; - - private volatile boolean timeoutInProgress; - - - public AsyncRequestInterceptor(SessionFactory sessionFactory, org.springframework.orm.hibernate3.SessionHolder sessionHolder) { - this.sessionFactory = sessionFactory; - this.sessionHolder = sessionHolder; - } - - - @Override - public void preProcess(NativeWebRequest request, Callable task) { - bindSession(); - } - - public void bindSession() { - this.timeoutInProgress = false; - TransactionSynchronizationManager.bindResource(this.sessionFactory, this.sessionHolder); - } - - @Override - public void postProcess(NativeWebRequest request, Callable task, Object concurrentResult) { - TransactionSynchronizationManager.unbindResource(this.sessionFactory); - } - - @Override - public Object handleTimeout(NativeWebRequest request, Callable task) { - this.timeoutInProgress = true; - return RESULT_NONE; // give other interceptors a chance to handle the timeout - } - - @Override - public void afterCompletion(NativeWebRequest request, Callable task) throws Exception { - closeAfterTimeout(); - } - - private void closeAfterTimeout() { - if (this.timeoutInProgress) { - logger.debug("Closing Hibernate Session after async request timeout"); - org.springframework.orm.hibernate3.SessionFactoryUtils.closeSession(this.sessionHolder.getSession()); - } - } - - - // Implementation of DeferredResultProcessingInterceptor methods - - @Override - public void beforeConcurrentHandling(NativeWebRequest request, DeferredResult deferredResult) { - } - - @Override - public void preProcess(NativeWebRequest request, DeferredResult deferredResult) { - } - - @Override - public void postProcess(NativeWebRequest request, DeferredResult deferredResult, Object result) { - } - - @Override - public boolean handleTimeout(NativeWebRequest request, DeferredResult deferredResult) { - this.timeoutInProgress = true; - return true; // give other interceptors a chance to handle the timeout - } - - @Override - public void afterCompletion(NativeWebRequest request, DeferredResult deferredResult) { - closeAfterTimeout(); - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/BlobByteArrayType.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/BlobByteArrayType.java deleted file mode 100644 index f1dd0882a9..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/BlobByteArrayType.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3.support; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; -import java.util.Arrays; -import javax.transaction.TransactionManager; - -import org.springframework.jdbc.support.lob.LobCreator; -import org.springframework.jdbc.support.lob.LobHandler; - -/** - * Hibernate UserType implementation for byte arrays that get mapped to BLOBs. - * Retrieves the LobHandler to use from LocalSessionFactoryBean at config time. - * - *

Can also be defined in generic Hibernate mappings, as DefaultLobCreator will - * work with most JDBC-compliant database drivers. In this case, the field type - * does not have to be BLOB: For databases like MySQL and MS SQL Server, any - * large enough binary type will work. - * - * @author Juergen Hoeller - * @since 1.2 - * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#setLobHandler - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public class BlobByteArrayType extends AbstractLobType { - - /** - * Constructor used by Hibernate: fetches config-time LobHandler and - * config-time JTA TransactionManager from LocalSessionFactoryBean. - * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#getConfigTimeLobHandler - * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#getConfigTimeTransactionManager - */ - public BlobByteArrayType() { - super(); - } - - /** - * Constructor used for testing: takes an explicit LobHandler - * and an explicit JTA TransactionManager (can be {@code null}). - */ - protected BlobByteArrayType(LobHandler lobHandler, TransactionManager jtaTransactionManager) { - super(lobHandler, jtaTransactionManager); - } - - @Override - public int[] sqlTypes() { - return new int[] {Types.BLOB}; - } - - @Override - public Class returnedClass() { - return byte[].class; - } - - @Override - public boolean isMutable() { - return true; - } - - @Override - public boolean equals(Object x, Object y) { - return (x == y) || - (x instanceof byte[] && y instanceof byte[] && Arrays.equals((byte[]) x, (byte[]) y)); - } - - @Override - public Object deepCopy(Object value) { - if (value == null) { - return null; - } - byte[] original = (byte[]) value; - byte[] copy = new byte[original.length]; - System.arraycopy(original, 0, copy, 0, original.length); - return copy; - } - - @Override - protected Object nullSafeGetInternal( - ResultSet rs, String[] names, Object owner, LobHandler lobHandler) - throws SQLException { - - return lobHandler.getBlobAsBytes(rs, names[0]); - } - - @Override - protected void nullSafeSetInternal( - PreparedStatement ps, int index, Object value, LobCreator lobCreator) - throws SQLException { - - lobCreator.setBlobAsBytes(ps, index, (byte[]) value); - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/BlobSerializableType.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/BlobSerializableType.java deleted file mode 100644 index 42dec75d4c..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/BlobSerializableType.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3.support; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; -import javax.transaction.TransactionManager; - -import org.hibernate.HibernateException; - -import org.springframework.jdbc.support.lob.LobCreator; -import org.springframework.jdbc.support.lob.LobHandler; - -/** - * Hibernate UserType implementation for arbitrary objects that get serialized to BLOBs. - * Retrieves the LobHandler to use from LocalSessionFactoryBean at config time. - * - *

Can also be defined in generic Hibernate mappings, as DefaultLobCreator will - * work with most JDBC-compliant database drivers. In this case, the field type - * does not have to be BLOB: For databases like MySQL and MS SQL Server, any - * large enough binary type will work. - * - * @author Juergen Hoeller - * @since 1.2 - * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#setLobHandler - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public class BlobSerializableType extends AbstractLobType { - - /** - * Initial size for ByteArrayOutputStreams used for serialization output. - *

If a serialized object is larger than these 1024 bytes, the size of - * the byte array used by the output stream will be doubled each time the - * limit is reached. - */ - private static final int OUTPUT_BYTE_ARRAY_INITIAL_SIZE = 1024; - - /** - * Constructor used by Hibernate: fetches config-time LobHandler and - * config-time JTA TransactionManager from LocalSessionFactoryBean. - * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#getConfigTimeLobHandler - * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#getConfigTimeTransactionManager - */ - public BlobSerializableType() { - super(); - } - - /** - * Constructor used for testing: takes an explicit LobHandler - * and an explicit JTA TransactionManager (can be {@code null}). - */ - protected BlobSerializableType(LobHandler lobHandler, TransactionManager jtaTransactionManager) { - super(lobHandler, jtaTransactionManager); - } - - @Override - public int[] sqlTypes() { - return new int[] {Types.BLOB}; - } - - @Override - public Class returnedClass() { - return Serializable.class; - } - - @Override - public boolean isMutable() { - return true; - } - - @Override - public Object deepCopy(Object value) throws HibernateException { - try { - // Write to new byte array to clone. - ByteArrayOutputStream baos = new ByteArrayOutputStream(OUTPUT_BYTE_ARRAY_INITIAL_SIZE); - ObjectOutputStream oos = new ObjectOutputStream(baos); - try { - oos.writeObject(value); - } - finally { - oos.close(); - } - - // Read it back and return a true copy. - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - ObjectInputStream ois = new ObjectInputStream(bais); - try { - return ois.readObject(); - } - finally { - ois.close(); - } - } - catch (ClassNotFoundException ex) { - throw new HibernateException("Couldn't clone BLOB contents", ex); - } - catch (IOException ex) { - throw new HibernateException("Couldn't clone BLOB contents", ex); - } - } - - @Override - protected Object nullSafeGetInternal( - ResultSet rs, String[] names, Object owner, LobHandler lobHandler) - throws SQLException, IOException, HibernateException { - - InputStream is = lobHandler.getBlobAsBinaryStream(rs, names[0]); - if (is != null) { - ObjectInputStream ois = new ObjectInputStream(is); - try { - return ois.readObject(); - } - catch (ClassNotFoundException ex) { - throw new HibernateException("Could not deserialize BLOB contents", ex); - } - finally { - ois.close(); - } - } - else { - return null; - } - } - - @Override - protected void nullSafeSetInternal( - PreparedStatement ps, int index, Object value, LobCreator lobCreator) - throws SQLException, IOException { - - if (value != null) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(OUTPUT_BYTE_ARRAY_INITIAL_SIZE); - ObjectOutputStream oos = new ObjectOutputStream(baos); - try { - oos.writeObject(value); - oos.flush(); - lobCreator.setBlobAsBytes(ps, index, baos.toByteArray()); - } - finally { - oos.close(); - } - } - else { - lobCreator.setBlobAsBytes(ps, index, null); - } - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/BlobStringType.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/BlobStringType.java deleted file mode 100644 index 0d6e399c04..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/BlobStringType.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3.support; - -import java.io.UnsupportedEncodingException; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; -import javax.transaction.TransactionManager; - -import org.springframework.jdbc.support.lob.LobCreator; -import org.springframework.jdbc.support.lob.LobHandler; - -/** - * Hibernate UserType implementation for Strings that get mapped to BLOBs. - * Retrieves the LobHandler to use from LocalSessionFactoryBean at config time. - * - *

This is intended for the (arguably unnatural, but still common) case - * where character data is stored in a binary LOB. This requires encoding - * and decoding the characters within this UserType; see the javadoc of the - * {@code getCharacterEncoding()} method. - * - *

Can also be defined in generic Hibernate mappings, as DefaultLobCreator will - * work with most JDBC-compliant database drivers. In this case, the field type - * does not have to be BLOB: For databases like MySQL and MS SQL Server, any - * large enough binary type will work. - * - * @author Juergen Hoeller - * @since 1.2.7 - * @see #getCharacterEncoding() - * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#setLobHandler - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public class BlobStringType extends AbstractLobType { - - /** - * Constructor used by Hibernate: fetches config-time LobHandler and - * config-time JTA TransactionManager from LocalSessionFactoryBean. - * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#getConfigTimeLobHandler - * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#getConfigTimeTransactionManager - */ - public BlobStringType() { - super(); - } - - /** - * Constructor used for testing: takes an explicit LobHandler - * and an explicit JTA TransactionManager (can be {@code null}). - */ - protected BlobStringType(LobHandler lobHandler, TransactionManager jtaTransactionManager) { - super(lobHandler, jtaTransactionManager); - } - - @Override - public int[] sqlTypes() { - return new int[] {Types.BLOB}; - } - - @Override - public Class returnedClass() { - return String.class; - } - - @Override - protected Object nullSafeGetInternal( - ResultSet rs, String[] names, Object owner, LobHandler lobHandler) - throws SQLException, UnsupportedEncodingException { - - byte[] bytes = lobHandler.getBlobAsBytes(rs, names[0]); - if (bytes != null) { - String encoding = getCharacterEncoding(); - return (encoding != null ? new String(bytes, encoding) : new String(bytes)); - } - else { - return null; - } - } - - @Override - protected void nullSafeSetInternal( - PreparedStatement ps, int index, Object value, LobCreator lobCreator) - throws SQLException, UnsupportedEncodingException { - - if (value != null) { - String str = (String) value; - String encoding = getCharacterEncoding(); - byte[] bytes = (encoding != null ? str.getBytes(encoding) : str.getBytes()); - lobCreator.setBlobAsBytes(ps, index, bytes); - } - else { - lobCreator.setBlobAsBytes(ps, index, null); - } - } - - /** - * Determine the character encoding to apply to the BLOB's bytes - * to turn them into a String. - *

Default is {@code null}, indicating to use the platform - * default encoding. To be overridden in subclasses for a specific - * encoding such as "ISO-8859-1" or "UTF-8". - * @return the character encoding to use, or {@code null} - * to use the platform default encoding - * @see String#String(byte[], String) - * @see String#getBytes(String) - */ - protected String getCharacterEncoding() { - return null; - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/ClobStringType.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/ClobStringType.java deleted file mode 100644 index 6fe9786c0f..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/ClobStringType.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3.support; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; -import javax.transaction.TransactionManager; - -import org.springframework.jdbc.support.lob.LobCreator; -import org.springframework.jdbc.support.lob.LobHandler; - -/** - * Hibernate UserType implementation for Strings that get mapped to CLOBs. - * Retrieves the LobHandler to use from LocalSessionFactoryBean at config time. - * - *

Particularly useful for storing Strings with more than 4000 characters in an - * Oracle database (only possible via CLOBs), in combination with OracleLobHandler. - * - *

Can also be defined in generic Hibernate mappings, as DefaultLobCreator will - * work with most JDBC-compliant database drivers. In this case, the field type - * does not have to be CLOB: For databases like MySQL and MS SQL Server, any - * large enough character type will work. - * - * @author Juergen Hoeller - * @since 1.2 - * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#setLobHandler - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public class ClobStringType extends AbstractLobType { - - /** - * Constructor used by Hibernate: fetches config-time LobHandler and - * config-time JTA TransactionManager from LocalSessionFactoryBean. - * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#getConfigTimeLobHandler - * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#getConfigTimeTransactionManager - */ - public ClobStringType() { - super(); - } - - /** - * Constructor used for testing: takes an explicit LobHandler - * and an explicit JTA TransactionManager (can be {@code null}). - */ - protected ClobStringType(LobHandler lobHandler, TransactionManager jtaTransactionManager) { - super(lobHandler, jtaTransactionManager); - } - - @Override - public int[] sqlTypes() { - return new int[] {Types.CLOB}; - } - - @Override - public Class returnedClass() { - return String.class; - } - - @Override - protected Object nullSafeGetInternal( - ResultSet rs, String[] names, Object owner, LobHandler lobHandler) - throws SQLException { - - return lobHandler.getClobAsString(rs, names[0]); - } - - @Override - protected void nullSafeSetInternal( - PreparedStatement ps, int index, Object value, LobCreator lobCreator) - throws SQLException { - - lobCreator.setClobAsString(ps, index, (String) value); - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/HibernateDaoSupport.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/HibernateDaoSupport.java deleted file mode 100644 index 32aa867faf..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/HibernateDaoSupport.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3.support; - -import org.hibernate.HibernateException; -import org.hibernate.Session; -import org.hibernate.SessionFactory; - -import org.springframework.dao.DataAccessException; -import org.springframework.dao.DataAccessResourceFailureException; -import org.springframework.dao.support.DaoSupport; - -/** - * Convenient super class for Hibernate-based data access objects. - * - *

Requires a {@link org.hibernate.SessionFactory} to be set, providing a - * {@link org.springframework.orm.hibernate3.HibernateTemplate} based on it to - * subclasses through the {@link #getHibernateTemplate()} method. - * Can alternatively be initialized directly with a HibernateTemplate, - * in order to reuse the latter's settings such as the SessionFactory, - * exception translator, flush mode, etc. - * - *

This base class is mainly intended for HibernateTemplate usage but can - * also be used when working with a Hibernate Session directly, for example - * when relying on transactional Sessions. Convenience {@link #getSession} - * and {@link #releaseSession} methods are provided for that usage style. - * - *

This class will create its own HibernateTemplate instance if a SessionFactory - * is passed in. The "allowCreate" flag on that HibernateTemplate will be "true" - * by default. A custom HibernateTemplate instance can be used through overriding - * {@link #createHibernateTemplate}. - * - *

NOTE: As of Hibernate 3.0.1, transactional Hibernate access code can - * also be coded in plain Hibernate style. Hence, for newly started projects, - * consider adopting the standard Hibernate3 style of coding data access objects - * instead, based on {@link org.hibernate.SessionFactory#getCurrentSession()}. - * - * @author Juergen Hoeller - * @since 1.2 - * @see #setSessionFactory - * @see #getHibernateTemplate - * @see org.springframework.orm.hibernate3.HibernateTemplate - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public abstract class HibernateDaoSupport extends DaoSupport { - - private org.springframework.orm.hibernate3.HibernateTemplate hibernateTemplate; - - - /** - * Set the Hibernate SessionFactory to be used by this DAO. - * Will automatically create a HibernateTemplate for the given SessionFactory. - * @see #createHibernateTemplate - * @see #setHibernateTemplate - */ - public final void setSessionFactory(SessionFactory sessionFactory) { - if (this.hibernateTemplate == null || sessionFactory != this.hibernateTemplate.getSessionFactory()) { - this.hibernateTemplate = createHibernateTemplate(sessionFactory); - } - } - - /** - * Create a HibernateTemplate for the given SessionFactory. - * Only invoked if populating the DAO with a SessionFactory reference! - *

Can be overridden in subclasses to provide a HibernateTemplate instance - * with different configuration, or a custom HibernateTemplate subclass. - * @param sessionFactory the Hibernate SessionFactory to create a HibernateTemplate for - * @return the new HibernateTemplate instance - * @see #setSessionFactory - */ - protected org.springframework.orm.hibernate3.HibernateTemplate createHibernateTemplate(SessionFactory sessionFactory) { - return new org.springframework.orm.hibernate3.HibernateTemplate(sessionFactory); - } - - /** - * Return the Hibernate SessionFactory used by this DAO. - */ - public final SessionFactory getSessionFactory() { - return (this.hibernateTemplate != null ? this.hibernateTemplate.getSessionFactory() : null); - } - - /** - * Set the HibernateTemplate for this DAO explicitly, - * as an alternative to specifying a SessionFactory. - * @see #setSessionFactory - */ - public final void setHibernateTemplate(org.springframework.orm.hibernate3.HibernateTemplate hibernateTemplate) { - this.hibernateTemplate = hibernateTemplate; - } - - /** - * Return the HibernateTemplate for this DAO, - * pre-initialized with the SessionFactory or set explicitly. - *

Note: The returned HibernateTemplate is a shared instance. - * You may introspect its configuration, but not modify the configuration - * (other than from within an {@link #initDao} implementation). - * Consider creating a custom HibernateTemplate instance via - * {@code new HibernateTemplate(getSessionFactory())}, in which case - * you're allowed to customize the settings on the resulting instance. - */ - public final org.springframework.orm.hibernate3.HibernateTemplate getHibernateTemplate() { - return this.hibernateTemplate; - } - - @Override - protected final void checkDaoConfig() { - if (this.hibernateTemplate == null) { - throw new IllegalArgumentException("'sessionFactory' or 'hibernateTemplate' is required"); - } - } - - - /** - * Obtain a Hibernate Session, either from the current transaction or - * a new one. The latter is only allowed if the - * {@link org.springframework.orm.hibernate3.HibernateTemplate#setAllowCreate "allowCreate"} - * setting of this bean's {@link #setHibernateTemplate HibernateTemplate} is "true". - *

Note that this is not meant to be invoked from HibernateTemplate code - * but rather just in plain Hibernate code. Either rely on a thread-bound - * Session or use it in combination with {@link #releaseSession}. - *

In general, it is recommended to use HibernateTemplate, either with - * the provided convenience operations or with a custom HibernateCallback - * that provides you with a Session to work on. HibernateTemplate will care - * for all resource management and for proper exception conversion. - * @return the Hibernate Session - * @throws DataAccessResourceFailureException if the Session couldn't be created - * @throws IllegalStateException if no thread-bound Session found and allowCreate=false - * @see org.springframework.orm.hibernate3.SessionFactoryUtils#getSession(SessionFactory, boolean) - * @deprecated as of Spring 3.2.7, in favor of {@link org.springframework.orm.hibernate3.HibernateTemplate} usage - */ - @Deprecated - protected final Session getSession() throws DataAccessResourceFailureException, IllegalStateException { - return getSession(this.hibernateTemplate.isAllowCreate()); - } - - /** - * Obtain a Hibernate Session, either from the current transaction or - * a new one. The latter is only allowed if "allowCreate" is true. - *

Note that this is not meant to be invoked from HibernateTemplate code - * but rather just in plain Hibernate code. Either rely on a thread-bound - * Session or use it in combination with {@link #releaseSession}. - *

In general, it is recommended to use - * {@link #getHibernateTemplate() HibernateTemplate}, either with - * the provided convenience operations or with a custom - * {@link org.springframework.orm.hibernate3.HibernateCallback} that - * provides you with a Session to work on. HibernateTemplate will care - * for all resource management and for proper exception conversion. - * @param allowCreate if a non-transactional Session should be created when no - * transactional Session can be found for the current thread - * @return the Hibernate Session - * @throws DataAccessResourceFailureException if the Session couldn't be created - * @throws IllegalStateException if no thread-bound Session found and allowCreate=false - * @see org.springframework.orm.hibernate3.SessionFactoryUtils#getSession(SessionFactory, boolean) - * @deprecated as of Spring 3.2.7, in favor of {@link org.springframework.orm.hibernate3.HibernateTemplate} usage - */ - @Deprecated - protected final Session getSession(boolean allowCreate) - throws DataAccessResourceFailureException, IllegalStateException { - - return (!allowCreate ? - org.springframework.orm.hibernate3.SessionFactoryUtils.getSession(getSessionFactory(), false) : - org.springframework.orm.hibernate3.SessionFactoryUtils.getSession( - getSessionFactory(), - this.hibernateTemplate.getEntityInterceptor(), - this.hibernateTemplate.getJdbcExceptionTranslator())); - } - - /** - * Convert the given HibernateException to an appropriate exception from the - * {@code org.springframework.dao} hierarchy. Will automatically detect - * wrapped SQLExceptions and convert them accordingly. - *

Delegates to the - * {@link org.springframework.orm.hibernate3.HibernateTemplate#convertHibernateAccessException} - * method of this DAO's HibernateTemplate. - *

Typically used in plain Hibernate code, in combination with - * {@link #getSession} and {@link #releaseSession}. - * @param ex HibernateException that occurred - * @return the corresponding DataAccessException instance - * @see org.springframework.orm.hibernate3.SessionFactoryUtils#convertHibernateAccessException - * @deprecated as of Spring 3.2.7, in favor of {@link org.springframework.orm.hibernate3.HibernateTemplate} usage - */ - @Deprecated - protected final DataAccessException convertHibernateAccessException(HibernateException ex) { - return this.hibernateTemplate.convertHibernateAccessException(ex); - } - - /** - * Close the given Hibernate Session, created via this DAO's SessionFactory, - * if it isn't bound to the thread (i.e. isn't a transactional Session). - *

Typically used in plain Hibernate code, in combination with - * {@link #getSession} and {@link #convertHibernateAccessException}. - * @param session the Session to close - * @see org.springframework.orm.hibernate3.SessionFactoryUtils#releaseSession - * @deprecated as of Spring 3.2.7, in favor of {@link org.springframework.orm.hibernate3.HibernateTemplate} usage - */ - @Deprecated - protected final void releaseSession(Session session) { - org.springframework.orm.hibernate3.SessionFactoryUtils.releaseSession(session, getSessionFactory()); - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/IdTransferringMergeEventListener.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/IdTransferringMergeEventListener.java deleted file mode 100644 index 646c973a39..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/IdTransferringMergeEventListener.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3.support; - -import java.io.Serializable; -import java.util.Map; - -import org.hibernate.engine.SessionImplementor; -import org.hibernate.event.MergeEvent; -import org.hibernate.event.def.DefaultMergeEventListener; -import org.hibernate.persister.entity.EntityPersister; - -/** - * Extension of Hibernate's DefaultMergeEventListener, transferring the ids - * of newly saved objects to the corresponding original objects (that are part - * of the detached object graph passed into the {@code merge} method). - * - *

Transferring newly assigned ids to the original graph allows for continuing - * to use the original object graph, despite merged copies being registered with - * the current Hibernate Session. This is particularly useful for web applications - * that might want to store an object graph and then render it in a web view, - * with links that include the id of certain (potentially newly saved) objects. - * - *

The merge behavior given by this MergeEventListener is nearly identical - * to TopLink's merge behavior. See PetClinic for an example, which relies on - * ids being available for newly saved objects: the {@code HibernateClinic} - * and {@code TopLinkClinic} DAO implementations both use straight merge - * calls, with the Hibernate SessionFactory configuration specifying an - * {@code IdTransferringMergeEventListener}. - * - *

Typically specified as entry for LocalSessionFactoryBean's "eventListeners" - * map, with key "merge". - * - * @author Juergen Hoeller - * @since 1.2 - * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#setEventListeners(java.util.Map) - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -@SuppressWarnings({"serial", "rawtypes"}) -public class IdTransferringMergeEventListener extends DefaultMergeEventListener { - - /** - * Hibernate 3.1 implementation of ID transferral. - */ - @Override - protected void entityIsTransient(MergeEvent event, Map copyCache) { - super.entityIsTransient(event, copyCache); - SessionImplementor session = event.getSession(); - EntityPersister persister = session.getEntityPersister(event.getEntityName(), event.getEntity()); - // Extract id from merged copy (which is currently registered with Session). - Serializable id = persister.getIdentifier(event.getResult(), session.getEntityMode()); - // Set id on original object (which remains detached). - persister.setIdentifier(event.getOriginal(), id, session.getEntityMode()); - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/OpenSessionInViewFilter.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/OpenSessionInViewFilter.java deleted file mode 100644 index 1ece0146c5..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/OpenSessionInViewFilter.java +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Copyright 2002-2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3.support; - -import java.io.IOException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.hibernate.FlushMode; -import org.hibernate.Session; -import org.hibernate.SessionFactory; - -import org.springframework.dao.DataAccessResourceFailureException; -import org.springframework.transaction.support.TransactionSynchronizationManager; -import org.springframework.util.Assert; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.context.request.async.WebAsyncManager; -import org.springframework.web.context.request.async.WebAsyncUtils; -import org.springframework.web.context.support.WebApplicationContextUtils; -import org.springframework.web.filter.OncePerRequestFilter; - -/** - * Servlet Filter that binds a Hibernate Session to the thread for the entire - * processing of the request. Intended for the "Open Session in View" pattern, - * i.e. to allow for lazy loading in web views despite the original transactions - * already being completed. - * - *

This filter makes Hibernate Sessions available via the current thread, which - * will be autodetected by transaction managers. It is suitable for service layer - * transactions via {@link org.springframework.orm.hibernate3.HibernateTransactionManager} - * or {@link org.springframework.transaction.jta.JtaTransactionManager} as well - * as for non-transactional execution (if configured appropriately). - * - *

NOTE: This filter will by default not flush the Hibernate Session, - * with the flush mode set to {@code FlushMode.NEVER}. It assumes to be used - * in combination with service layer transactions that care for the flushing: The - * active transaction manager will temporarily change the flush mode to - * {@code FlushMode.AUTO} during a read-write transaction, with the flush - * mode reset to {@code FlushMode.NEVER} at the end of each transaction. - * If you intend to use this filter without transactions, consider changing - * the default flush mode (through the "flushMode" property). - * - *

WARNING: Applying this filter to existing logic can cause issues that - * have not appeared before, through the use of a single Hibernate Session for the - * processing of an entire request. In particular, the reassociation of persistent - * objects with a Hibernate Session has to occur at the very beginning of request - * processing, to avoid clashes with already loaded instances of the same objects. - * - *

Alternatively, turn this filter into deferred close mode, by specifying - * "singleSession"="false": It will not use a single session per request then, - * but rather let each data access operation or transaction use its own session - * (like without Open Session in View). Each of those sessions will be registered - * for deferred close, though, actually processed at request completion. - * - *

A single session per request allows for most efficient first-level caching, - * but can cause side effects, for example on {@code saveOrUpdate} or when - * continuing after a rolled-back transaction. The deferred close strategy is as safe - * as no Open Session in View in that respect, while still allowing for lazy loading - * in views (but not providing a first-level cache for the entire request). - * - *

Looks up the SessionFactory in Spring's root web application context. - * Supports a "sessionFactoryBeanName" filter init-param in {@code web.xml}; - * the default bean name is "sessionFactory". - * - * @author Juergen Hoeller - * @since 1.2 - * @see #setSingleSession - * @see #setFlushMode - * @see #lookupSessionFactory - * @see OpenSessionInViewInterceptor - * @see OpenSessionInterceptor - * @see org.springframework.orm.hibernate3.HibernateTransactionManager - * @see org.springframework.orm.hibernate3.SessionFactoryUtils#getSession - * @see org.springframework.transaction.support.TransactionSynchronizationManager - * @see org.hibernate.SessionFactory#getCurrentSession() - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public class OpenSessionInViewFilter extends OncePerRequestFilter { - - public static final String DEFAULT_SESSION_FACTORY_BEAN_NAME = "sessionFactory"; - - - private String sessionFactoryBeanName = DEFAULT_SESSION_FACTORY_BEAN_NAME; - - private boolean singleSession = true; - - private FlushMode flushMode = FlushMode.MANUAL; - - - /** - * Set the bean name of the SessionFactory to fetch from Spring's - * root application context. Default is "sessionFactory". - * @see #DEFAULT_SESSION_FACTORY_BEAN_NAME - */ - public void setSessionFactoryBeanName(String sessionFactoryBeanName) { - this.sessionFactoryBeanName = sessionFactoryBeanName; - } - - /** - * Return the bean name of the SessionFactory to fetch from Spring's - * root application context. - */ - protected String getSessionFactoryBeanName() { - return this.sessionFactoryBeanName; - } - - /** - * Set whether to use a single session for each request. Default is "true". - *

If set to "false", each data access operation or transaction will use - * its own session (like without Open Session in View). Each of those - * sessions will be registered for deferred close, though, actually - * processed at request completion. - * @see org.springframework.orm.hibernate3.SessionFactoryUtils#initDeferredClose - * @see org.springframework.orm.hibernate3.SessionFactoryUtils#processDeferredClose - */ - public void setSingleSession(boolean singleSession) { - this.singleSession = singleSession; - } - - /** - * Return whether to use a single session for each request. - */ - protected boolean isSingleSession() { - return this.singleSession; - } - - /** - * Specify the Hibernate FlushMode to apply to this filter's - * {@link org.hibernate.Session}. Only applied in single session mode. - *

Can be populated with the corresponding constant name in XML bean - * definitions: e.g. "AUTO". - *

The default is "MANUAL". Specify "AUTO" if you intend to use - * this filter without service layer transactions. - * @see org.hibernate.Session#setFlushMode - * @see org.hibernate.FlushMode#MANUAL - * @see org.hibernate.FlushMode#AUTO - */ - public void setFlushMode(FlushMode flushMode) { - this.flushMode = flushMode; - } - - /** - * Return the Hibernate FlushMode that this filter applies to its - * {@link org.hibernate.Session} (in single session mode). - */ - protected FlushMode getFlushMode() { - return this.flushMode; - } - - - /** - * Returns "false" so that the filter may re-bind the opened Hibernate - * {@code Session} to each asynchronously dispatched thread and postpone - * closing it until the very last asynchronous dispatch. - */ - @Override - protected boolean shouldNotFilterAsyncDispatch() { - return false; - } - - /** - * Returns "false" so that the filter may provide a Hibernate - * {@code Session} to each error dispatches. - */ - @Override - protected boolean shouldNotFilterErrorDispatch() { - return false; - } - - @Override - protected void doFilterInternal( - HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) - throws ServletException, IOException { - - SessionFactory sessionFactory = lookupSessionFactory(request); - boolean participate = false; - - WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); - String key = getAlreadyFilteredAttributeName(); - - if (isSingleSession()) { - // single session mode - if (TransactionSynchronizationManager.hasResource(sessionFactory)) { - // Do not modify the Session: just set the participate flag. - participate = true; - } - else { - boolean isFirstRequest = !isAsyncDispatch(request); - if (isFirstRequest || !applySessionBindingInterceptor(asyncManager, key)) { - logger.debug("Opening single Hibernate Session in OpenSessionInViewFilter"); - Session session = getSession(sessionFactory); - org.springframework.orm.hibernate3.SessionHolder sessionHolder = new org.springframework.orm.hibernate3.SessionHolder(session); - TransactionSynchronizationManager.bindResource(sessionFactory, sessionHolder); - - AsyncRequestInterceptor interceptor = new AsyncRequestInterceptor(sessionFactory, sessionHolder); - asyncManager.registerCallableInterceptor(key, interceptor); - asyncManager.registerDeferredResultInterceptor(key, interceptor); - } - } - } - else { - // deferred close mode - Assert.state(!isAsyncStarted(request), "Deferred close mode is not supported on async dispatches"); - if (org.springframework.orm.hibernate3.SessionFactoryUtils.isDeferredCloseActive(sessionFactory)) { - // Do not modify deferred close: just set the participate flag. - participate = true; - } - else { - org.springframework.orm.hibernate3.SessionFactoryUtils.initDeferredClose(sessionFactory); - } - } - - try { - filterChain.doFilter(request, response); - } - finally { - if (!participate) { - if (isSingleSession()) { - // single session mode - org.springframework.orm.hibernate3.SessionHolder sessionHolder = - (org.springframework.orm.hibernate3.SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory); - if (!isAsyncStarted(request)) { - logger.debug("Closing single Hibernate Session in OpenSessionInViewFilter"); - closeSession(sessionHolder.getSession(), sessionFactory); - } - } - else { - // deferred close mode - org.springframework.orm.hibernate3.SessionFactoryUtils.processDeferredClose(sessionFactory); - } - } - } - } - - /** - * Look up the SessionFactory that this filter should use, - * taking the current HTTP request as argument. - *

The default implementation delegates to the {@link #lookupSessionFactory()} - * variant without arguments. - * @param request the current request - * @return the SessionFactory to use - */ - protected SessionFactory lookupSessionFactory(HttpServletRequest request) { - return lookupSessionFactory(); - } - - /** - * Look up the SessionFactory that this filter should use. - *

The default implementation looks for a bean with the specified name - * in Spring's root application context. - * @return the SessionFactory to use - * @see #getSessionFactoryBeanName - */ - protected SessionFactory lookupSessionFactory() { - if (logger.isDebugEnabled()) { - logger.debug("Using SessionFactory '" + getSessionFactoryBeanName() + "' for OpenSessionInViewFilter"); - } - WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()); - return wac.getBean(getSessionFactoryBeanName(), SessionFactory.class); - } - - /** - * Get a Session for the SessionFactory that this filter uses. - * Note that this just applies in single session mode! - *

The default implementation delegates to the - * {@code SessionFactoryUtils.getSession} method and - * sets the {@code Session}'s flush mode to "MANUAL". - *

Can be overridden in subclasses for creating a Session with a - * custom entity interceptor or JDBC exception translator. - * @param sessionFactory the SessionFactory that this filter uses - * @return the Session to use - * @throws DataAccessResourceFailureException if the Session could not be created - * @see org.springframework.orm.hibernate3.SessionFactoryUtils#getSession(SessionFactory, boolean) - * @see org.hibernate.FlushMode#MANUAL - */ - protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException { - Session session = org.springframework.orm.hibernate3.SessionFactoryUtils.getSession(sessionFactory, true); - FlushMode flushMode = getFlushMode(); - if (flushMode != null) { - session.setFlushMode(flushMode); - } - return session; - } - - /** - * Close the given Session. - * Note that this just applies in single session mode! - *

Can be overridden in subclasses, e.g. for flushing the Session before - * closing it. See class-level javadoc for a discussion of flush handling. - * Note that you should also override getSession accordingly, to set - * the flush mode to something else than NEVER. - * @param session the Session used for filtering - * @param sessionFactory the SessionFactory that this filter uses - */ - protected void closeSession(Session session, SessionFactory sessionFactory) { - org.springframework.orm.hibernate3.SessionFactoryUtils.closeSession(session); - } - - private boolean applySessionBindingInterceptor(WebAsyncManager asyncManager, String key) { - if (asyncManager.getCallableInterceptor(key) == null) { - return false; - } - ((AsyncRequestInterceptor) asyncManager.getCallableInterceptor(key)).bindSession(); - return true; - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/OpenSessionInViewInterceptor.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/OpenSessionInViewInterceptor.java deleted file mode 100644 index 10598cd874..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/OpenSessionInViewInterceptor.java +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3.support; - -import org.hibernate.HibernateException; -import org.hibernate.Session; - -import org.springframework.dao.DataAccessException; -import org.springframework.transaction.support.TransactionSynchronizationManager; -import org.springframework.ui.ModelMap; -import org.springframework.web.context.request.AsyncWebRequestInterceptor; -import org.springframework.web.context.request.WebRequest; -import org.springframework.web.context.request.async.WebAsyncManager; -import org.springframework.web.context.request.async.WebAsyncUtils; - -/** - * Spring web request interceptor that binds a Hibernate {@code Session} to the - * thread for the entire processing of the request. - * - *

This class is a concrete expression of the "Open Session in View" pattern, which - * is a pattern that allows for the lazy loading of associations in web views despite - * the original transactions already being completed. - * - *

This interceptor makes Hibernate {@code Sessions} available via the current - * thread, which will be autodetected by transaction managers. It is suitable for - * service layer transactions via - * {@link org.springframework.orm.hibernate3.HibernateTransactionManager} or - * {@link org.springframework.transaction.jta.JtaTransactionManager} as well as for - * non-transactional execution (if configured appropriately). - * - *

NOTE: This interceptor will by default not flush the Hibernate - * {@code Session}, with the flush mode being set to {@code FlushMode.NEVER}. - * It assumes that it will be used in combination with service layer transactions - * that handle the flushing: the active transaction manager will temporarily change - * the flush mode to {@code FlushMode.AUTO} during a read-write transaction, - * with the flush mode reset to {@code FlushMode.NEVER} at the end of each - * transaction. If you intend to use this interceptor without transactions, consider - * changing the default flush mode (through the - * {@link #setFlushMode(int) "flushMode"} property). - * - *

In contrast to {@link OpenSessionInViewFilter}, this interceptor is - * configured in a Spring application context and can thus take advantage of bean - * wiring. It inherits common Hibernate configuration properties from - * {@link org.springframework.orm.hibernate3.HibernateAccessor}, - * to be configured in a bean definition. - * - *

WARNING: Applying this interceptor to existing logic can cause issues - * that have not appeared before, through the use of a single Hibernate - * {@code Session} for the processing of an entire request. In particular, the - * reassociation of persistent objects with a Hibernate {@code Session} has to - * occur at the very beginning of request processing, to avoid clashes with already - * loaded instances of the same objects. - * - *

Alternatively, turn this interceptor into deferred close mode, by specifying - * "singleSession"="false": It will not use a single session per request then, - * but rather let each data access operation or transaction use its own session - * (as would be the case without Open Session in View). Each of those sessions will - * be registered for deferred close though, which will actually be processed at - * request completion. - * - *

A single session per request allows for the most efficient first-level caching, - * but can cause side effects, for example on {@code saveOrUpdate} or when - * continuing after a rolled-back transaction. The deferred close strategy is as safe - * as no Open Session in View in that respect, while still allowing for lazy loading - * in views (but not providing a first-level cache for the entire request). - * - * @author Juergen Hoeller - * @since 1.2 - * @see #setSingleSession - * @see #setFlushMode - * @see OpenSessionInViewFilter - * @see OpenSessionInterceptor - * @see org.springframework.orm.hibernate3.HibernateTransactionManager - * @see org.springframework.orm.hibernate3.SessionFactoryUtils#getSession - * @see org.springframework.transaction.support.TransactionSynchronizationManager - * @see org.hibernate.SessionFactory#getCurrentSession() - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public class OpenSessionInViewInterceptor extends org.springframework.orm.hibernate3.HibernateAccessor implements AsyncWebRequestInterceptor { - - /** - * Suffix that gets appended to the {@code SessionFactory} - * {@code toString()} representation for the "participate in existing - * session handling" request attribute. - * @see #getParticipateAttributeName - */ - public static final String PARTICIPATE_SUFFIX = ".PARTICIPATE"; - - - private boolean singleSession = true; - - - /** - * Create a new {@code OpenSessionInViewInterceptor}, - * turning the default flushMode to {@code FLUSH_NEVER}. - * @see #setFlushMode - */ - public OpenSessionInViewInterceptor() { - setFlushMode(FLUSH_NEVER); - } - - /** - * Set whether to use a single session for each request. Default is "true". - *

If set to false, each data access operation or transaction will use - * its own session (like without Open Session in View). Each of those - * sessions will be registered for deferred close, though, actually - * processed at request completion. - * @see org.springframework.orm.hibernate3.SessionFactoryUtils#initDeferredClose - * @see org.springframework.orm.hibernate3.SessionFactoryUtils#processDeferredClose - */ - public void setSingleSession(boolean singleSession) { - this.singleSession = singleSession; - } - - /** - * Return whether to use a single session for each request. - */ - protected boolean isSingleSession() { - return singleSession; - } - - - /** - * Open a new Hibernate {@code Session} according to the settings of this - * {@code HibernateAccessor} and bind it to the thread via the - * {@link TransactionSynchronizationManager}. - * @see org.springframework.orm.hibernate3.SessionFactoryUtils#getSession - */ - @Override - public void preHandle(WebRequest request) throws DataAccessException { - String participateAttributeName = getParticipateAttributeName(); - - WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); - if (asyncManager.hasConcurrentResult()) { - if (applySessionBindingInterceptor(asyncManager, participateAttributeName)) { - return; - } - } - - if ((isSingleSession() && TransactionSynchronizationManager.hasResource(getSessionFactory())) || - org.springframework.orm.hibernate3.SessionFactoryUtils.isDeferredCloseActive(getSessionFactory())) { - // Do not modify the Session: just mark the request accordingly. - Integer count = (Integer) request.getAttribute(participateAttributeName, WebRequest.SCOPE_REQUEST); - int newCount = (count != null ? count + 1 : 1); - request.setAttribute(getParticipateAttributeName(), newCount, WebRequest.SCOPE_REQUEST); - } - else { - if (isSingleSession()) { - // single session mode - logger.debug("Opening single Hibernate Session in OpenSessionInViewInterceptor"); - Session session = org.springframework.orm.hibernate3.SessionFactoryUtils.getSession( - getSessionFactory(), getEntityInterceptor(), getJdbcExceptionTranslator()); - applyFlushMode(session, false); - org.springframework.orm.hibernate3.SessionHolder sessionHolder = new org.springframework.orm.hibernate3.SessionHolder(session); - TransactionSynchronizationManager.bindResource(getSessionFactory(), sessionHolder); - - AsyncRequestInterceptor asyncRequestInterceptor = - new AsyncRequestInterceptor(getSessionFactory(), sessionHolder); - asyncManager.registerCallableInterceptor(participateAttributeName, asyncRequestInterceptor); - asyncManager.registerDeferredResultInterceptor(participateAttributeName, asyncRequestInterceptor); - } - else { - // deferred close mode - org.springframework.orm.hibernate3.SessionFactoryUtils.initDeferredClose(getSessionFactory()); - } - } - } - - /** - * Flush the Hibernate {@code Session} before view rendering, if necessary. - *

Note that this just applies in {@link #isSingleSession() single session mode}! - *

The default is {@code FLUSH_NEVER} to avoid this extra flushing, - * assuming that service layer transactions have flushed their changes on commit. - * @see #setFlushMode - */ - @Override - public void postHandle(WebRequest request, ModelMap model) throws DataAccessException { - if (isSingleSession()) { - // Only potentially flush in single session mode. - org.springframework.orm.hibernate3.SessionHolder sessionHolder = - (org.springframework.orm.hibernate3.SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory()); - logger.debug("Flushing single Hibernate Session in OpenSessionInViewInterceptor"); - try { - flushIfNecessary(sessionHolder.getSession(), false); - } - catch (HibernateException ex) { - throw convertHibernateAccessException(ex); - } - } - } - - /** - * Unbind the Hibernate {@code Session} from the thread and close it (in - * single session mode), or process deferred close for all sessions that have - * been opened during the current request (in deferred close mode). - * @see org.springframework.transaction.support.TransactionSynchronizationManager - */ - @Override - public void afterCompletion(WebRequest request, Exception ex) throws DataAccessException { - if (!decrementParticipateCount(request)) { - if (isSingleSession()) { - // single session mode - org.springframework.orm.hibernate3.SessionHolder sessionHolder = - (org.springframework.orm.hibernate3.SessionHolder) TransactionSynchronizationManager.unbindResource(getSessionFactory()); - logger.debug("Closing single Hibernate Session in OpenSessionInViewInterceptor"); - org.springframework.orm.hibernate3.SessionFactoryUtils.closeSession(sessionHolder.getSession()); - } - else { - // deferred close mode - org.springframework.orm.hibernate3.SessionFactoryUtils.processDeferredClose(getSessionFactory()); - } - } - } - - @Override - public void afterConcurrentHandlingStarted(WebRequest request) { - if (!decrementParticipateCount(request)) { - if (isSingleSession()) { - TransactionSynchronizationManager.unbindResource(getSessionFactory()); - } - else { - throw new IllegalStateException("Deferred close mode is not supported with async requests."); - } - - } - } - - private boolean decrementParticipateCount(WebRequest request) { - String participateAttributeName = getParticipateAttributeName(); - Integer count = (Integer) request.getAttribute(participateAttributeName, WebRequest.SCOPE_REQUEST); - if (count == null) { - return false; - } - // Do not modify the Session: just clear the marker. - if (count > 1) { - request.setAttribute(participateAttributeName, count - 1, WebRequest.SCOPE_REQUEST); - } - else { - request.removeAttribute(participateAttributeName, WebRequest.SCOPE_REQUEST); - } - return true; - } - - /** - * Return the name of the request attribute that identifies that a request is - * already intercepted. - *

The default implementation takes the {@code toString()} representation - * of the {@code SessionFactory} instance and appends {@link #PARTICIPATE_SUFFIX}. - */ - protected String getParticipateAttributeName() { - return getSessionFactory().toString() + PARTICIPATE_SUFFIX; - } - - private boolean applySessionBindingInterceptor(WebAsyncManager asyncManager, String key) { - if (asyncManager.getCallableInterceptor(key) == null) { - return false; - } - ((AsyncRequestInterceptor) asyncManager.getCallableInterceptor(key)).bindSession(); - return true; - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/OpenSessionInterceptor.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/OpenSessionInterceptor.java deleted file mode 100644 index 1a61ffd547..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/OpenSessionInterceptor.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3.support; - -import org.aopalliance.intercept.MethodInterceptor; -import org.aopalliance.intercept.MethodInvocation; -import org.hibernate.FlushMode; -import org.hibernate.HibernateException; -import org.hibernate.Session; -import org.hibernate.SessionFactory; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.dao.DataAccessResourceFailureException; -import org.springframework.transaction.support.TransactionSynchronizationManager; - -/** - * Simple AOP Alliance {@link MethodInterceptor} implementation that binds a new - * Hibernate {@link Session} for each method invocation, if none bound before. - * - *

This is a simple Hibernate Session scoping interceptor along the lines of - * {@link OpenSessionInViewInterceptor}, just for use with AOP setup instead of - * MVC setup. It opens a new {@link Session} with flush mode "MANUAL" since the - * Session is only meant for reading, except when participating in a transaction. - * - *

Note: This can serve as a streamlined alternative to the outdated - * {@link org.springframework.orm.hibernate3.HibernateInterceptor}, providing - * plain Session binding without any automatic exception translation or the like. - * - * @author Juergen Hoeller - * @since 4.0.2 - * @see OpenSessionInViewInterceptor - * @see OpenSessionInViewFilter - * @see org.springframework.orm.hibernate3.HibernateTransactionManager - * @see org.springframework.transaction.support.TransactionSynchronizationManager - * @see org.hibernate.SessionFactory#getCurrentSession() - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public class OpenSessionInterceptor implements MethodInterceptor, InitializingBean { - - private SessionFactory sessionFactory; - - - /** - * Set the Hibernate SessionFactory that should be used to create Hibernate Sessions. - */ - public void setSessionFactory(SessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; - } - - /** - * Return the Hibernate SessionFactory that should be used to create Hibernate Sessions. - */ - public SessionFactory getSessionFactory() { - return this.sessionFactory; - } - - @Override - public void afterPropertiesSet() { - if (getSessionFactory() == null) { - throw new IllegalArgumentException("Property 'sessionFactory' is required"); - } - } - - - @Override - public Object invoke(MethodInvocation invocation) throws Throwable { - SessionFactory sf = getSessionFactory(); - if (!TransactionSynchronizationManager.hasResource(sf)) { - // New Session to be bound for the current method's scope... - Session session = openSession(); - try { - TransactionSynchronizationManager.bindResource(sf, new org.springframework.orm.hibernate3.SessionHolder(session)); - return invocation.proceed(); - } - finally { - org.springframework.orm.hibernate3.SessionFactoryUtils.closeSession(session); - TransactionSynchronizationManager.unbindResource(sf); - } - } - else { - // Pre-bound Session found -> simply proceed. - return invocation.proceed(); - } - } - - /** - * Open a Session for the SessionFactory that this interceptor uses. - *

The default implementation delegates to the {@link SessionFactory#openSession} - * method and sets the {@link Session}'s flush mode to "MANUAL". - * @return the Session to use - * @throws DataAccessResourceFailureException if the Session could not be created - * @see org.hibernate.FlushMode#MANUAL - */ - protected Session openSession() throws DataAccessResourceFailureException { - try { - Session session = getSessionFactory().openSession(); - session.setFlushMode(FlushMode.MANUAL); - return session; - } - catch (HibernateException ex) { - throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex); - } - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/ScopedBeanInterceptor.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/ScopedBeanInterceptor.java deleted file mode 100644 index 6dec1f9348..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/ScopedBeanInterceptor.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3.support; - -import org.hibernate.EmptyInterceptor; - -import org.springframework.aop.scope.ScopedObject; -import org.springframework.aop.support.AopUtils; - -/** - * Hibernate3 interceptor used for getting the proper entity name for scoped - * beans. As scoped bean classes are proxies generated at runtime, they are - * unrecognized by the persisting framework. Using this interceptor, the - * original scoped bean class is retrieved end exposed to Hibernate for - * persisting. - * - *

Usage example: - * - *

- * <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
- *   ...
- *   <property name="entityInterceptor">
- *     <bean class="org.springframework.orm.hibernate3.support.ScopedBeanInterceptor"/>
- *   </property>
- * </bean>
- * - * @author Costin Leau - * @author Juergen Hoeller - * @since 2.0 - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -@SuppressWarnings("serial") -public class ScopedBeanInterceptor extends EmptyInterceptor { - - @Override - public String getEntityName(Object entity) { - if (entity instanceof ScopedObject) { - // Determine underlying object's type. - Object targetObject = ((ScopedObject) entity).getTargetObject(); - return AopUtils.getTargetClass(targetObject).getName(); - } - - // Any other object: delegate to the default implementation. - return super.getEntityName(entity); - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/package-info.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/package-info.java deleted file mode 100644 index 58ade25435..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -/** - * Classes supporting the {@code org.springframework.orm.hibernate3} package. - * Contains a DAO base class for HibernateTemplate usage. - */ -package org.springframework.orm.hibernate3.support; diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/ConfigurableJtaPlatform.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/ConfigurableJtaPlatform.java similarity index 100% rename from spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/ConfigurableJtaPlatform.java rename to spring-orm/src/main/java/org/springframework/orm/hibernate5/ConfigurableJtaPlatform.java diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateCallback.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateCallback.java similarity index 100% rename from spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateCallback.java rename to spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateCallback.java diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateExceptionTranslator.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateExceptionTranslator.java similarity index 100% rename from spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateExceptionTranslator.java rename to spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateExceptionTranslator.java diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateJdbcException.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateJdbcException.java similarity index 100% rename from spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateJdbcException.java rename to spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateJdbcException.java diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateObjectRetrievalFailureException.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateObjectRetrievalFailureException.java similarity index 100% rename from spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateObjectRetrievalFailureException.java rename to spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateObjectRetrievalFailureException.java diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateOperations.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateOperations.java similarity index 100% rename from spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateOperations.java rename to spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateOperations.java diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateOptimisticLockingFailureException.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateOptimisticLockingFailureException.java similarity index 100% rename from spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateOptimisticLockingFailureException.java rename to spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateOptimisticLockingFailureException.java diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateQueryException.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateQueryException.java similarity index 100% rename from spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateQueryException.java rename to spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateQueryException.java diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateSystemException.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateSystemException.java similarity index 100% rename from spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateSystemException.java rename to spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateSystemException.java diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateTemplate.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTemplate.java similarity index 100% rename from spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateTemplate.java rename to spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTemplate.java diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateTransactionManager.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTransactionManager.java similarity index 100% rename from spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateTransactionManager.java rename to spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTransactionManager.java diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBean.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBean.java similarity index 100% rename from spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBean.java rename to spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBean.java diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java similarity index 100% rename from spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java rename to spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SessionFactoryUtils.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/SessionFactoryUtils.java similarity index 100% rename from spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SessionFactoryUtils.java rename to spring-orm/src/main/java/org/springframework/orm/hibernate5/SessionFactoryUtils.java diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SessionHolder.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/SessionHolder.java similarity index 100% rename from spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SessionHolder.java rename to spring-orm/src/main/java/org/springframework/orm/hibernate5/SessionHolder.java diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringFlushSynchronization.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringFlushSynchronization.java similarity index 100% rename from spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringFlushSynchronization.java rename to spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringFlushSynchronization.java diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringJtaSessionContext.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringJtaSessionContext.java similarity index 100% rename from spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringJtaSessionContext.java rename to spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringJtaSessionContext.java diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringSessionContext.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringSessionContext.java similarity index 100% rename from spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringSessionContext.java rename to spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringSessionContext.java diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringSessionSynchronization.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringSessionSynchronization.java similarity index 100% rename from spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringSessionSynchronization.java rename to spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringSessionSynchronization.java diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/package-info.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/package-info.java similarity index 69% rename from spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/package-info.java rename to spring-orm/src/main/java/org/springframework/orm/hibernate5/package-info.java index 1211ac0098..12f5d47003 100644 --- a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/package-info.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/package-info.java @@ -9,8 +9,5 @@ * using Hibernate's native sessionFactory.getCurrentSession() style. * *

This package supports Hibernate 5.x only. - * See the {@code org.springframework.orm.hibernate4} package for Hibernate 4.x support. - * Note: Do not use HibernateTemplate or other classes from the hibernate4 package - * with Hibernate 5; this will lead to class definition exceptions at runtime. */ package org.springframework.orm.hibernate5; diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/support/AsyncRequestInterceptor.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/AsyncRequestInterceptor.java similarity index 100% rename from spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/support/AsyncRequestInterceptor.java rename to spring-orm/src/main/java/org/springframework/orm/hibernate5/support/AsyncRequestInterceptor.java diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/support/HibernateDaoSupport.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/HibernateDaoSupport.java similarity index 100% rename from spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/support/HibernateDaoSupport.java rename to spring-orm/src/main/java/org/springframework/orm/hibernate5/support/HibernateDaoSupport.java diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewFilter.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewFilter.java similarity index 100% rename from spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewFilter.java rename to spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewFilter.java diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewInterceptor.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewInterceptor.java similarity index 100% rename from spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewInterceptor.java rename to spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewInterceptor.java diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInterceptor.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInterceptor.java similarity index 100% rename from spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInterceptor.java rename to spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInterceptor.java diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/support/package-info.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/package-info.java similarity index 100% rename from spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/support/package-info.java rename to spring-orm/src/main/java/org/springframework/orm/hibernate5/support/package-info.java diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryUtils.java b/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryUtils.java index c2f3a5884a..57ada0f58d 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryUtils.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,7 @@ import javax.persistence.PersistenceException; import javax.persistence.PessimisticLockException; import javax.persistence.Query; import javax.persistence.QueryTimeoutException; +import javax.persistence.SynchronizationType; import javax.persistence.TransactionRequiredException; import org.apache.commons.logging.Log; @@ -81,26 +82,6 @@ public abstract class EntityManagerFactoryUtils { private static final Log logger = LogFactory.getLog(EntityManagerFactoryUtils.class); - private static Method createEntityManagerWithSynchronizationTypeMethod; - - private static Object synchronizationTypeUnsynchronized; - - static { - try { - @SuppressWarnings( "rawtypes" ) - Class synchronizationTypeClass = (Class) ClassUtils.forName( - "javax.persistence.SynchronizationType", EntityManagerFactoryUtils.class.getClassLoader()); - createEntityManagerWithSynchronizationTypeMethod = EntityManagerFactory.class.getMethod( - "createEntityManager", synchronizationTypeClass, Map.class); - synchronizationTypeUnsynchronized = Enum.valueOf(synchronizationTypeClass, "UNSYNCHRONIZED"); - } - catch (Exception ex) { - // No JPA 2.1 API available - createEntityManagerWithSynchronizationTypeMethod = null; - } - } - - /** * Find an EntityManagerFactory with the given name in the given * Spring application context (represented as ListableBeanFactory). @@ -271,10 +252,9 @@ public abstract class EntityManagerFactoryUtils { // Create a new EntityManager for use within the current transaction. logger.debug("Opening JPA EntityManager"); EntityManager em = null; - if (!synchronizedWithTransaction && createEntityManagerWithSynchronizationTypeMethod != null) { + if (!synchronizedWithTransaction) { try { - em = (EntityManager) ReflectionUtils.invokeMethod(createEntityManagerWithSynchronizationTypeMethod, - emf, synchronizationTypeUnsynchronized, properties); + em = emf.createEntityManager(SynchronizationType.UNSYNCHRONIZED, properties); } catch (AbstractMethodError err) { // JPA 2.1 API available but method not actually implemented in persistence provider: diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java b/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java index a3bac0ce61..46f6ae689d 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java @@ -115,11 +115,11 @@ public abstract class SharedEntityManagerCreator { */ public static EntityManager createSharedEntityManager( EntityManagerFactory emf, Map properties, boolean synchronizedWithTransaction) { - Class entityManagerInterface = (emf instanceof EntityManagerFactoryInfo ? + + Class emIfc = (emf instanceof EntityManagerFactoryInfo ? ((EntityManagerFactoryInfo) emf).getEntityManagerInterface() : EntityManager.class); return createSharedEntityManager(emf, properties, synchronizedWithTransaction, - (entityManagerInterface == null ? NO_ENTITY_MANAGER_INTERFACES : - new Class[] { entityManagerInterface })); + (emIfc == null ? NO_ENTITY_MANAGER_INTERFACES : new Class[] {emIfc})); } /** diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java index bae326c44f..af74040358 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java @@ -17,7 +17,6 @@ package org.springframework.orm.jpa.persistenceunit; import java.io.IOException; -import java.lang.annotation.Annotation; import java.net.URL; import java.util.HashMap; import java.util.HashSet; @@ -26,6 +25,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; +import javax.persistence.Converter; import javax.persistence.Embeddable; import javax.persistence.Entity; import javax.persistence.MappedSuperclass; @@ -73,8 +73,7 @@ import org.springframework.util.ResourceUtils; * DataSource names are by default interpreted as JNDI names, and no load time weaving * is available (which requires weaving to be turned off in the persistence provider). * - *

NOTE: Spring's JPA support requires JPA 2.0 or higher, as of Spring 4.0. - * Spring's persistence unit bootstrapping automatically detects JPA 2.1 at runtime. + *

NOTE: Spring's JPA support requires JPA 2.1 or higher, as of Spring 5.0. * * @author Juergen Hoeller * @since 2.0 @@ -116,15 +115,7 @@ public class DefaultPersistenceUnitManager entityTypeFilters.add(new AnnotationTypeFilter(Entity.class, false)); entityTypeFilters.add(new AnnotationTypeFilter(Embeddable.class, false)); entityTypeFilters.add(new AnnotationTypeFilter(MappedSuperclass.class, false)); - try { - @SuppressWarnings("unchecked") - Class converterAnnotation = (Class) - ClassUtils.forName("javax.persistence.Converter", DefaultPersistenceUnitManager.class.getClassLoader()); - entityTypeFilters.add(new AnnotationTypeFilter(converterAnnotation, false)); - } - catch (ClassNotFoundException ex) { - // JPA 2.1 API not available - } + entityTypeFilters.add(new AnnotationTypeFilter(Converter.class, false)); } diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java b/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java index e65d70f0d6..f8236240ea 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,7 @@ import javax.persistence.PersistenceContext; import javax.persistence.PersistenceContextType; import javax.persistence.PersistenceProperty; import javax.persistence.PersistenceUnit; +import javax.persistence.SynchronizationType; import org.springframework.beans.BeanUtils; import org.springframework.beans.BeansException; @@ -168,11 +169,6 @@ public class PersistenceAnnotationBeanPostProcessor implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware, Serializable { - /* Check JPA 2.1 PersistenceContext.synchronization() attribute */ - private static final Method synchronizationAttribute = - ClassUtils.getMethodIfAvailable(PersistenceContext.class, "synchronization"); - - private Object jndiEnvironment; private boolean resourceRef = true; @@ -662,8 +658,7 @@ public class PersistenceAnnotationBeanPostProcessor } this.unitName = pc.unitName(); this.type = pc.type(); - this.synchronizedWithTransaction = (synchronizationAttribute == null || - "SYNCHRONIZED".equals(ReflectionUtils.invokeMethod(synchronizationAttribute, pc).toString())); + this.synchronizedWithTransaction = SynchronizationType.SYNCHRONIZED.equals(pc.synchronization()); this.properties = properties; } else { diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java index c089b42561..df4608637d 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java @@ -28,7 +28,6 @@ import org.hibernate.HibernateException; import org.hibernate.NonUniqueObjectException; import org.hibernate.NonUniqueResultException; import org.hibernate.ObjectDeletedException; -import org.hibernate.OptimisticLockException; import org.hibernate.PersistentObjectException; import org.hibernate.PessimisticLockException; import org.hibernate.PropertyValueException; @@ -40,6 +39,8 @@ import org.hibernate.StaleStateException; import org.hibernate.TransientObjectException; import org.hibernate.UnresolvableObjectException; import org.hibernate.WrongClassException; +import org.hibernate.dialect.lock.OptimisticEntityLockException; +import org.hibernate.dialect.lock.PessimisticEntityLockException; import org.hibernate.exception.ConstraintViolationException; import org.hibernate.exception.DataException; import org.hibernate.exception.JDBCConnectionException; @@ -57,7 +58,6 @@ import org.springframework.dao.InvalidDataAccessResourceUsageException; import org.springframework.dao.PessimisticLockingFailureException; import org.springframework.jdbc.datasource.ConnectionHandle; import org.springframework.jdbc.datasource.DataSourceUtils; -import org.springframework.jdbc.support.JdbcUtils; import org.springframework.orm.ObjectOptimisticLockingFailureException; import org.springframework.orm.ObjectRetrievalFailureException; import org.springframework.orm.jpa.DefaultJpaDialect; @@ -67,13 +67,11 @@ import org.springframework.transaction.InvalidIsolationLevelException; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionException; import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; import org.springframework.util.ReflectionUtils; /** * {@link org.springframework.orm.jpa.JpaDialect} implementation for - * Hibernate EntityManager. Developed and tested against Hibernate 3.6, - * 4.2/4.3 as well as 5.0/5.1/5.2. + * Hibernate EntityManager. Developed against Hibernate 5.0/5.1/5.2. * * @author Juergen Hoeller * @author Costin Leau @@ -85,29 +83,9 @@ import org.springframework.util.ReflectionUtils; @SuppressWarnings("serial") public class HibernateJpaDialect extends DefaultJpaDialect { - private static Class optimisticLockExceptionClass; - - private static Class pessimisticLockExceptionClass; - private static Method getFlushMode; static { - // Checking for Hibernate 4.x's Optimistic/PessimisticEntityLockException - ClassLoader cl = HibernateJpaDialect.class.getClassLoader(); - try { - optimisticLockExceptionClass = cl.loadClass("org.hibernate.dialect.lock.OptimisticEntityLockException"); - } - catch (ClassNotFoundException ex) { - // OptimisticLockException is deprecated on Hibernate 4.x; we're just using it on 3.x anyway - optimisticLockExceptionClass = OptimisticLockException.class; - } - try { - pessimisticLockExceptionClass = cl.loadClass("org.hibernate.dialect.lock.PessimisticEntityLockException"); - } - catch (ClassNotFoundException ex) { - pessimisticLockExceptionClass = null; - } - try { // Hibernate 5.2+ getHibernateFlushMode() getFlushMode = Session.class.getMethod("getHibernateFlushMode"); @@ -126,7 +104,7 @@ public class HibernateJpaDialect extends DefaultJpaDialect { } - boolean prepareConnection = (HibernateConnectionHandle.sessionConnectionMethod == null); + boolean prepareConnection = true; /** @@ -135,9 +113,7 @@ public class HibernateJpaDialect extends DefaultJpaDialect { * isolation level and/or the transaction's read-only flag to the underlying * JDBC Connection. *

Default is "true" on Hibernate EntityManager 4.x (with its 'on-close' - * connection release mode, and "false" on Hibernate EntityManager 3.6 (due to - * the 'after-transaction' release mode there). Note that Hibernate 4.2+ is - * strongly recommended in order to make isolation levels work efficiently. + * connection release mode. *

If you turn this flag off, JPA transaction management will not support * per-transaction isolation levels anymore. It will not call * {@code Connection.setReadOnly(true)} for read-only transactions anymore either. @@ -179,9 +155,7 @@ public class HibernateJpaDialect extends DefaultJpaDialect { } else if (isolationLevelNeeded) { throw new InvalidIsolationLevelException(getClass().getSimpleName() + - " does not support custom isolation levels since the 'prepareConnection' flag is off. " + - "This is the case on Hibernate 3.6 by default; either switch that flag at your own risk " + - "or upgrade to Hibernate 4.x, with 4.2+ recommended."); + " does not support custom isolation levels since the 'prepareConnection' flag is off."); } } @@ -319,10 +293,10 @@ public class HibernateJpaDialect extends DefaultJpaDialect { if (ex instanceof StaleStateException) { return new ObjectOptimisticLockingFailureException(ex.getMessage(), ex); } - if (optimisticLockExceptionClass.isInstance(ex)) { + if (ex instanceof OptimisticEntityLockException) { return new ObjectOptimisticLockingFailureException(ex.getMessage(), ex); } - if (pessimisticLockExceptionClass != null && pessimisticLockExceptionClass.isInstance(ex)) { + if (ex instanceof PessimisticEntityLockException) { if (ex.getCause() instanceof LockAcquisitionException) { return new CannotAcquireLockException(ex.getMessage(), ex.getCause()); } @@ -376,11 +350,7 @@ public class HibernateJpaDialect extends DefaultJpaDialect { private static class HibernateConnectionHandle implements ConnectionHandle { - // This will find a corresponding method on Hibernate 3.x but not on 4.x - private static final Method sessionConnectionMethod = - ClassUtils.getMethodIfAvailable(Session.class, "connection"); - - private static volatile Method connectionMethodToUse = sessionConnectionMethod; + private static volatile Method connectionMethodToUse; private final Session session; @@ -395,20 +365,12 @@ public class HibernateJpaDialect extends DefaultJpaDialect { @Override public void releaseConnection(Connection con) { - if (sessionConnectionMethod != null) { - // Need to explicitly call close() with Hibernate 3.x in order to allow - // for eager release of the underlying physical Connection if necessary. - // However, do not do this on Hibernate 4.2+ since it would return the - // physical Connection to the pool right away, making it unusable for - // further operations within the current transaction! - JdbcUtils.closeConnection(con); - } } public static Connection doGetConnection(Session session) { try { if (connectionMethodToUse == null) { - // Reflective lookup to find SessionImpl's connection() method on Hibernate 4.x + // Reflective lookup to find SessionImpl's connection() method on Hibernate 4.x/5.x connectionMethodToUse = session.getClass().getMethod("connection"); } return (Connection) ReflectionUtils.invokeMethod(connectionMethodToUse, session); diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaVendorAdapter.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaVendorAdapter.java index 4451a8bf9a..a11a13d878 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaVendorAdapter.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaVendorAdapter.java @@ -32,11 +32,13 @@ import org.hibernate.dialect.MySQLDialect; import org.hibernate.dialect.Oracle9iDialect; import org.hibernate.dialect.PostgreSQLDialect; import org.hibernate.dialect.SQLServerDialect; +import org.hibernate.jpa.HibernateEntityManager; +import org.hibernate.jpa.HibernateEntityManagerFactory; /** * {@link org.springframework.orm.jpa.JpaVendorAdapter} implementation for Hibernate - * EntityManager. Developed and tested against Hibernate 3.6, 4.2/4.3 as well as 5.x. - * Hibernate 4.2+ is strongly recommended for use with Spring 4.0+. + * EntityManager. Developed and tested against Hibernate 5.0, 5.1 and 5.2; + * backwards-compatible with Hibernate 4.3 as well. * *

Exposes Hibernate's persistence provider and EntityManager extension interface, * and adapts {@link AbstractJpaVendorAdapter}'s common configuration settings. @@ -46,18 +48,10 @@ import org.hibernate.dialect.SQLServerDialect; * along with Spring-driven entity scanning which requires no {@code persistence.xml} * ({@link org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean#setPackagesToScan}). * - *

Note that the package location of Hibernate's JPA support changed from 4.2 to 4.3: - * from {@code org.hibernate.ejb.HibernateEntityManager(Factory)} to - * {@code org.hibernate.jpa.HibernateEntityManager(Factory)}. As of Spring 4.0, - * we're exposing the correct, non-deprecated variant depending on the Hibernate - * version encountered at runtime, in order to avoid deprecation log entries. - * * @author Juergen Hoeller * @author Rod Johnson * @since 2.0 * @see HibernateJpaDialect - * @see org.hibernate.ejb.HibernatePersistence - * @see org.hibernate.ejb.HibernateEntityManager */ public class HibernateJpaVendorAdapter extends AbstractJpaVendorAdapter { @@ -73,31 +67,9 @@ public class HibernateJpaVendorAdapter extends AbstractJpaVendorAdapter { @SuppressWarnings("unchecked") public HibernateJpaVendorAdapter() { ClassLoader cl = HibernateJpaVendorAdapter.class.getClassLoader(); - Class emfIfcToUse; - Class emIfcToUse; - Class providerClass; - PersistenceProvider providerToUse; - try { - try { - // Try Hibernate 4.3/5.0's org.hibernate.jpa package in order to avoid deprecation warnings - emfIfcToUse = (Class) cl.loadClass("org.hibernate.jpa.HibernateEntityManagerFactory"); - emIfcToUse = (Class) cl.loadClass("org.hibernate.jpa.HibernateEntityManager"); - providerClass = cl.loadClass("org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider"); - } - catch (ClassNotFoundException ex) { - // Fall back to Hibernate 3.6-4.2 org.hibernate.ejb package - emfIfcToUse = (Class) cl.loadClass("org.hibernate.ejb.HibernateEntityManagerFactory"); - emIfcToUse = (Class) cl.loadClass("org.hibernate.ejb.HibernateEntityManager"); - providerClass = cl.loadClass("org.springframework.orm.jpa.vendor.SpringHibernateEjbPersistenceProvider"); - } - providerToUse = (PersistenceProvider) providerClass.newInstance(); - } - catch (Exception ex) { - throw new IllegalStateException("Failed to determine Hibernate PersistenceProvider", ex); - } - this.persistenceProvider = providerToUse; - this.entityManagerFactoryInterface = emfIfcToUse; - this.entityManagerInterface = emIfcToUse; + this.persistenceProvider = new SpringHibernateJpaPersistenceProvider(); + this.entityManagerFactoryInterface = HibernateEntityManagerFactory.class; + this.entityManagerInterface = HibernateEntityManager.class; } @@ -170,15 +142,15 @@ public class HibernateJpaVendorAdapter extends AbstractJpaVendorAdapter { protected Class determineDatabaseDialectClass(Database database) { switch (database) { case DB2: return DB2Dialect.class; - case DERBY: return DerbyDialect.class; // DerbyDialect deprecated in 4.x + case DERBY: return DerbyDialect.class; case H2: return H2Dialect.class; case HSQL: return HSQLDialect.class; case INFORMIX: return InformixDialect.class; case MYSQL: return MySQLDialect.class; case ORACLE: return Oracle9iDialect.class; - case POSTGRESQL: return PostgreSQLDialect.class; // PostgreSQLDialect deprecated in 4.x + case POSTGRESQL: return PostgreSQLDialect.class; case SQL_SERVER: return SQLServerDialect.class; - case SYBASE: return org.hibernate.dialect.SybaseDialect.class; // SybaseDialect deprecated in 3.6 but not 4.x + case SYBASE: return org.hibernate.dialect.SybaseDialect.class; default: return null; } } diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/SpringHibernateEjbPersistenceProvider.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/SpringHibernateEjbPersistenceProvider.java deleted file mode 100644 index f0d9bffd26..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/SpringHibernateEjbPersistenceProvider.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.jpa.vendor; - -import java.util.Map; -import javax.persistence.EntityManagerFactory; -import javax.persistence.spi.PersistenceUnitInfo; - -import org.hibernate.ejb.Ejb3Configuration; -import org.hibernate.ejb.HibernatePersistence; - -import org.springframework.orm.jpa.persistenceunit.SmartPersistenceUnitInfo; - -/** - * Spring-specific subclass of the standard {@link HibernatePersistence} - * provider from the {@code org.hibernate.ejb} package, adding support for - * {@link SmartPersistenceUnitInfo#getManagedPackages()}. - * - *

Compatible with Hibernate 3.6 as well as 4.0-4.2. - * - * @author Juergen Hoeller - * @author Joris Kuipers - * @since 4.1 - * @see Ejb3Configuration#addPackage - */ -class SpringHibernateEjbPersistenceProvider extends HibernatePersistence { - - @SuppressWarnings("rawtypes") - public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map properties) { - Ejb3Configuration cfg = new Ejb3Configuration(); - if (info instanceof SmartPersistenceUnitInfo) { - for (String managedPackage : ((SmartPersistenceUnitInfo) info).getManagedPackages()) { - cfg.addPackage(managedPackage); - } - } - Ejb3Configuration configured = cfg.configure(info, properties); - return (configured != null ? configured.buildEntityManagerFactory() : null); - } - -} diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/jpa/vendor/SpringHibernateJpaPersistenceProvider.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/SpringHibernateJpaPersistenceProvider.java similarity index 90% rename from spring-orm-hibernate4/src/main/java/org/springframework/orm/jpa/vendor/SpringHibernateJpaPersistenceProvider.java rename to spring-orm/src/main/java/org/springframework/orm/jpa/vendor/SpringHibernateJpaPersistenceProvider.java index 88e063bfbe..90e29408e7 100644 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/jpa/vendor/SpringHibernateJpaPersistenceProvider.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/SpringHibernateJpaPersistenceProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,9 +34,6 @@ import org.springframework.orm.jpa.persistenceunit.SmartPersistenceUnitInfo; * from the {@code org.hibernate.jpa} package, adding support for * {@link SmartPersistenceUnitInfo#getManagedPackages()}. * - *

Compatible with Hibernate 4.3-5.0. {@link SpringHibernateEjbPersistenceProvider} - * is an alternative for compatibility with earlier Hibernate versions (3.6-4.2). - * * @author Juergen Hoeller * @author Joris Kuipers * @since 4.1 diff --git a/spring-orm/src/test/java/org/springframework/orm/hibernate3/HibernateInterceptorTests.java b/spring-orm/src/test/java/org/springframework/orm/hibernate3/HibernateInterceptorTests.java deleted file mode 100644 index dd94db2174..0000000000 --- a/spring-orm/src/test/java/org/springframework/orm/hibernate3/HibernateInterceptorTests.java +++ /dev/null @@ -1,375 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import java.sql.SQLException; - -import org.aopalliance.intercept.MethodInvocation; -import org.hibernate.FlushMode; -import org.hibernate.HibernateException; -import org.hibernate.SessionFactory; -import org.hibernate.classic.Session; -import org.hibernate.exception.ConstraintViolationException; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.mockito.InOrder; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import org.springframework.beans.factory.BeanFactory; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.transaction.support.TransactionSynchronizationManager; - -import static org.junit.Assert.*; -import static org.mockito.BDDMockito.*; - -/** - * @author Juergen Hoeller - * @author Phillip Webb - * @since 05.03.2005 - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public class HibernateInterceptorTests { - - private SessionFactory sessionFactory; - private Session session; - private MethodInvocation invocation; - - @Before - public void setUp() throws Throwable { - this.sessionFactory = mock(SessionFactory.class); - this.session = mock(Session.class); - this.invocation = mock(MethodInvocation.class); - given(sessionFactory.openSession()).willReturn(session); - given(session.getSessionFactory()).willReturn(sessionFactory); - given(invocation.proceed()).willAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - if (!TransactionSynchronizationManager.hasResource(sessionFactory)) { - throw new IllegalStateException("Session not bound"); - } - return null; - } - }); - } - - @After - public void tearDown() { - assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty()); - assertFalse(TransactionSynchronizationManager.isSynchronizationActive()); - } - - @Test - public void testInterceptorWithNewSession() throws HibernateException { - HibernateInterceptor interceptor = new HibernateInterceptor(); - interceptor.setSessionFactory(sessionFactory); - try { - interceptor.invoke(invocation); - } - catch (Throwable t) { - fail("Should not have thrown Throwable: " + t.getMessage()); - } - - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testInterceptorWithNewSessionAndFlushNever() throws HibernateException { - HibernateInterceptor interceptor = new HibernateInterceptor(); - interceptor.setFlushModeName("FLUSH_NEVER"); - interceptor.setSessionFactory(sessionFactory); - try { - interceptor.invoke(invocation); - } - catch (Throwable t) { - fail("Should not have thrown Throwable: " + t.getMessage()); - } - verify(session).setFlushMode(FlushMode.MANUAL); - verify(session, never()).flush(); - verify(session).close(); - } - - @Test - public void testInterceptorWithNewSessionAndFilter() throws HibernateException { - HibernateInterceptor interceptor = new HibernateInterceptor(); - interceptor.setSessionFactory(sessionFactory); - interceptor.setFilterName("myFilter"); - try { - interceptor.invoke(invocation); - } - catch (Throwable t) { - fail("Should not have thrown Throwable: " + t.getMessage()); - } - - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testInterceptorWithThreadBound() { - given(session.isOpen()).willReturn(true); - - TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session)); - HibernateInterceptor interceptor = new HibernateInterceptor(); - interceptor.setSessionFactory(sessionFactory); - try { - interceptor.invoke(invocation); - } - catch (Throwable t) { - fail("Should not have thrown Throwable: " + t.getMessage()); - } - finally { - verify(session, never()).flush(); - verify(session, never()).close(); - TransactionSynchronizationManager.unbindResource(sessionFactory); - } - } - - @Test - public void testInterceptorWithThreadBoundAndFlushEager() throws HibernateException { - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - - TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session)); - HibernateInterceptor interceptor = new HibernateInterceptor(); - interceptor.setFlushMode(HibernateInterceptor.FLUSH_EAGER); - interceptor.setSessionFactory(sessionFactory); - try { - interceptor.invoke(invocation); - } - catch (Throwable t) { - fail("Should not have thrown Throwable: " + t.getMessage()); - } - finally { - TransactionSynchronizationManager.unbindResource(sessionFactory); - } - - verify(session).flush(); - } - - @Test - public void testInterceptorWithThreadBoundAndFlushEagerSwitch() throws HibernateException { - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(FlushMode.NEVER); - - TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session)); - HibernateInterceptor interceptor = new HibernateInterceptor(); - interceptor.setFlushMode(HibernateInterceptor.FLUSH_EAGER); - interceptor.setSessionFactory(sessionFactory); - try { - interceptor.invoke(invocation); - } - catch (Throwable t) { - fail("Should not have thrown Throwable: " + t.getMessage()); - } - finally { - TransactionSynchronizationManager.unbindResource(sessionFactory); - } - - InOrder ordered = inOrder(session); - ordered.verify(session).setFlushMode(FlushMode.AUTO); - ordered.verify(session).flush(); - ordered.verify(session).setFlushMode(FlushMode.NEVER); - } - - @Test - public void testInterceptorWithThreadBoundAndFlushCommit() { - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - - TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session)); - HibernateInterceptor interceptor = new HibernateInterceptor(); - interceptor.setSessionFactory(sessionFactory); - interceptor.setFlushMode(HibernateInterceptor.FLUSH_COMMIT); - try { - interceptor.invoke(invocation); - } - catch (Throwable t) { - fail("Should not have thrown Throwable: " + t.getMessage()); - } - finally { - TransactionSynchronizationManager.unbindResource(sessionFactory); - } - - InOrder ordered = inOrder(session); - ordered.verify(session).setFlushMode(FlushMode.COMMIT); - ordered.verify(session).setFlushMode(FlushMode.AUTO); - verify(session, never()).flush(); - } - - @Test - public void testInterceptorWithThreadBoundAndFlushAlways() { - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - - TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session)); - HibernateInterceptor interceptor = new HibernateInterceptor(); - interceptor.setSessionFactory(sessionFactory); - interceptor.setFlushMode(HibernateInterceptor.FLUSH_ALWAYS); - try { - interceptor.invoke(invocation); - } - catch (Throwable t) { - fail("Should not have thrown Throwable: " + t.getMessage()); - } - finally { - TransactionSynchronizationManager.unbindResource(sessionFactory); - } - - InOrder ordered = inOrder(session); - ordered.verify(session).setFlushMode(FlushMode.ALWAYS); - ordered.verify(session).setFlushMode(FlushMode.AUTO); - verify(session, never()).flush(); - } - - @Test - public void testInterceptorWithThreadBoundAndFilter() { - given(session.isOpen()).willReturn(true); - - TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session)); - HibernateInterceptor interceptor = new HibernateInterceptor(); - interceptor.setSessionFactory(sessionFactory); - interceptor.setFilterName("myFilter"); - try { - interceptor.invoke(invocation); - } - catch (Throwable t) { - fail("Should not have thrown Throwable: " + t.getMessage()); - } - finally { - TransactionSynchronizationManager.unbindResource(sessionFactory); - } - - InOrder ordered = inOrder(session); - ordered.verify(session).enableFilter("myFilter"); - ordered.verify(session).disableFilter("myFilter"); - } - - @Test - public void testInterceptorWithThreadBoundAndFilters() { - given(session.isOpen()).willReturn(true); - - TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session)); - HibernateInterceptor interceptor = new HibernateInterceptor(); - interceptor.setSessionFactory(sessionFactory); - interceptor.setFilterNames(new String[] {"myFilter", "yourFilter"}); - try { - interceptor.invoke(invocation); - } - catch (Throwable t) { - fail("Should not have thrown Throwable: " + t.getMessage()); - } - finally { - TransactionSynchronizationManager.unbindResource(sessionFactory); - } - - InOrder ordered = inOrder(session); - ordered.verify(session).enableFilter("myFilter"); - ordered.verify(session).enableFilter("yourFilter"); - ordered.verify(session).disableFilter("myFilter"); - ordered.verify(session).disableFilter("yourFilter"); - } - - @Test - public void testInterceptorWithFlushFailure() throws Throwable { - SQLException sqlEx = new SQLException("argh", "27"); - ConstraintViolationException jdbcEx = new ConstraintViolationException("", sqlEx, null); - willThrow(jdbcEx).given(session).flush(); - - HibernateInterceptor interceptor = new HibernateInterceptor(); - interceptor.setSessionFactory(sessionFactory); - try { - interceptor.invoke(invocation); - fail("Should have thrown DataIntegrityViolationException"); - } - catch (DataIntegrityViolationException ex) { - // expected - assertEquals(jdbcEx, ex.getCause()); - } - - verify(session).close(); - } - - @Test - public void testInterceptorWithThreadBoundEmptyHolder() { - SessionHolder holder = new SessionHolder("key", session); - holder.removeSession("key"); - TransactionSynchronizationManager.bindResource(sessionFactory, holder); - HibernateInterceptor interceptor = new HibernateInterceptor(); - interceptor.setSessionFactory(sessionFactory); - try { - interceptor.invoke(invocation); - } - catch (Throwable t) { - fail("Should not have thrown Throwable: " + t.getMessage()); - } - - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testInterceptorWithEntityInterceptor() throws HibernateException { - org.hibernate.Interceptor entityInterceptor = mock(org.hibernate.Interceptor.class); - given(sessionFactory.openSession(entityInterceptor)).willReturn(session); - - HibernateInterceptor interceptor = new HibernateInterceptor(); - interceptor.setSessionFactory(sessionFactory); - interceptor.setEntityInterceptor(entityInterceptor); - try { - interceptor.invoke(invocation); - } - catch (Throwable t) { - fail("Should not have thrown Throwable: " + t.getMessage()); - } - - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testInterceptorWithEntityInterceptorBeanName() throws HibernateException { - org.hibernate.Interceptor entityInterceptor = mock(org.hibernate.Interceptor.class); - org.hibernate.Interceptor entityInterceptor2 = mock(org.hibernate.Interceptor.class); - - given(sessionFactory.openSession(entityInterceptor)).willReturn(session); - given(sessionFactory.openSession(entityInterceptor2)).willReturn(session); - - BeanFactory beanFactory = mock(BeanFactory.class); - given(beanFactory.getBean("entityInterceptor", org.hibernate.Interceptor.class)).willReturn( - entityInterceptor, entityInterceptor2); - - HibernateInterceptor interceptor = new HibernateInterceptor(); - interceptor.setSessionFactory(sessionFactory); - interceptor.setEntityInterceptorBeanName("entityInterceptor"); - interceptor.setBeanFactory(beanFactory); - for (int i = 0; i < 2; i++) { - try { - interceptor.invoke(invocation); - } - catch (Throwable t) { - fail("Should not have thrown Throwable: " + t.getMessage()); - } - } - - verify(session, times(2)).flush(); - verify(session, times(2)).close(); - } -} diff --git a/spring-orm/src/test/java/org/springframework/orm/hibernate3/HibernateJtaTransactionTests.java b/spring-orm/src/test/java/org/springframework/orm/hibernate3/HibernateJtaTransactionTests.java deleted file mode 100644 index 9c1988efd4..0000000000 --- a/spring-orm/src/test/java/org/springframework/orm/hibernate3/HibernateJtaTransactionTests.java +++ /dev/null @@ -1,1539 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import java.util.ArrayList; -import java.util.List; -import javax.transaction.RollbackException; -import javax.transaction.Status; -import javax.transaction.Synchronization; -import javax.transaction.SystemException; -import javax.transaction.TransactionManager; -import javax.transaction.UserTransaction; - -import org.hibernate.FlushMode; -import org.hibernate.HibernateException; -import org.hibernate.Query; -import org.hibernate.SessionFactory; -import org.hibernate.classic.Session; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; -import org.junit.After; -import org.junit.Test; -import org.mockito.InOrder; - -import org.springframework.dao.DataAccessException; -import org.springframework.tests.transaction.MockJtaTransaction; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.TransactionException; -import org.springframework.transaction.TransactionStatus; -import org.springframework.transaction.UnexpectedRollbackException; -import org.springframework.transaction.jta.JtaTransactionManager; -import org.springframework.transaction.support.TransactionCallback; -import org.springframework.transaction.support.TransactionCallbackWithoutResult; -import org.springframework.transaction.support.TransactionSynchronizationManager; -import org.springframework.transaction.support.TransactionTemplate; - -import static org.junit.Assert.*; -import static org.mockito.BDDMockito.*; - -/** - * @author Juergen Hoeller - * @author Phillip Webb - * @since 05.03.2005 - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public class HibernateJtaTransactionTests { - - @After - public void tearDown() { - assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty()); - assertFalse(TransactionSynchronizationManager.isSynchronizationActive()); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); - } - - @Test - public void testJtaTransactionCommit() throws Exception { - doTestJtaTransactionCommit(Status.STATUS_NO_TRANSACTION, false); - } - - @Test - public void testJtaTransactionCommitWithReadOnly() throws Exception { - doTestJtaTransactionCommit(Status.STATUS_NO_TRANSACTION, true); - } - - @Test - public void testJtaTransactionCommitWithExisting() throws Exception { - doTestJtaTransactionCommit(Status.STATUS_ACTIVE, false); - } - - @Test - public void testJtaTransactionCommitWithExistingAndReadOnly() throws Exception { - doTestJtaTransactionCommit(Status.STATUS_ACTIVE, true); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private void doTestJtaTransactionCommit(int status, final boolean readOnly) throws Exception { - UserTransaction ut = mock(UserTransaction.class); - final SessionFactory sf = mock(SessionFactory.class); - final Session session = mock(Session.class); - Query query = mock(Query.class); - if (status == Status.STATUS_NO_TRANSACTION) { - given(ut.getStatus()).willReturn(status, Status.STATUS_ACTIVE); - } - else { - given(ut.getStatus()).willReturn(status); - } - - final List list = new ArrayList(); - list.add("test"); - given(sf.openSession()).willReturn(session); - given(session.getSessionFactory()).willReturn(sf); - given(session.isOpen()).willReturn(true); - given(session.createQuery("some query string")).willReturn(query); - given(query.list()).willReturn(list); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - - JtaTransactionManager ptm = new JtaTransactionManager(ut); - TransactionTemplate tt = new TransactionTemplate(ptm); - tt.setReadOnly(readOnly); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - - Object result = tt.execute(new TransactionCallback() { - - @Override - public Object doInTransaction(TransactionStatus status) { - try { - assertTrue("JTA synchronizations active", - TransactionSynchronizationManager.isSynchronizationActive()); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - HibernateTemplate ht = new HibernateTemplate(sf); - ht.setExposeNativeSession(true); - ht.executeFind(new HibernateCallback() { - - @Override - public Object doInHibernate(org.hibernate.Session sess) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertEquals(session, sess); - return null; - } - }); - ht = new HibernateTemplate(sf); - List htl = ht.executeFind(new HibernateCallback() { - - @Override - public Object doInHibernate(org.hibernate.Session sess) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - return sess.createQuery("some query string").list(); - } - }); - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - return htl; - } - catch (Error err) { - err.printStackTrace(); - throw err; - } - } - }); - - assertTrue("Correct result list", result == list); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - if (status == Status.STATUS_NO_TRANSACTION) { - InOrder ordered = inOrder(ut); - ordered.verify(ut).begin(); - ordered.verify(ut).commit(); - } - - if (readOnly) { - verify(session).setFlushMode(FlushMode.MANUAL); - } - else { - verify(session).flush(); - } - verify(session).close(); - } - - @Test - public void testJtaTransactionCommitWithJtaTm() throws Exception { - doTestJtaTransactionCommitWithJtaTm(Status.STATUS_NO_TRANSACTION); - } - - @Test - public void testJtaTransactionCommitWithJtaTmAndExisting() throws Exception { - doTestJtaTransactionCommitWithJtaTm(Status.STATUS_ACTIVE); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private void doTestJtaTransactionCommitWithJtaTm(int status) throws Exception { - - UserTransaction ut = mock(UserTransaction.class); - if (status == Status.STATUS_NO_TRANSACTION) { - given(ut.getStatus()).willReturn(status, status, Status.STATUS_ACTIVE); - } - else { - given(ut.getStatus()).willReturn(status); - } - - TransactionManager tm = mock(TransactionManager.class); - MockJtaTransaction transaction = new MockJtaTransaction(); - given(tm.getTransaction()).willReturn(transaction); - - final SessionFactoryImplementor sf = mock(SessionFactoryImplementor.class); - final Session session = mock(Session.class); - given(sf.getTransactionManager()).willReturn(tm); - given(sf.openSession()).willReturn(session); - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - - JtaTransactionManager ptm = new JtaTransactionManager(ut); - TransactionTemplate tt = new TransactionTemplate(ptm); - final List l = new ArrayList(); - l.add("test"); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - - Object result = tt.execute(new TransactionCallback() { - - @Override - public Object doInTransaction(TransactionStatus status) { - try { - assertTrue("JTA synchronizations active", - TransactionSynchronizationManager.isSynchronizationActive()); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - HibernateTemplate ht = new HibernateTemplate(sf); - ht.setExposeNativeSession(true); - List htl = ht.executeFind(new HibernateCallback() { - - @Override - public Object doInHibernate(org.hibernate.Session sess) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertEquals(session, sess); - return l; - } - }); - ht = new HibernateTemplate(sf); - ht.setExposeNativeSession(true); - htl = ht.executeFind(new HibernateCallback() { - - @Override - public Object doInHibernate(org.hibernate.Session sess) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertEquals(session, sess); - return l; - } - }); - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - return htl; - } - catch (Error err) { - err.printStackTrace(); - throw err; - } - } - }); - - assertTrue("Correct result list", result == l); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - if (status == Status.STATUS_NO_TRANSACTION) { - InOrder ordered = inOrder(ut); - ordered.verify(ut).begin(); - ordered.verify(ut).commit(); - } - verify(session).flush(); - verify(session).close(); - } - - @Test - @SuppressWarnings({ "rawtypes", "unchecked" }) - public void testJtaTransactionWithFlushFailure() throws Exception { - - UserTransaction ut = mock(UserTransaction.class); - given(ut.getStatus()).willReturn(Status.STATUS_NO_TRANSACTION, Status.STATUS_ACTIVE); - - final SessionFactory sf = mock(SessionFactory.class); - final Session session = mock(Session.class); - given(sf.openSession()).willReturn(session); - given(session.getSessionFactory()).willReturn(sf); - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - - JtaTransactionManager ptm = new JtaTransactionManager(ut); - TransactionTemplate tt = new TransactionTemplate(ptm); - final List l = new ArrayList(); - l.add("test"); - final HibernateException flushEx = new HibernateException("flush failure"); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - willThrow(flushEx).given(session).flush(); - - try { - tt.execute(new TransactionCallback() { - - @Override - public Object doInTransaction(TransactionStatus status) { - try { - assertTrue("JTA synchronizations active", - TransactionSynchronizationManager.isSynchronizationActive()); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - HibernateTemplate ht = new HibernateTemplate(sf); - ht.setExposeNativeSession(true); - List htl = ht.executeFind(new HibernateCallback() { - - @Override - public Object doInHibernate(org.hibernate.Session sess) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertEquals(session, sess); - return l; - } - }); - ht = new HibernateTemplate(sf); - ht.setExposeNativeSession(true); - htl = ht.executeFind(new HibernateCallback() { - - @Override - public Object doInHibernate(org.hibernate.Session sess) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertEquals(session, sess); - return l; - } - }); - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - return htl; - } - catch (Error err) { - err.printStackTrace(); - throw err; - } - } - }); - } - catch (DataAccessException ex) { - // expected - assertTrue(flushEx == ex.getCause()); - } - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - verify(ut).begin(); - verify(ut).rollback(); - verify(session).close(); - } - - @Test - public void testJtaTransactionRollback() throws Exception { - doTestJtaTransactionRollback(false); - } - - @Test - public void testJtaTransactionRollbackWithFlush() throws Exception { - doTestJtaTransactionRollback(true); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private void doTestJtaTransactionRollback(final boolean flush) throws Exception { - - UserTransaction ut = mock(UserTransaction.class); - given(ut.getStatus()).willReturn(Status.STATUS_NO_TRANSACTION, Status.STATUS_ACTIVE); - - final SessionFactory sf = mock(SessionFactory.class); - final Session session = mock(Session.class); - given(sf.openSession()).willReturn(session); - given(session.getSessionFactory()).willReturn(sf); - - JtaTransactionManager ptm = new JtaTransactionManager(ut); - TransactionTemplate tt = new TransactionTemplate(ptm); - final List l = new ArrayList(); - l.add("test"); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - Object result = tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - try { - assertTrue("JTA synchronizations active", - TransactionSynchronizationManager.isSynchronizationActive()); - HibernateTemplate ht = new HibernateTemplate(sf); - List htl = ht.executeFind(new HibernateCallback() { - - @Override - public Object doInHibernate(org.hibernate.Session session) { - return l; - } - }); - if (flush) { - status.flush(); - } - status.setRollbackOnly(); - return htl; - } - catch (Error err) { - err.printStackTrace(); - throw err; - } - } - }); - assertTrue("Correct result list", result == l); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - InOrder ordered = inOrder(ut); - ordered.verify(ut).begin(); - ordered.verify(ut).rollback(); - if (flush) { - verify(session).flush(); - } - verify(session).close(); - } - - @Test - public void testJtaTransactionCommitWithPreBound() throws Exception { - doTestJtaTransactionCommitWithPreBound(false, false, false); - } - - @Test - public void testJtaTransactionCommitWithPreBoundAndReadOnly() throws Exception { - doTestJtaTransactionCommitWithPreBound(false, false, true); - } - - @Test - public void testJtaTransactionCommitWithPreBoundAndFlushModeNever() throws Exception { - doTestJtaTransactionCommitWithPreBound(false, true, false); - } - - @Test - public void testJtaTransactionCommitWithPreBoundAndFlushModeNeverAndReadOnly() throws Exception { - doTestJtaTransactionCommitWithPreBound(false, true, true); - } - - @Test - public void testJtaTransactionCommitWithJtaTmAndPreBound() throws Exception { - doTestJtaTransactionCommitWithPreBound(true, false, false); - } - - @Test - public void testJtaTransactionCommitWithJtaTmAndPreBoundAndReadOnly() throws Exception { - doTestJtaTransactionCommitWithPreBound(true, false, true); - } - - @Test - public void testJtaTransactionCommitWithJtaTmAndPreBoundAndFlushModeNever() throws Exception { - doTestJtaTransactionCommitWithPreBound(true, true, false); - } - - @Test - public void testJtaTransactionCommitWithJtaTmAndPreBoundAndFlushModeNeverAndReadOnly() throws Exception { - doTestJtaTransactionCommitWithPreBound(true, true, true); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - protected void doTestJtaTransactionCommitWithPreBound(boolean jtaTm, final boolean flushNever, - final boolean readOnly) throws Exception { - - - UserTransaction ut = mock(UserTransaction.class); - given(ut.getStatus()).willReturn(Status.STATUS_NO_TRANSACTION, - Status.STATUS_ACTIVE, Status.STATUS_ACTIVE); - - TransactionManager tm = mock(TransactionManager.class); - if (jtaTm) { - MockJtaTransaction transaction = new MockJtaTransaction(); - given(tm.getTransaction()).willReturn(transaction); - } - - final SessionFactoryImplementor sf = mock(SessionFactoryImplementor.class); - final ExtendedSession session = mock(ExtendedSession.class); - given(sf.getTransactionManager()).willReturn(jtaTm ? tm : null); - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(flushNever ? FlushMode.MANUAL: FlushMode.AUTO); - - TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session)); - try { - JtaTransactionManager ptm = new JtaTransactionManager(ut); - TransactionTemplate tt = new TransactionTemplate(ptm); - tt.setReadOnly(readOnly); - final List l = new ArrayList(); - l.add("test"); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - - Object result = tt.execute(new TransactionCallback() { - - @Override - public Object doInTransaction(TransactionStatus status) { - try { - assertTrue("JTA synchronizations active", - TransactionSynchronizationManager.isSynchronizationActive()); - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - HibernateTemplate ht = new HibernateTemplate(sf); - ht.setExposeNativeSession(true); - List htl = null; - for (int i = 0; i < 5; i++) { - htl = ht.executeFind(new HibernateCallback() { - - @Override - public Object doInHibernate(org.hibernate.Session sess) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertEquals(session, sess); - return l; - } - }); - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - } - return htl; - } - catch (Error err) { - err.printStackTrace(); - throw err; - } - } - }); - - assertTrue("Correct result list", result == l); - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - } - finally { - TransactionSynchronizationManager.unbindResource(sf); - } - - verify(ut).begin(); - verify(ut).commit(); - - if (flushNever) { - if (!readOnly) { - InOrder ordered = inOrder(session); - ordered.verify(session).setFlushMode(FlushMode.AUTO); - ordered.verify(session).setFlushMode(FlushMode.MANUAL); - } - } - if (!flushNever && !readOnly) { - verify(session).flush(); - } - verify(session).afterTransactionCompletion(true, null); - verify(session).disconnect(); - } - - @Test - @SuppressWarnings({ "rawtypes", "unchecked" }) - public void testJtaTransactionRollbackWithPreBound() throws Exception { - - UserTransaction ut = mock(UserTransaction.class); - given(ut.getStatus()).willReturn(Status.STATUS_NO_TRANSACTION, - Status.STATUS_ACTIVE, Status.STATUS_ACTIVE, - Status.STATUS_MARKED_ROLLBACK, Status.STATUS_MARKED_ROLLBACK); - RollbackException rex = new RollbackException(); - willThrow(rex).given(ut).commit(); - - final SessionFactory sf = mock(SessionFactory.class); - - final Session session = mock(Session.class); - given(session.getSessionFactory()).willReturn(sf); - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - - TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session)); - try { - JtaTransactionManager ptm = new JtaTransactionManager(ut); - final TransactionTemplate tt = new TransactionTemplate(ptm); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - - tt.execute(new TransactionCallbackWithoutResult() { - - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - tt.execute(new TransactionCallbackWithoutResult() { - - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - status.setRollbackOnly(); - try { - assertTrue("JTA synchronizations active", - TransactionSynchronizationManager.isSynchronizationActive()); - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - HibernateTemplate ht = new HibernateTemplate(sf); - ht.setExposeNativeSession(true); - for (int i = 0; i < 5; i++) { - ht.execute(new HibernateCallback() { - - @Override - public Object doInHibernate(org.hibernate.Session sess) { - assertTrue("Has thread session", - TransactionSynchronizationManager.hasResource(sf)); - assertEquals(session, sess); - return null; - } - }); - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - } - } - catch (Error err) { - err.printStackTrace(); - throw err; - } - } - }); - } - }); - fail("Should have thrown UnexpectedRollbackException"); - } - catch (UnexpectedRollbackException ex) { - // expected - assertEquals(rex, ex.getCause()); - } - finally { - TransactionSynchronizationManager.unbindResource(sf); - } - - verify(ut).begin(); - verify(ut).setRollbackOnly(); - verify(session).flush(); - verify(session).disconnect(); - verify(session).clear(); - } - - @Test - public void testJtaTransactionCommitWithRequiresNew() throws Exception { - doTestJtaTransactionWithRequiresNew(false); - } - - @Test - public void testJtaTransactionRollbackWithRequiresNew() throws Exception { - doTestJtaTransactionWithRequiresNew(true); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - protected void doTestJtaTransactionWithRequiresNew(final boolean rollback) throws Exception { - - UserTransaction ut = mock(UserTransaction.class); - - TransactionManager tm = mock(TransactionManager.class); - javax.transaction.Transaction tx1 = mock(javax.transaction.Transaction.class); - - final SessionFactory sf = mock(SessionFactory.class); - final Session session1 = mock(Session.class); - final Session session2 = mock(Session.class); - - given(ut.getStatus()).willReturn(Status.STATUS_NO_TRANSACTION, - Status.STATUS_ACTIVE, Status.STATUS_ACTIVE, Status.STATUS_ACTIVE, - Status.STATUS_ACTIVE, Status.STATUS_ACTIVE); - given(tm.suspend()).willReturn(tx1); - given(sf.openSession()).willReturn(session1, session2); - given(session1.getSessionFactory()).willReturn(sf); - given(session2.getSessionFactory()).willReturn(sf); - given(session1.isOpen()).willReturn(true); - given(session2.isOpen()).willReturn(true); - given(session2.getFlushMode()).willReturn(FlushMode.AUTO); - if (!rollback) { - given(session1.getFlushMode()).willReturn(FlushMode.AUTO); - } - - JtaTransactionManager ptm = new JtaTransactionManager(); - ptm.setUserTransaction(ut); - ptm.setTransactionManager(tm); - final TransactionTemplate tt = new TransactionTemplate(ptm); - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - try { - tt.execute(new TransactionCallback() { - - @Override - public Object doInTransaction(TransactionStatus status) { - org.hibernate.Session outerSession = SessionFactoryUtils.getSession(sf, false); - assertSame(session1, outerSession); - SessionHolder holder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); - assertTrue("Has thread session", holder != null); - try { - tt.execute(new TransactionCallback() { - - @Override - public Object doInTransaction(TransactionStatus status) { - org.hibernate.Session innerSession = SessionFactoryUtils.getSession(sf, false); - assertSame(session2, innerSession); - HibernateTemplate ht = new HibernateTemplate(sf); - ht.setFlushMode(HibernateTemplate.FLUSH_EAGER); - return ht.executeFind(new HibernateCallback() { - - @Override - public Object doInHibernate(org.hibernate.Session innerSession) { - if (rollback) { - throw new HibernateException(""); - } - return null; - } - }); - } - }); - return null; - } - finally { - assertTrue("Same thread session as before", - outerSession == SessionFactoryUtils.getSession(sf, false)); - } - } - }); - if (rollback) { - fail("Should have thrown DataAccessException"); - } - } - catch (DataAccessException ex) { - if (!rollback) { - throw ex; - } - } - finally { - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - } - - verify(ut, times(2)).begin(); - verify(tm).resume(tx1); - if (rollback) { - verify(ut, times(2)).rollback(); - } - else { - verify(ut, times(2)).commit(); - } - verify(session1).disconnect(); - verify(session1).close(); - if (!rollback) { - verify(session1).flush(); - verify(session2, atLeastOnce()).flush(); - } - verify(session2).close(); - } - - @Test - public void testJtaTransactionWithRequiresNewAndSuspendException() throws Exception { - doTestJtaTransactionWithRequiresNewAndException(true); - } - - @Test - public void testJtaTransactionWithRequiresNewAndBeginException() throws Exception { - doTestJtaTransactionWithRequiresNewAndException(false); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - protected void doTestJtaTransactionWithRequiresNewAndException(boolean suspendException) throws Exception { - - UserTransaction ut = mock(UserTransaction.class); - - TransactionManager tm = mock(TransactionManager.class); - javax.transaction.Transaction tx = mock(javax.transaction.Transaction.class); - - final SessionFactory sf = mock(SessionFactory.class); - final Session session1 = mock(Session.class); - - given(ut.getStatus()).willReturn(Status.STATUS_NO_TRANSACTION, Status.STATUS_ACTIVE, Status.STATUS_ACTIVE); - if (suspendException) { - given(tm.suspend()).willThrow(new SystemException()); - } - else { - given(tm.suspend()).willReturn(tx); - willDoNothing().willThrow(new SystemException()).given(ut).begin(); - } - - given(sf.openSession()).willReturn(session1); - given(session1.getSessionFactory()).willReturn(sf); - - JtaTransactionManager ptm = new JtaTransactionManager(); - ptm.setUserTransaction(ut); - ptm.setTransactionManager(tm); - final TransactionTemplate tt = new TransactionTemplate(ptm); - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - try { - tt.execute(new TransactionCallback() { - - @Override - public Object doInTransaction(TransactionStatus status) { - org.hibernate.Session outerSession = SessionFactoryUtils.getSession(sf, false); - assertSame(session1, outerSession); - SessionHolder holder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); - assertTrue("Has thread session", holder != null); - tt.execute(new TransactionCallback() { - - @Override - public Object doInTransaction(TransactionStatus status) { - return null; - } - }); - return null; - } - }); - fail("Should have thrown TransactionException"); - } - catch (TransactionException ex) { - // expected - } - finally { - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - } - - verify(ut, atLeastOnce()).begin(); - if (!suspendException) { - verify(tm).resume(tx); - } - verify(ut).rollback(); - verify(session1).disconnect(); - verify(session1).close(); - } - - @Test - public void testJtaTransactionCommitWithRequiresNewAndJtaTm() throws Exception { - doTestJtaTransactionWithRequiresNewAndJtaTm(false); - } - - @Test - public void testJtaTransactionRollbackWithRequiresNewAndJtaTm() throws Exception { - doTestJtaTransactionWithRequiresNewAndJtaTm(true); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - protected void doTestJtaTransactionWithRequiresNewAndJtaTm(final boolean rollback) throws Exception { - - UserTransaction ut = mock(UserTransaction.class); - - TransactionManager tm = mock(TransactionManager.class); - javax.transaction.Transaction tx1 = mock(javax.transaction.Transaction.class); - - final SessionFactoryImplementor sf = mock(SessionFactoryImplementor.class); - final Session session1 = mock(Session.class); - final Session session2 = mock(Session.class); - - MockJtaTransaction transaction1 = new MockJtaTransaction(); - MockJtaTransaction transaction2 = new MockJtaTransaction(); - given(ut.getStatus()).willReturn(Status.STATUS_NO_TRANSACTION, - Status.STATUS_ACTIVE, Status.STATUS_ACTIVE, Status.STATUS_ACTIVE, - Status.STATUS_ACTIVE, Status.STATUS_ACTIVE); - given(tm.getTransaction()).willReturn(transaction1); - given(tm.suspend()).willReturn(tx1); - given(tm.getTransaction()).willReturn(transaction2); - given(sf.getTransactionManager()).willReturn(tm); - given(sf.openSession()).willReturn(session1, session2); - given(session1.isOpen()).willReturn(true); - given(session2.isOpen()).willReturn(true); - given(session1.getFlushMode()).willReturn(FlushMode.AUTO); - given(session2.getFlushMode()).willReturn(FlushMode.AUTO); - - JtaTransactionManager ptm = new JtaTransactionManager(); - ptm.setUserTransaction(ut); - ptm.setTransactionManager(tm); - final TransactionTemplate tt = new TransactionTemplate(ptm); - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - try { - tt.execute(new TransactionCallback() { - - @Override - public Object doInTransaction(TransactionStatus status) { - org.hibernate.Session outerSession = SessionFactoryUtils.getSession(sf, false); - assertSame(session1, outerSession); - SessionHolder holder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); - assertTrue("Has thread session", holder != null); - try { - tt.execute(new TransactionCallback() { - - @Override - public Object doInTransaction(TransactionStatus status) { - org.hibernate.Session innerSession = SessionFactoryUtils.getSession(sf, false); - assertSame(session2, innerSession); - HibernateTemplate ht = new HibernateTemplate(sf); - ht.setFlushMode(HibernateTemplate.FLUSH_EAGER); - return ht.executeFind(new HibernateCallback() { - - @Override - public Object doInHibernate(org.hibernate.Session innerSession) { - if (rollback) { - throw new HibernateException(""); - } - return null; - } - }); - } - }); - return null; - } - finally { - assertTrue("Same thread session as before", - outerSession == SessionFactoryUtils.getSession(sf, false)); - } - } - }); - if (rollback) { - fail("Should have thrown DataAccessException"); - } - } - catch (DataAccessException ex) { - if (!rollback) { - throw ex; - } - } - finally { - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - } - - verify(ut, times(2)).begin(); - verify(tm).resume(tx1); - if (rollback) { - verify(ut, times(2)).rollback(); - } - else { - verify(ut, times(2)).commit(); - verify(session1).flush(); - verify(session2, times(2)).flush(); - } - verify(session1).disconnect(); - verify(session1).close(); - verify(session2).close(); - } - - @Test - @SuppressWarnings({ "rawtypes", "unchecked" }) - public void testTransactionWithPropagationSupports() throws Exception { - - UserTransaction ut = mock(UserTransaction.class); - given(ut.getStatus()).willReturn(Status.STATUS_NO_TRANSACTION, Status.STATUS_ACTIVE); - - final SessionFactory sf = mock(SessionFactory.class); - final Session session = mock(Session.class); - - given(sf.openSession()).willReturn(session); - given(session.getSessionFactory()).willReturn(sf); - given(session.getFlushMode()).willReturn(FlushMode.MANUAL); - - JtaTransactionManager tm = new JtaTransactionManager(ut); - TransactionTemplate tt = new TransactionTemplate(tm); - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - - tt.execute(new TransactionCallback() { - - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Is not new transaction", !status.isNewTransaction()); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); - HibernateTemplate ht = new HibernateTemplate(sf); - ht.setFlushMode(HibernateTemplate.FLUSH_EAGER); - ht.execute(new HibernateCallback() { - - @Override - public Object doInHibernate(org.hibernate.Session session) { - return null; - } - }); - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - return null; - } - }); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - InOrder ordered = inOrder(session); - ordered.verify(session).setFlushMode(FlushMode.AUTO); - ordered.verify(session).flush(); - ordered.verify(session).setFlushMode(FlushMode.MANUAL); - ordered.verify(session).close(); - } - - @Test - @SuppressWarnings({ "rawtypes", "unchecked" }) - public void testTransactionWithPropagationSupportsAndInnerTransaction() throws Exception { - - UserTransaction ut = mock(UserTransaction.class); - given(ut.getStatus()).willReturn(Status.STATUS_NO_TRANSACTION, Status.STATUS_ACTIVE); - - final SessionFactory sf = mock(SessionFactory.class); - final Session session = mock(Session.class); - - given(sf.openSession()).willReturn(session); - given(session.getSessionFactory()).willReturn(sf); - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - - JtaTransactionManager tm = new JtaTransactionManager(ut); - TransactionTemplate tt = new TransactionTemplate(tm); - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); - final TransactionTemplate tt2 = new TransactionTemplate(tm); - tt2.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - tt.execute(new TransactionCallback() { - - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Is not new transaction", !status.isNewTransaction()); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); - HibernateTemplate ht = new HibernateTemplate(sf); - ht.setFlushMode(HibernateTemplate.FLUSH_EAGER); - ht.execute(new HibernateCallback() { - - @Override - public Object doInHibernate(org.hibernate.Session session) { - return null; - } - }); - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - tt2.execute(new TransactionCallback() { - - @Override - public Object doInTransaction(TransactionStatus status) { - HibernateTemplate ht = new HibernateTemplate(sf); - ht.setFlushMode(HibernateTemplate.FLUSH_EAGER); - return ht.executeFind(new HibernateCallback() { - - @Override - public Object doInHibernate(org.hibernate.Session session) { - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - // assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); - return null; - } - }); - } - }); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); - return null; - } - }); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - verify(session, times(3)).flush(); - verify(session).close(); - } - - @Test - @SuppressWarnings("rawtypes") - public void testJtaSessionSynchronization() throws Exception { - - TransactionManager tm = mock(TransactionManager.class); - MockJtaTransaction transaction = new MockJtaTransaction(); - given(tm.getTransaction()).willReturn(transaction); - final SessionFactoryImplementor sf = mock(SessionFactoryImplementor.class); - final Session session = mock(Session.class); - given(sf.openSession()).willReturn(session); - given(sf.getTransactionManager()).willReturn(tm); - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - HibernateTemplate ht = new HibernateTemplate(sf); - ht.setExposeNativeSession(true); - for (int i = 0; i < 5; i++) { - ht.executeFind(new HibernateCallback() { - - @Override - public Object doInHibernate(org.hibernate.Session sess) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertEquals(session, sess); - return null; - } - }); - } - - Synchronization synchronization = transaction.getSynchronization(); - assertTrue("JTA synchronization registered", synchronization != null); - synchronization.beforeCompletion(); - synchronization.afterCompletion(Status.STATUS_COMMITTED); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - verify(session).flush(); - verify(session).close(); - } - - @Test - @SuppressWarnings("rawtypes") - public void testJtaSessionSynchronizationWithRollback() throws Exception { - - TransactionManager tm = mock(TransactionManager.class); - MockJtaTransaction transaction = new MockJtaTransaction(); - given(tm.getTransaction()).willReturn(transaction); - final SessionFactoryImplementor sf = mock(SessionFactoryImplementor.class); - final Session session = mock(Session.class); - given(sf.openSession()).willReturn(session); - given(sf.getTransactionManager()).willReturn(tm); - given(session.isOpen()).willReturn(true); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - HibernateTemplate ht = new HibernateTemplate(sf); - ht.setExposeNativeSession(true); - for (int i = 0; i < 5; i++) { - ht.executeFind(new HibernateCallback() { - - @Override - public Object doInHibernate(org.hibernate.Session sess) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertEquals(session, sess); - return null; - } - }); - } - - Synchronization synchronization = transaction.getSynchronization(); - assertTrue("JTA synchronization registered", synchronization != null); - synchronization.afterCompletion(Status.STATUS_ROLLEDBACK); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - verify(session).close(); - } - - @Test - @SuppressWarnings("rawtypes") - public void testJtaSessionSynchronizationWithRollbackByOtherThread() throws Exception { - - TransactionManager tm = mock(TransactionManager.class); - MockJtaTransaction transaction = new MockJtaTransaction(); - given(tm.getTransaction()).willReturn(transaction); - given(tm.getStatus()).willReturn(Status.STATUS_NO_TRANSACTION); - final SessionFactoryImplementor sf = mock(SessionFactoryImplementor.class); - final Session session = mock(Session.class); - given(sf.openSession()).willReturn(session); - given(sf.getTransactionManager()).willReturn(tm); - given(session.isOpen()).willReturn(true); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - final HibernateTemplate ht = new HibernateTemplate(sf); - ht.setExposeNativeSession(true); - for (int i = 0; i < 5; i++) { - ht.executeFind(new HibernateCallback() { - - @Override - public Object doInHibernate(org.hibernate.Session sess) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertEquals(session, sess); - return null; - } - }); - } - - final Synchronization synchronization = transaction.getSynchronization(); - assertTrue("JTA synchronization registered", synchronization != null); - Thread thread = new Thread() { - - @Override - public void run() { - synchronization.afterCompletion(Status.STATUS_ROLLEDBACK); - } - }; - thread.start(); - thread.join(); - - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - TransactionTemplate tt = new TransactionTemplate(new JtaTransactionManager(tm)); - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); - tt.setReadOnly(true); - tt.execute(new TransactionCallbackWithoutResult() { - - @Override - protected void doInTransactionWithoutResult(TransactionStatus status) { - assertTrue("JTA synchronizations active", TransactionSynchronizationManager.isSynchronizationActive()); - for (int i = 0; i < 5; i++) { - ht.executeFind(new HibernateCallback() { - - @Override - public Object doInHibernate(org.hibernate.Session sess) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertEquals(session, sess); - return null; - } - }); - } - } - }); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - verify(session).setFlushMode(FlushMode.MANUAL); - verify(session, times(2)).close(); - } - - @Test - @SuppressWarnings("rawtypes") - public void testJtaSessionSynchronizationWithFlushFailure() throws Exception { - - TransactionManager tm = mock(TransactionManager.class); - MockJtaTransaction transaction = new MockJtaTransaction(); - given(tm.getTransaction()).willReturn(transaction); - final HibernateException flushEx = new HibernateException("flush failure"); - final SessionFactoryImplementor sf = mock(SessionFactoryImplementor.class); - final Session session = mock(Session.class); - given(sf.openSession()).willReturn(session); - given(sf.getTransactionManager()).willReturn(tm); - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - willThrow(flushEx).given(session).flush(); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - HibernateTemplate ht = new HibernateTemplate(sf); - ht.setExposeNativeSession(true); - for (int i = 0; i < 5; i++) { - ht.executeFind(new HibernateCallback() { - - @Override - public Object doInHibernate(org.hibernate.Session sess) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertEquals(session, sess); - return null; - } - }); - } - - Synchronization synchronization = transaction.getSynchronization(); - assertTrue("JTA synchronization registered", synchronization != null); - try { - synchronization.beforeCompletion(); - fail("Should have thrown HibernateSystemException"); - } - catch (HibernateSystemException ex) { - assertSame(flushEx, ex.getCause()); - } - synchronization.afterCompletion(Status.STATUS_ROLLEDBACK); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - verify(tm).setRollbackOnly(); - verify(session).close(); - } - - @Test - @SuppressWarnings("rawtypes") - public void testJtaSessionSynchronizationWithSuspendedTransaction() throws Exception { - - TransactionManager tm = mock(TransactionManager.class); - MockJtaTransaction transaction1 = new MockJtaTransaction(); - MockJtaTransaction transaction2 = new MockJtaTransaction(); - given(tm.getTransaction()).willReturn(transaction1, transaction1, transaction2, transaction2, - transaction2); - - final SessionFactoryImplementor sf = mock(SessionFactoryImplementor.class); - final Session session1 = mock(Session.class); - final Session session2 = mock(Session.class); - given(sf.openSession()).willReturn(session1, session2); - given(sf.getTransactionManager()).willReturn(tm); - given(session1.getFlushMode()).willReturn(FlushMode.AUTO); - given(session2.getFlushMode()).willReturn(FlushMode.AUTO); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - HibernateTemplate ht = new HibernateTemplate(sf); - ht.setExposeNativeSession(true); - ht.executeFind(new HibernateCallback() { - - @Override - public Object doInHibernate(org.hibernate.Session sess) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertEquals(session1, sess); - return null; - } - }); - ht.executeFind(new HibernateCallback() { - - @Override - public Object doInHibernate(org.hibernate.Session sess) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertEquals(session2, sess); - return null; - } - }); - - Synchronization synchronization2 = transaction2.getSynchronization(); - assertTrue("JTA synchronization registered", synchronization2 != null); - synchronization2.beforeCompletion(); - synchronization2.afterCompletion(Status.STATUS_COMMITTED); - - Synchronization synchronization1 = transaction1.getSynchronization(); - assertTrue("JTA synchronization registered", synchronization1 != null); - synchronization1.beforeCompletion(); - synchronization1.afterCompletion(Status.STATUS_COMMITTED); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - verify(session1).flush(); - verify(session2).flush(); - verify(session1).close(); - verify(session2).close(); - } - - @Test - @SuppressWarnings("rawtypes") - public void testJtaSessionSynchronizationWithNonSessionFactoryImplementor() throws Exception { - - TransactionManager tm = mock(TransactionManager.class); - MockJtaTransaction transaction = new MockJtaTransaction(); - given(tm.getTransaction()).willReturn(transaction); - final SessionFactory sf = mock(SessionFactory.class); - final Session session = mock(Session.class); - final SessionFactoryImplementor sfi = mock(SessionFactoryImplementor.class); - given(sf.openSession()).willReturn(session); - given(session.getSessionFactory()).willReturn(sfi); - given(sfi.getTransactionManager()).willReturn(tm); - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - HibernateTemplate ht = new HibernateTemplate(sf); - ht.setExposeNativeSession(true); - for (int i = 0; i < 5; i++) { - ht.executeFind(new HibernateCallback() { - - @Override - public Object doInHibernate(org.hibernate.Session sess) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertEquals(session, sess); - return null; - } - }); - } - - Synchronization synchronization = transaction.getSynchronization(); - assertTrue("JTA Synchronization registered", synchronization != null); - synchronization.beforeCompletion(); - synchronization.afterCompletion(Status.STATUS_COMMITTED); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - verify(session).flush(); - verify(session).close(); - } - - @Test - @SuppressWarnings("rawtypes") - public void testJtaSessionSynchronizationWithSpringTransactionLaterOn() throws Exception { - UserTransaction ut = mock(UserTransaction.class); - - TransactionManager tm = mock(TransactionManager.class); - MockJtaTransaction transaction = new MockJtaTransaction(); - given(ut.getStatus()).willReturn(Status.STATUS_ACTIVE); - given(tm.getTransaction()).willReturn(transaction); - final SessionFactoryImplementor sf = mock(SessionFactoryImplementor.class); - final Session session = mock(Session.class); - given(sf.openSession()).willReturn(session); - given(sf.getTransactionManager()).willReturn(tm); - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - final HibernateTemplate ht = new HibernateTemplate(sf); - ht.setExposeNativeSession(true); - for (int i = 0; i < 2; i++) { - ht.executeFind(new HibernateCallback() { - - @Override - public Object doInHibernate(org.hibernate.Session sess) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertEquals(session, sess); - return null; - } - }); - } - - TransactionTemplate tt = new TransactionTemplate(new JtaTransactionManager(ut)); - tt.execute(new TransactionCallbackWithoutResult() { - - @Override - protected void doInTransactionWithoutResult(TransactionStatus status) { - for (int i = 2; i < 5; i++) { - ht.executeFind(new HibernateCallback() { - - @Override - public Object doInHibernate(org.hibernate.Session sess) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertEquals(session, sess); - return null; - } - }); - } - } - }); - - Synchronization synchronization = transaction.getSynchronization(); - assertTrue("JTA synchronization registered", synchronization != null); - synchronization.beforeCompletion(); - synchronization.afterCompletion(Status.STATUS_COMMITTED); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testJtaSessionSynchronizationWithPreBound() throws Exception { - doTestJtaSessionSynchronizationWithPreBound(false); - } - - @Test - public void testJtaJtaSessionSynchronizationWithPreBoundAndFlushNever() throws Exception { - doTestJtaSessionSynchronizationWithPreBound(true); - } - - @SuppressWarnings("rawtypes") - private void doTestJtaSessionSynchronizationWithPreBound(boolean flushNever) throws Exception { - - TransactionManager tm = mock(TransactionManager.class); - MockJtaTransaction transaction = new MockJtaTransaction(); - given(tm.getTransaction()).willReturn(transaction); - final SessionFactoryImplementor sf = mock(SessionFactoryImplementor.class); - final Session session = mock(Session.class); - given(sf.getTransactionManager()).willReturn(tm); - given(session.isOpen()).willReturn(true); - if (flushNever) { - given(session.getFlushMode()).willReturn(FlushMode.MANUAL, FlushMode.AUTO, FlushMode.MANUAL); - } - else { - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - } - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session)); - try { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - HibernateTemplate ht = new HibernateTemplate(sf); - ht.setExposeNativeSession(true); - for (int i = 0; i < 5; i++) { - ht.executeFind(new HibernateCallback() { - - @Override - public Object doInHibernate(org.hibernate.Session sess) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertEquals(session, sess); - return null; - } - }); - } - - Synchronization synchronization = transaction.getSynchronization(); - assertTrue("JTA synchronization registered", synchronization != null); - synchronization.beforeCompletion(); - synchronization.afterCompletion(Status.STATUS_COMMITTED); - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - } - finally { - TransactionSynchronizationManager.unbindResource(sf); - } - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - - InOrder ordered = inOrder(session); - if (flushNever) { - ordered.verify(session).setFlushMode(FlushMode.AUTO); - ordered.verify(session).setFlushMode(FlushMode.MANUAL); - } - else { - ordered.verify(session).flush(); - } - ordered.verify(session).disconnect(); - } - - @Test - @SuppressWarnings("rawtypes") - public void testJtaSessionSynchronizationWithRemoteTransaction() throws Exception { - - TransactionManager tm = mock(TransactionManager.class); - MockJtaTransaction transaction = new MockJtaTransaction(); - final SessionFactoryImplementor sf = mock(SessionFactoryImplementor.class); - final Session session = mock(Session.class); - given(tm.getTransaction()).willReturn(transaction); - given(sf.openSession()).willReturn(session); - given(sf.getTransactionManager()).willReturn(tm); - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - - for (int j = 0; j < 2; j++) { - - if (j == 0) { - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - } - else { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - } - - HibernateTemplate ht = new HibernateTemplate(sf); - ht.setExposeNativeSession(true); - for (int i = 0; i < 5; i++) { - ht.executeFind(new HibernateCallback() { - - @Override - public Object doInHibernate(org.hibernate.Session sess) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertEquals(session, sess); - return null; - } - }); - } - - final Synchronization synchronization = transaction.getSynchronization(); - assertTrue("JTA synchronization registered", synchronization != null); - - // Call synchronization in a new thread, to simulate a - // synchronization - // triggered by a new remote call from a remote transaction - // coordinator. - Thread synch = new Thread() { - - @Override - public void run() { - synchronization.beforeCompletion(); - synchronization.afterCompletion(Status.STATUS_COMMITTED); - } - }; - synch.start(); - synch.join(); - - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); - assertTrue("Thread session holder empty", sessionHolder.isEmpty()); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - } - - verify(session, times(2)).flush(); - verify(session, times(2)).close(); - TransactionSynchronizationManager.unbindResource(sf); - } - - /** - * Interface that combines Hibernate's Session and SessionImplementor - * interface. Necessary for creating a mock that implements both interfaces. - * Note: Hibernate 3.1's SessionImplementor interface does not extend - * Session anymore. - */ - public static interface ExtendedSession extends Session, SessionImplementor { - - } - -} diff --git a/spring-orm/src/test/java/org/springframework/orm/hibernate3/HibernateTemplateTests.java b/spring-orm/src/test/java/org/springframework/orm/hibernate3/HibernateTemplateTests.java deleted file mode 100644 index 25f3de5267..0000000000 --- a/spring-orm/src/test/java/org/springframework/orm/hibernate3/HibernateTemplateTests.java +++ /dev/null @@ -1,1596 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import java.lang.reflect.Proxy; -import java.sql.Connection; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import org.hibernate.Criteria; -import org.hibernate.Filter; -import org.hibernate.FlushMode; -import org.hibernate.HibernateException; -import org.hibernate.Interceptor; -import org.hibernate.JDBCException; -import org.hibernate.LockMode; -import org.hibernate.NonUniqueResultException; -import org.hibernate.ObjectDeletedException; -import org.hibernate.ObjectNotFoundException; -import org.hibernate.PersistentObjectException; -import org.hibernate.PropertyValueException; -import org.hibernate.Query; -import org.hibernate.QueryException; -import org.hibernate.ReplicationMode; -import org.hibernate.SessionFactory; -import org.hibernate.StaleObjectStateException; -import org.hibernate.StaleStateException; -import org.hibernate.TransientObjectException; -import org.hibernate.UnresolvableObjectException; -import org.hibernate.WrongClassException; -import org.hibernate.classic.Session; -import org.hibernate.exception.ConstraintViolationException; -import org.hibernate.exception.DataException; -import org.hibernate.exception.GenericJDBCException; -import org.hibernate.exception.JDBCConnectionException; -import org.hibernate.exception.LockAcquisitionException; -import org.hibernate.exception.SQLGrammarException; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.mockito.InOrder; - -import org.springframework.dao.CannotAcquireLockException; -import org.springframework.dao.DataAccessResourceFailureException; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.dao.IncorrectResultSizeDataAccessException; -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.dao.InvalidDataAccessResourceUsageException; -import org.springframework.tests.sample.beans.TestBean; -import org.springframework.transaction.support.TransactionSynchronizationManager; - -import static org.junit.Assert.*; -import static org.mockito.BDDMockito.*; - -/** - * @author Juergen Hoeller - * @author Phillip Webb - * @since 05.03.2005 - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -@SuppressWarnings({"rawtypes", "unchecked"}) -public class HibernateTemplateTests { - - private SessionFactory sessionFactory; - private Session session; - private HibernateTemplate hibernateTemplate; - - @Before - public void setUp() { - this.sessionFactory = mock(SessionFactory.class); - this.session = mock(Session.class); - this.hibernateTemplate = new HibernateTemplate(sessionFactory); - given(sessionFactory.openSession()).willReturn(session); - given(session.getSessionFactory()).willReturn(sessionFactory); - } - - @After - public void tearDown() { - assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty()); - assertFalse(TransactionSynchronizationManager.isSynchronizationActive()); - } - - @Test - public void testExecuteWithNewSession() throws HibernateException { - assertTrue("Correct allowCreate default", hibernateTemplate.isAllowCreate()); - assertTrue("Correct flushMode default", hibernateTemplate.getFlushMode() == HibernateTemplate.FLUSH_AUTO); - final List l = new ArrayList(); - l.add("test"); - List result = hibernateTemplate.executeFind(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - return l; - } - }); - assertTrue("Correct result list", result == l); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testExecuteWithNewSessionAndFlushNever() throws HibernateException { - hibernateTemplate.setFlushMode(HibernateTemplate.FLUSH_NEVER); - final List l = new ArrayList(); - l.add("test"); - List result = hibernateTemplate.executeFind(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - return l; - } - }); - assertTrue("Correct result list", result == l); - verify(session).setFlushMode(FlushMode.MANUAL); - verify(session).close(); - } - - @Test - public void testExecuteWithNewSessionAndFilter() throws HibernateException { - hibernateTemplate.setFilterName("myFilter"); - final List l = new ArrayList(); - l.add("test"); - List result = hibernateTemplate.executeFind(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - return l; - } - }); - assertTrue("Correct result list", result == l); - verify(session).enableFilter("myFilter"); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testExecuteWithNewSessionAndFilters() throws HibernateException { - hibernateTemplate.setFilterNames(new String[] {"myFilter", "yourFilter"}); - final List l = new ArrayList(); - l.add("test"); - List result = hibernateTemplate.executeFind(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - return l; - } - }); - assertTrue("Correct result list", result == l); - InOrder ordered = inOrder(session); - ordered.verify(session).enableFilter("myFilter"); - ordered.verify(session).enableFilter("yourFilter"); - ordered.verify(session).flush(); - ordered.verify(session).close(); - } - - @Test - public void testExecuteWithNotAllowCreate() { - reset(sessionFactory); - given(sessionFactory.getCurrentSession()).willThrow(new HibernateException("")); - HibernateTemplate ht = new HibernateTemplate(); - ht.setSessionFactory(sessionFactory); - ht.setAllowCreate(false); - try { - ht.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - return null; - } - }); - fail("Should have thrown DataAccessException"); - } - catch (DataAccessResourceFailureException ex) { - // expected - } - } - - @Test - public void testExecuteWithNotAllowCreateAndThreadBound() { - given(sessionFactory.getCurrentSession()).willReturn(session); - hibernateTemplate.setAllowCreate(false); - - final List l = new ArrayList(); - l.add("test"); - List result = hibernateTemplate.executeFind(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - return l; - } - }); - assertTrue("Correct result list", result == l); - } - - @Test - public void testExecuteWithThreadBoundAndFlushEager() throws HibernateException { - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - hibernateTemplate.setFlushModeName("FLUSH_EAGER"); - TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session)); - try { - final List l = new ArrayList(); - l.add("test"); - List result = hibernateTemplate.executeFind(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - return l; - } - }); - assertTrue("Correct result list", result == l); - } - finally { - TransactionSynchronizationManager.unbindResource(sessionFactory); - } - verify(session).flush(); - } - - @Test - public void testExecuteWithThreadBoundAndFilter() { - given(session.isOpen()).willReturn(true); - hibernateTemplate.setFilterName("myFilter"); - - TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session)); - try { - final List l = new ArrayList(); - l.add("test"); - List result = hibernateTemplate.executeFind(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - return l; - } - }); - assertTrue("Correct result list", result == l); - } - finally { - TransactionSynchronizationManager.unbindResource(sessionFactory); - } - InOrder ordered = inOrder(session); - ordered.verify(session).enableFilter("myFilter"); - ordered.verify(session).disableFilter("myFilter"); - } - - @Test - public void testExecuteWithThreadBoundAndFilters() { - given(session.isOpen()).willReturn(true); - hibernateTemplate.setFilterNames(new String[] {"myFilter", "yourFilter"}); - - TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session)); - try { - final List l = new ArrayList(); - l.add("test"); - List result = hibernateTemplate.executeFind(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - return l; - } - }); - assertTrue("Correct result list", result == l); - } - finally { - TransactionSynchronizationManager.unbindResource(sessionFactory); - } - InOrder ordered = inOrder(session); - ordered.verify(session).enableFilter("myFilter"); - ordered.verify(session).enableFilter("yourFilter"); - ordered.verify(session).disableFilter("myFilter"); - ordered.verify(session).disableFilter("yourFilter"); - } - - @Test - public void testExecuteWithThreadBoundAndParameterizedFilter() { - Filter filter = mock(Filter.class); - given(session.isOpen()).willReturn(true); - given(session.enableFilter("myFilter")).willReturn(filter); - hibernateTemplate.setAllowCreate(false); - hibernateTemplate.setFilterName("myFilter"); - - TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session)); - try { - final List l = new ArrayList(); - l.add("test"); - Filter f = hibernateTemplate.enableFilter("myFilter"); - assertTrue("Correct filter", f == filter); - } - finally { - TransactionSynchronizationManager.unbindResource(sessionFactory); - } - InOrder ordered = inOrder(session); - ordered.verify(session).getEnabledFilter("myFilter"); - ordered.verify(session).enableFilter("myFilter"); - } - - @Test - public void testExecuteWithThreadBoundAndParameterizedExistingFilter() { - Filter filter = mock(Filter.class); - given(session.isOpen()).willReturn(true); - given(session.enableFilter("myFilter")).willReturn(filter); - hibernateTemplate.setAllowCreate(false); - hibernateTemplate.setFilterName("myFilter"); - - TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session)); - try { - final List l = new ArrayList(); - l.add("test"); - Filter f = hibernateTemplate.enableFilter("myFilter"); - assertTrue("Correct filter", f == filter); - } - finally { - TransactionSynchronizationManager.unbindResource(sessionFactory); - } - verify(session).getEnabledFilter("myFilter"); - } - - @Test - public void testExecuteWithThreadBoundAndNewSession() throws HibernateException { - Connection con = mock(Connection.class); - Session session2 = mock(Session.class); - given(session2.connection()).willReturn(con); - given(sessionFactory.openSession(con)).willReturn(session); - hibernateTemplate.setAlwaysUseNewSession(true); - - TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session2)); - try { - final List l = new ArrayList(); - l.add("test"); - List result = hibernateTemplate.executeFind(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - return l; - } - }); - assertTrue("Correct result list", result == l); - } - finally { - TransactionSynchronizationManager.unbindResource(sessionFactory); - } - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testExecuteWithThreadBoundAndNewSessionAndEntityInterceptor() throws HibernateException { - Interceptor entityInterceptor = mock(Interceptor.class); - Connection con = mock(Connection.class); - Session session2 = mock(Session.class); - given(session2.connection()).willReturn(con); - given(sessionFactory.openSession(con, entityInterceptor)).willReturn(session); - hibernateTemplate.setAlwaysUseNewSession(true); - hibernateTemplate.setEntityInterceptor(entityInterceptor); - - TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session2)); - try { - final List l = new ArrayList(); - l.add("test"); - List result = hibernateTemplate.executeFind(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - return l; - } - }); - assertTrue("Correct result list", result == l); - } - finally { - TransactionSynchronizationManager.unbindResource(sessionFactory); - } - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testExecuteWithEntityInterceptor() throws HibernateException { - Interceptor entityInterceptor = mock(Interceptor.class); - given(sessionFactory.openSession(entityInterceptor)).willReturn(session); - hibernateTemplate.setEntityInterceptor(entityInterceptor); - final List l = new ArrayList(); - l.add("test"); - List result = hibernateTemplate.executeFind(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - return l; - } - }); - assertTrue("Correct result list", result == l); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testExecuteWithCacheQueries() throws HibernateException { - Query query1 = mock(Query.class); - Query query2 = mock(Query.class); - Criteria criteria = mock(Criteria.class); - given(session.createQuery("some query")).willReturn(query1); - given(query1.setCacheable(true)).willReturn(query1); - given(session.getNamedQuery("some query name")).willReturn(query2); - given(query2.setCacheable(true)).willReturn(query2); - given(session.createCriteria(TestBean.class)).willReturn(criteria); - given(criteria.setCacheable(true)).willReturn(criteria); - - hibernateTemplate.setCacheQueries(true); - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session sess) throws HibernateException { - assertNotSame(session, sess); - assertTrue(Proxy.isProxyClass(sess.getClass())); - sess.createQuery("some query"); - sess.getNamedQuery("some query name"); - sess.createCriteria(TestBean.class); - // should be ignored - sess.close(); - return null; - } - }); - - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testExecuteWithCacheQueriesAndCacheRegion() throws HibernateException { - Query query1 = mock(Query.class); - Query query2 = mock(Query.class); - Criteria criteria = mock(Criteria.class); - given(session.createQuery("some query")).willReturn(query1); - given(query1.setCacheable(true)).willReturn(query1); - given(query1.setCacheRegion("myRegion")).willReturn(query1); - given(session.getNamedQuery("some query name")).willReturn(query2); - given(query2.setCacheable(true)).willReturn(query2); - given(query2.setCacheRegion("myRegion")).willReturn(query2); - given(session.createCriteria(TestBean.class)).willReturn(criteria); - given(criteria.setCacheable(true)).willReturn(criteria); - given(criteria.setCacheRegion("myRegion")).willReturn(criteria); - - hibernateTemplate.setCacheQueries(true); - hibernateTemplate.setQueryCacheRegion("myRegion"); - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session sess) throws HibernateException { - assertNotSame(session, sess); - assertTrue(Proxy.isProxyClass(sess.getClass())); - sess.createQuery("some query"); - sess.getNamedQuery("some query name"); - sess.createCriteria(TestBean.class); - // should be ignored - sess.close(); - return null; - } - }); - - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testExecuteWithCacheQueriesAndCacheRegionAndNativeSession() throws HibernateException { - Query query1 = mock(Query.class); - Query query2 = mock(Query.class); - Criteria criteria = mock(Criteria.class); - - given(session.createQuery("some query")).willReturn(query1); - given(session.getNamedQuery("some query name")).willReturn(query2); - given(session.createCriteria(TestBean.class)).willReturn(criteria); - - hibernateTemplate.setExposeNativeSession(true); - hibernateTemplate.setCacheQueries(true); - hibernateTemplate.setQueryCacheRegion("myRegion"); - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session sess) throws HibernateException { - assertSame(session, sess); - sess.createQuery("some query"); - sess.getNamedQuery("some query name"); - sess.createCriteria(TestBean.class); - return null; - } - }); - - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testExecuteWithFetchSizeAndMaxResults() throws HibernateException { - Query query1 = mock(Query.class); - Query query2 = mock(Query.class); - Criteria criteria = mock(Criteria.class); - - given(session.createQuery("some query")).willReturn(query1); - given(query1.setFetchSize(10)).willReturn(query1); - given(query1.setMaxResults(20)).willReturn(query1); - given(session.getNamedQuery("some query name")).willReturn(query2); - given(query2.setFetchSize(10)).willReturn(query2); - given(query2.setMaxResults(20)).willReturn(query2); - given(session.createCriteria(TestBean.class)).willReturn(criteria); - given(criteria.setFetchSize(10)).willReturn(criteria); - given(criteria.setMaxResults(20)).willReturn(criteria); - - hibernateTemplate.setFetchSize(10); - hibernateTemplate.setMaxResults(20); - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session sess) throws HibernateException { - sess.createQuery("some query"); - sess.getNamedQuery("some query name"); - sess.createCriteria(TestBean.class); - return null; - } - }); - - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testGet() throws HibernateException { - TestBean tb = new TestBean(); - given(session.get(TestBean.class, "")).willReturn(tb); - Object result = hibernateTemplate.get(TestBean.class, ""); - assertTrue("Correct result", result == tb); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testGetWithLockMode() throws HibernateException { - TestBean tb = new TestBean(); - given(session.get(TestBean.class, "", LockMode.UPGRADE_NOWAIT)).willReturn(tb); - Object result = hibernateTemplate.get(TestBean.class, "", LockMode.UPGRADE_NOWAIT); - assertTrue("Correct result", result == tb); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testGetWithEntityName() throws HibernateException { - TestBean tb = new TestBean(); - given(session.get("myEntity", "")).willReturn(tb); - Object result = hibernateTemplate.get("myEntity", ""); - assertTrue("Correct result", result == tb); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testGetWithEntityNameAndLockMode() throws HibernateException { - TestBean tb = new TestBean(); - given(session.get("myEntity", "", LockMode.UPGRADE_NOWAIT)).willReturn(tb); - Object result = hibernateTemplate.get("myEntity", "", LockMode.UPGRADE_NOWAIT); - assertTrue("Correct result", result == tb); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testLoad() throws HibernateException { - TestBean tb = new TestBean(); - given(session.load(TestBean.class, "")).willReturn(tb); - Object result = hibernateTemplate.load(TestBean.class, ""); - assertTrue("Correct result", result == tb); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testLoadWithNotFound() throws HibernateException { - ObjectNotFoundException onfex = new ObjectNotFoundException("id", TestBean.class.getName()); - given(session.load(TestBean.class, "id")).willThrow(onfex); - try { - hibernateTemplate.load(TestBean.class, "id"); - fail("Should have thrown HibernateObjectRetrievalFailureException"); - } - catch (HibernateObjectRetrievalFailureException ex) { - // expected - assertEquals(TestBean.class.getName(), ex.getPersistentClassName()); - assertEquals("id", ex.getIdentifier()); - assertEquals(onfex, ex.getCause()); - } - verify(session).close(); - } - - @Test - public void testLoadWithLockMode() throws HibernateException { - TestBean tb = new TestBean(); - given(session.load(TestBean.class, "", LockMode.UPGRADE)).willReturn(tb); - Object result = hibernateTemplate.load(TestBean.class, "", LockMode.UPGRADE); - assertTrue("Correct result", result == tb); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testLoadWithEntityName() throws HibernateException { - TestBean tb = new TestBean(); - given(session.load("myEntity", "")).willReturn(tb); - Object result = hibernateTemplate.load("myEntity", ""); - assertTrue("Correct result", result == tb); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testLoadWithEntityNameLockMode() throws HibernateException { - TestBean tb = new TestBean(); - given(session.load("myEntity", "", LockMode.UPGRADE)).willReturn(tb); - Object result = hibernateTemplate.load("myEntity", "", LockMode.UPGRADE); - assertTrue("Correct result", result == tb); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testLoadWithObject() throws HibernateException { - TestBean tb = new TestBean(); - hibernateTemplate.load(tb, ""); - verify(session).load(tb, ""); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testLoadAll() throws HibernateException { - Criteria criteria = mock(Criteria.class); - List list = new ArrayList(); - given(session.createCriteria(TestBean.class)).willReturn(criteria); - given(criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)).willReturn(criteria); - given(criteria.list()).willReturn(list); - List result = hibernateTemplate.loadAll(TestBean.class); - assertTrue("Correct result", result == list); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testLoadAllWithCacheable() throws HibernateException { - Criteria criteria = mock(Criteria.class); - List list = new ArrayList(); - given(session.createCriteria(TestBean.class)).willReturn(criteria); - given(criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)).willReturn(criteria); - given(criteria.setCacheable(true)).willReturn(criteria); - given(criteria.list()).willReturn(list); - - hibernateTemplate.setCacheQueries(true); - List result = hibernateTemplate.loadAll(TestBean.class); - assertTrue("Correct result", result == list); - verify(criteria).setCacheable(true); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testLoadAllWithCacheableAndCacheRegion() throws HibernateException { - Criteria criteria = mock(Criteria.class); - List list = new ArrayList(); - given(session.createCriteria(TestBean.class)).willReturn(criteria); - given(criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)).willReturn(criteria); - given(criteria.setCacheable(true)).willReturn(criteria); - given(criteria.setCacheRegion("myCacheRegion")).willReturn(criteria); - given(criteria.list()).willReturn(list); - - hibernateTemplate.setCacheQueries(true); - hibernateTemplate.setQueryCacheRegion("myCacheRegion"); - List result = hibernateTemplate.loadAll(TestBean.class); - assertTrue("Correct result", result == list); - verify(criteria).setCacheable(true); - verify(criteria).setCacheRegion("myCacheRegion"); - verify(session).flush(); - verify(session).close(); - } - - @Test public void testRefresh() throws HibernateException { - TestBean tb = new TestBean(); - hibernateTemplate.refresh(tb); - verify(session).refresh(tb); - verify(session).flush(); - verify(session).close(); - } - - @Test public void testContains() throws HibernateException { - TestBean tb = new TestBean(); - given(session.contains(tb)).willReturn(true); - assertTrue(hibernateTemplate.contains(tb)); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testEvict() throws HibernateException { - TestBean tb = new TestBean(); - hibernateTemplate.evict(tb); - verify(session).evict(tb); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testLock() throws HibernateException { - TestBean tb = new TestBean(); - hibernateTemplate.lock(tb, LockMode.WRITE); - verify(session).lock(tb, LockMode.WRITE); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testLockWithEntityName() throws HibernateException { - TestBean tb = new TestBean(); - hibernateTemplate.lock("myEntity", tb, LockMode.WRITE); - verify(session).lock("myEntity", tb, LockMode.WRITE); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testSave() throws HibernateException { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - given(session.save(tb)).willReturn(0); - assertEquals("Correct return value", hibernateTemplate.save(tb), 0); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testSaveWithEntityName() throws HibernateException { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - given(session.save("myEntity", tb)).willReturn(0); - assertEquals("Correct return value", hibernateTemplate.save("myEntity", tb), 0); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testUpdate() throws HibernateException { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - hibernateTemplate.update(tb); - verify(session).update(tb); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testUpdateWithLockMode() throws HibernateException { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - hibernateTemplate.update(tb, LockMode.UPGRADE); - verify(session).update(tb); - verify(session).lock(tb, LockMode.UPGRADE); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testUpdateWithEntityName() throws HibernateException { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - hibernateTemplate.update("myEntity", tb); - verify(session).update("myEntity", tb); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testUpdateWithEntityNameAndLockMode() throws HibernateException { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - hibernateTemplate.update("myEntity", tb, LockMode.UPGRADE); - verify(session).update("myEntity", tb); - verify(session).lock(tb, LockMode.UPGRADE); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testSaveOrUpdate() throws HibernateException { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - hibernateTemplate.saveOrUpdate(tb); - verify(session).saveOrUpdate(tb); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testSaveOrUpdateWithFlushModeNever() throws HibernateException { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.MANUAL); - try { - hibernateTemplate.saveOrUpdate(tb); - fail("Should have thrown InvalidDataAccessApiUsageException"); - } - catch (InvalidDataAccessApiUsageException ex) { - // expected - } - verify(session).close(); - } - - @Test - public void testSaveOrUpdateWithEntityName() throws HibernateException { - TestBean tb = new TestBean(); - - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - hibernateTemplate.saveOrUpdate("myEntity", tb); - verify(session).saveOrUpdate("myEntity", tb); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testReplicate() throws HibernateException { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - hibernateTemplate.replicate(tb, ReplicationMode.LATEST_VERSION); - verify(session).replicate(tb, ReplicationMode.LATEST_VERSION); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testReplicateWithEntityName() throws HibernateException { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - hibernateTemplate.replicate("myEntity", tb, ReplicationMode.LATEST_VERSION); - verify(session).replicate("myEntity", tb, ReplicationMode.LATEST_VERSION); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testPersist() throws HibernateException { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - hibernateTemplate.persist(tb); - verify(session).persist(tb); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testPersistWithEntityName() throws HibernateException { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - hibernateTemplate.persist("myEntity", tb); - verify(session).persist("myEntity", tb); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testMerge() throws HibernateException { - TestBean tb = new TestBean(); - TestBean tbMerged = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - given(session.merge(tb)).willReturn(tbMerged); - assertSame(tbMerged, hibernateTemplate.merge(tb)); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testMergeWithEntityName() throws HibernateException { - TestBean tb = new TestBean(); - TestBean tbMerged = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - given(session.merge("myEntity", tb)).willReturn(tbMerged); - assertSame(tbMerged, hibernateTemplate.merge("myEntity", tb)); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testDelete() throws HibernateException { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - hibernateTemplate.delete(tb); - verify(session).delete(tb); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testDeleteWithLockMode() throws HibernateException { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - hibernateTemplate.delete(tb, LockMode.UPGRADE); - verify(session).lock(tb, LockMode.UPGRADE); - verify(session).delete(tb); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testDeleteWithEntityName() throws HibernateException { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - hibernateTemplate.delete("myEntity", tb); - verify(session).delete("myEntity", tb); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testDeleteWithEntityNameAndLockMode() throws HibernateException { - TestBean tb = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - hibernateTemplate.delete("myEntity", tb, LockMode.UPGRADE); - verify(session).lock("myEntity", tb, LockMode.UPGRADE); - verify(session).delete("myEntity", tb); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testDeleteAll() throws HibernateException { - TestBean tb1 = new TestBean(); - TestBean tb2 = new TestBean(); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - List tbs = new ArrayList(); - tbs.add(tb1); - tbs.add(tb2); - hibernateTemplate.deleteAll(tbs); - verify(session).delete(same(tb1)); - verify(session).delete(same(tb2)); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testFlush() throws HibernateException { - hibernateTemplate.setFlushMode(HibernateTemplate.FLUSH_NEVER); - hibernateTemplate.flush(); - verify(session).setFlushMode(FlushMode.MANUAL); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testClear() throws HibernateException { - hibernateTemplate.clear(); - verify(session).clear(); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testFind() throws HibernateException { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.createQuery("some query string")).willReturn(query); - given(query.list()).willReturn(list); - List result = hibernateTemplate.find("some query string"); - assertTrue("Correct list", result == list); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testFindWithParameter() throws HibernateException { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.createQuery("some query string")).willReturn(query); - given(query.setParameter(0, "myvalue")).willReturn(query); - given(query.list()).willReturn(list); - List result = hibernateTemplate.find("some query string", "myvalue"); - assertTrue("Correct list", result == list); - verify(query).setParameter(0, "myvalue"); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testFindWithParameters() throws HibernateException { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.createQuery("some query string")).willReturn(query); - given(query.setParameter(0, "myvalue1")).willReturn(query); - given(query.setParameter(1, 2)).willReturn(query); - given(query.list()).willReturn(list); - List result = hibernateTemplate.find("some query string", new Object[] {"myvalue1", 2}); - assertTrue("Correct list", result == list); - verify(query).setParameter(0, "myvalue1"); - verify(query).setParameter(1, 2); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testFindWithNamedParameter() throws HibernateException { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.createQuery("some query string")).willReturn(query); - given(query.setParameter("myparam", "myvalue")).willReturn(query); - given(query.list()).willReturn(list); - List result = hibernateTemplate.findByNamedParam("some query string", "myparam", "myvalue"); - assertTrue("Correct list", result == list); - verify(query).setParameter("myparam", "myvalue"); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testFindWithNamedParameters() throws HibernateException { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.createQuery("some query string")).willReturn(query); - given(query.setParameter("myparam1", "myvalue1")).willReturn(query); - given(query.setParameter("myparam2", 2)).willReturn(query); - given(query.list()).willReturn(list); - List result = hibernateTemplate.findByNamedParam("some query string", - new String[] {"myparam1", "myparam2"}, - new Object[] {"myvalue1", 2}); - assertTrue("Correct list", result == list); - verify(query).setParameter("myparam1", "myvalue1"); - verify(query).setParameter("myparam2", 2); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testFindByValueBean() throws HibernateException { - Query query = mock(Query.class); - TestBean tb = new TestBean(); - List list = new ArrayList(); - given(session.createQuery("some query string")).willReturn(query); - given(query.setProperties(tb)).willReturn(query); - given(query.list()).willReturn(list); - List result = hibernateTemplate.findByValueBean("some query string", tb); - assertTrue("Correct list", result == list); - verify(query).setProperties(tb); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testFindByNamedQuery() throws HibernateException { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.getNamedQuery("some query name")).willReturn(query); - given(query.list()).willReturn(list); - List result = hibernateTemplate.findByNamedQuery("some query name"); - assertTrue("Correct list", result == list); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testFindByNamedQueryWithParameter() throws HibernateException { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.getNamedQuery("some query name")).willReturn(query); - given(query.setParameter(0, "myvalue")).willReturn(query); - given(query.list()).willReturn(list); - List result = hibernateTemplate.findByNamedQuery("some query name", "myvalue"); - assertTrue("Correct list", result == list); - verify(query).setParameter(0, "myvalue"); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testFindByNamedQueryWithParameters() throws HibernateException { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.getNamedQuery("some query name")).willReturn(query); - given(query.setParameter(0, "myvalue1")).willReturn(query); - given(query.setParameter(1, 2)).willReturn(query); - given(query.list()).willReturn(list); - List result = hibernateTemplate.findByNamedQuery("some query name", new Object[] {"myvalue1", 2}); - assertTrue("Correct list", result == list); - verify(query).setParameter(0, "myvalue1"); - verify(query).setParameter(1, 2); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testFindByNamedQueryWithNamedParameter() throws HibernateException { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.getNamedQuery("some query name")).willReturn(query); - given(query.setParameter("myparam", "myvalue")).willReturn(query); - given(query.list()).willReturn(list); - List result = hibernateTemplate.findByNamedQueryAndNamedParam("some query name", "myparam", "myvalue"); - assertTrue("Correct list", result == list); - verify(query).setParameter("myparam", "myvalue"); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testFindByNamedQueryWithNamedParameters() throws HibernateException { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.getNamedQuery("some query name")).willReturn(query); - given(query.setParameter("myparam1", "myvalue1")).willReturn(query); - given(query.setParameter("myparam2", 2)).willReturn(query); - given(query.list()).willReturn(list); - List result = hibernateTemplate.findByNamedQueryAndNamedParam("some query name", - new String[] {"myparam1", "myparam2"}, - new Object[] {"myvalue1", 2}); - assertTrue("Correct list", result == list); - verify(query).setParameter("myparam1", "myvalue1"); - verify(query).setParameter("myparam2", 2); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testFindByNamedQueryAndValueBean() throws HibernateException { - Query query = mock(Query.class); - TestBean tb = new TestBean(); - List list = new ArrayList(); - given(session.getNamedQuery("some query name")).willReturn(query); - given(query.setProperties(tb)).willReturn(query); - given(query.list()).willReturn(list); - List result = hibernateTemplate.findByNamedQueryAndValueBean("some query name", tb); - assertTrue("Correct list", result == list); - verify(query).setProperties(tb); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testFindWithCacheable() throws HibernateException { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.createQuery("some query string")).willReturn(query); - given(query.setCacheable(true)).willReturn(query); - given(query.list()).willReturn(list); - hibernateTemplate.setCacheQueries(true); - List result = hibernateTemplate.find("some query string"); - assertTrue("Correct list", result == list); - verify(query).setCacheable(true); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testFindWithCacheableAndCacheRegion() throws HibernateException { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.createQuery("some query string")).willReturn(query); - given(query.setCacheable(true)).willReturn(query); - given(query.setCacheRegion("myCacheRegion")).willReturn(query); - given(query.list()).willReturn(list); - hibernateTemplate.setCacheQueries(true); - hibernateTemplate.setQueryCacheRegion("myCacheRegion"); - List result = hibernateTemplate.find("some query string"); - assertTrue("Correct list", result == list); - verify(query).setCacheable(true); - verify(query).setCacheRegion("myCacheRegion"); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testFindByNamedQueryWithCacheable() throws HibernateException { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.getNamedQuery("some query name")).willReturn(query); - given(query.setCacheable(true)).willReturn(query); - given(query.list()).willReturn(list); - hibernateTemplate.setCacheQueries(true); - List result = hibernateTemplate.findByNamedQuery("some query name"); - assertTrue("Correct list", result == list); - verify(query).setCacheable(true); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testFindByNamedQueryWithCacheableAndCacheRegion() throws HibernateException { - Query query = mock(Query.class); - List list = new ArrayList(); - given(session.getNamedQuery("some query name")).willReturn(query); - given(query.setCacheable(true)).willReturn(query); - given(query.setCacheRegion("myCacheRegion")).willReturn(query); - given(query.list()).willReturn(list); - hibernateTemplate.setCacheQueries(true); - hibernateTemplate.setQueryCacheRegion("myCacheRegion"); - List result = hibernateTemplate.findByNamedQuery("some query name"); - assertTrue("Correct list", result == list); - verify(query).setCacheable(true); - verify(query).setCacheRegion("myCacheRegion"); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testIterate() throws HibernateException { - Query query = mock(Query.class); - Iterator it = Collections.EMPTY_LIST.iterator(); - given(session.createQuery("some query string")).willReturn(query); - given(query.iterate()).willReturn(it); - Iterator result = hibernateTemplate.iterate("some query string"); - assertTrue("Correct list", result == it); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testIterateWithParameter() throws HibernateException { - Query query = mock(Query.class); - Iterator it = Collections.EMPTY_LIST.iterator(); - given(session.createQuery("some query string")).willReturn(query); - given(query.setParameter(0, "myvalue")).willReturn(query); - given(query.iterate()).willReturn(it); - Iterator result = hibernateTemplate.iterate("some query string", "myvalue"); - assertTrue("Correct list", result == it); - verify(query).setParameter(0, "myvalue"); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testIterateWithParameters() throws HibernateException { - Query query = mock(Query.class); - Iterator it = Collections.EMPTY_LIST.iterator(); - given(session.createQuery("some query string")).willReturn(query); - given(query.setParameter(0, "myvalue1")).willReturn(query); - given(query.setParameter(1, 2)).willReturn(query); - given(query.iterate()).willReturn(it); - Iterator result = hibernateTemplate.iterate("some query string", - new Object[] {"myvalue1", 2}); - assertTrue("Correct list", result == it); - verify(query).setParameter(0, "myvalue1"); - verify(query).setParameter(1, 2); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testBulkUpdate() throws HibernateException { - Query query = mock(Query.class); - given(session.createQuery("some query string")).willReturn(query); - given(query.executeUpdate()).willReturn(5); - int result = hibernateTemplate.bulkUpdate("some query string"); - assertTrue("Correct list", result == 5); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testBulkUpdateWithParameter() throws HibernateException { - Query query = mock(Query.class); - given(session.createQuery("some query string")).willReturn(query); - given(query.setParameter(0, "myvalue")).willReturn(query); - given(query.executeUpdate()).willReturn(5); - int result = hibernateTemplate.bulkUpdate("some query string", "myvalue"); - assertTrue("Correct list", result == 5); - verify(query).setParameter(0, "myvalue"); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testBulkUpdateWithParameters() throws HibernateException { - Query query = mock(Query.class); - given(session.createQuery("some query string")).willReturn(query); - given(query.setParameter(0, "myvalue1")).willReturn(query); - given(query.setParameter(1, 2)).willReturn(query); - given(query.executeUpdate()).willReturn(5); - int result = hibernateTemplate.bulkUpdate("some query string", - new Object[] {"myvalue1", 2}); - assertTrue("Correct list", result == 5); - verify(query).setParameter(0, "myvalue1"); - verify(query).setParameter(1, 2); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testExceptions() throws HibernateException { - SQLException sqlEx = new SQLException("argh", "27"); - - final JDBCConnectionException jcex = new JDBCConnectionException("mymsg", sqlEx); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - throw jcex; - } - }); - fail("Should have thrown DataAccessResourceFailureException"); - } - catch (DataAccessResourceFailureException ex) { - // expected - assertEquals(jcex, ex.getCause()); - assertTrue(ex.getMessage().indexOf("mymsg") != -1); - } - - final SQLGrammarException sgex = new SQLGrammarException("mymsg", sqlEx); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - throw sgex; - } - }); - fail("Should have thrown InvalidDataAccessResourceUsageException"); - } - catch (InvalidDataAccessResourceUsageException ex) { - // expected - assertEquals(sgex, ex.getCause()); - assertTrue(ex.getMessage().indexOf("mymsg") != -1); - } - - final LockAcquisitionException laex = new LockAcquisitionException("mymsg", sqlEx); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - throw laex; - } - }); - fail("Should have thrown CannotAcquireLockException"); - } - catch (CannotAcquireLockException ex) { - // expected - assertEquals(laex, ex.getCause()); - assertTrue(ex.getMessage().indexOf("mymsg") != -1); - } - - final ConstraintViolationException cvex = new ConstraintViolationException("mymsg", sqlEx, "myconstraint"); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - throw cvex; - } - }); - fail("Should have thrown DataIntegrityViolationException"); - } - catch (DataIntegrityViolationException ex) { - // expected - assertEquals(cvex, ex.getCause()); - assertTrue(ex.getMessage().indexOf("mymsg") != -1); - } - - final DataException dex = new DataException("mymsg", sqlEx); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - throw dex; - } - }); - fail("Should have thrown DataIntegrityViolationException"); - } - catch (DataIntegrityViolationException ex) { - // expected - assertEquals(dex, ex.getCause()); - assertTrue(ex.getMessage().indexOf("mymsg") != -1); - } - - final JDBCException jdex = new JDBCException("mymsg", sqlEx); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - throw jdex; - } - }); - fail("Should have thrown HibernateJdbcException"); - } - catch (HibernateJdbcException ex) { - // expected - assertEquals(jdex, ex.getCause()); - assertTrue(ex.getMessage().indexOf("mymsg") != -1); - } - - final PropertyValueException pvex = new PropertyValueException("mymsg", "myentity", "myproperty"); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - throw pvex; - } - }); - fail("Should have thrown DataIntegrityViolationException"); - } - catch (DataIntegrityViolationException ex) { - // expected - assertEquals(pvex, ex.getCause()); - assertTrue(ex.getMessage().indexOf("mymsg") != -1); - } - - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - throw new PersistentObjectException(""); - } - }); - fail("Should have thrown InvalidDataAccessApiUsageException"); - } - catch (InvalidDataAccessApiUsageException ex) { - // expected - } - - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - throw new TransientObjectException(""); - } - }); - fail("Should have thrown InvalidDataAccessApiUsageException"); - } - catch (InvalidDataAccessApiUsageException ex) { - // expected - } - - final ObjectDeletedException odex = new ObjectDeletedException("msg", "id", TestBean.class.getName()); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - throw odex; - } - }); - fail("Should have thrown InvalidDataAccessApiUsageException"); - } - catch (InvalidDataAccessApiUsageException ex) { - // expected - assertEquals(odex, ex.getCause()); - } - - final QueryException qex = new QueryException("msg"); - qex.setQueryString("query"); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - throw qex; - } - }); - fail("Should have thrown InvalidDataAccessResourceUsageException"); - } - catch (HibernateQueryException ex) { - // expected - assertEquals(qex, ex.getCause()); - assertEquals("query", ex.getQueryString()); - } - - final UnresolvableObjectException uoex = new UnresolvableObjectException("id", TestBean.class.getName()); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - throw uoex; - } - }); - fail("Should have thrown HibernateObjectRetrievalFailureException"); - } - catch (HibernateObjectRetrievalFailureException ex) { - // expected - assertEquals(TestBean.class.getName(), ex.getPersistentClassName()); - assertEquals("id", ex.getIdentifier()); - assertEquals(uoex, ex.getCause()); - } - - final ObjectNotFoundException onfe = new ObjectNotFoundException("id", TestBean.class.getName()); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - throw onfe; - } - }); - fail("Should have thrown HibernateObjectRetrievalFailureException"); - } - catch (HibernateObjectRetrievalFailureException ex) { - // expected - assertEquals(TestBean.class.getName(), ex.getPersistentClassName()); - assertEquals("id", ex.getIdentifier()); - assertEquals(onfe, ex.getCause()); - } - - final WrongClassException wcex = new WrongClassException("msg", "id", TestBean.class.getName()); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - throw wcex; - } - }); - fail("Should have thrown HibernateObjectRetrievalFailureException"); - } - catch (HibernateObjectRetrievalFailureException ex) { - // expected - assertEquals(TestBean.class.getName(), ex.getPersistentClassName()); - assertEquals("id", ex.getIdentifier()); - assertEquals(wcex, ex.getCause()); - } - - final NonUniqueResultException nuex = new NonUniqueResultException(2); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - throw nuex; - } - }); - fail("Should have thrown IncorrectResultSizeDataAccessException"); - } - catch (IncorrectResultSizeDataAccessException ex) { - // expected - assertEquals(1, ex.getExpectedSize()); - assertEquals(-1, ex.getActualSize()); - } - - final StaleObjectStateException sosex = new StaleObjectStateException(TestBean.class.getName(), "id"); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - throw sosex; - } - }); - fail("Should have thrown HibernateOptimisticLockingFailureException"); - } - catch (HibernateOptimisticLockingFailureException ex) { - // expected - assertEquals(TestBean.class.getName(), ex.getPersistentClassName()); - assertEquals("id", ex.getIdentifier()); - assertEquals(sosex, ex.getCause()); - } - - final StaleStateException ssex = new StaleStateException("msg"); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - throw ssex; - } - }); - fail("Should have thrown HibernateOptimisticLockingFailureException"); - } - catch (HibernateOptimisticLockingFailureException ex) { - // expected - assertNull(ex.getPersistentClassName()); - assertNull(ex.getIdentifier()); - assertEquals(ssex, ex.getCause()); - } - - final HibernateException hex = new HibernateException("msg"); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - throw hex; - } - }); - fail("Should have thrown HibernateSystemException"); - } - catch (HibernateSystemException ex) { - // expected - assertEquals(hex, ex.getCause()); - } - } - - @Test - public void testFallbackExceptionTranslation() throws HibernateException { - SQLException sqlEx = new SQLException("argh", "27"); - - final GenericJDBCException gjex = new GenericJDBCException("mymsg", sqlEx); - try { - hibernateTemplate.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - throw gjex; - } - }); - fail("Should have thrown DataIntegrityViolationException"); - } - catch (DataIntegrityViolationException ex) { - // expected - assertEquals(sqlEx, ex.getCause()); - assertTrue(ex.getMessage().indexOf("mymsg") != -1); - } - } -} diff --git a/spring-orm/src/test/java/org/springframework/orm/hibernate3/HibernateTransactionManagerTests.java b/spring-orm/src/test/java/org/springframework/orm/hibernate3/HibernateTransactionManagerTests.java deleted file mode 100644 index 22dbecc4c1..0000000000 --- a/spring-orm/src/test/java/org/springframework/orm/hibernate3/HibernateTransactionManagerTests.java +++ /dev/null @@ -1,1441 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.SQLException; -import java.sql.Savepoint; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; -import javax.sql.DataSource; - -import org.hibernate.FlushMode; -import org.hibernate.HibernateException; -import org.hibernate.Interceptor; -import org.hibernate.Query; -import org.hibernate.SessionFactory; -import org.hibernate.Transaction; -import org.hibernate.cache.NoCacheProvider; -import org.hibernate.cfg.Configuration; -import org.hibernate.classic.Session; -import org.hibernate.dialect.HSQLDialect; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.exception.ConstraintViolationException; -import org.hibernate.exception.GenericJDBCException; -import org.junit.After; -import org.junit.Test; -import org.mockito.InOrder; - -import org.springframework.beans.factory.BeanFactory; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.jdbc.datasource.ConnectionHolder; -import org.springframework.jdbc.datasource.DriverManagerDataSource; -import org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy; -import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator; -import org.springframework.transaction.CannotCreateTransactionException; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.TransactionStatus; -import org.springframework.transaction.UnexpectedRollbackException; -import org.springframework.transaction.support.TransactionCallback; -import org.springframework.transaction.support.TransactionCallbackWithoutResult; -import org.springframework.transaction.support.TransactionSynchronizationManager; -import org.springframework.transaction.support.TransactionTemplate; - -import static org.junit.Assert.*; -import static org.mockito.BDDMockito.*; - -/** - * @author Juergen Hoeller - * @author Phillip Webb - * @since 05.03.2005 - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -@SuppressWarnings({"rawtypes", "unchecked"}) -public class HibernateTransactionManagerTests { - - @After - public void tearDown() { - assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty()); - assertFalse(TransactionSynchronizationManager.isSynchronizationActive()); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); - } - - @Test - public void testTransactionCommit() throws Exception { - final DataSource ds = mock(DataSource.class); - Connection con = mock(Connection.class); - final SessionFactory sf = mock(SessionFactory.class); - final Session session = mock(Session.class); - Transaction tx = mock(Transaction.class); - Query query = mock(Query.class); - - final List list = new ArrayList(); - list.add("test"); - given(con.getTransactionIsolation()).willReturn(Connection.TRANSACTION_READ_COMMITTED); - given(sf.openSession()).willReturn(session); - given(session.getTransaction()).willReturn(tx); - given(session.connection()).willReturn(con); - given(session.isOpen()).willReturn(true); - given(session.createQuery("some query string")).willReturn(query); - given(query.list()).willReturn(list); - given(session.isConnected()).willReturn(true); - - LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean() { - @Override - protected SessionFactory newSessionFactory(Configuration config) throws HibernateException { - return sf; - } - }; - lsfb.afterPropertiesSet(); - final SessionFactory sfProxy = lsfb.getObject(); - - HibernateTransactionManager tm = new HibernateTransactionManager(); - tm.setJdbcExceptionTranslator(new SQLStateSQLExceptionTranslator()); - tm.setSessionFactory(sfProxy); - tm.setDataSource(ds); - TransactionTemplate tt = new TransactionTemplate(tm); - tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE); - tt.setTimeout(10); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sfProxy)); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - Object result = tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sfProxy)); - assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); - HibernateTemplate ht = new HibernateTemplate(sfProxy); - return ht.find("some query string"); - } - }); - assertTrue("Correct result list", result == list); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sfProxy)); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - verify(con).setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); - verify(con).setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); - verify(tx).setTimeout(10); - verify(tx).begin(); - verify(tx).commit(); - verify(session).close(); - } - - @Test - public void testTransactionRollback() throws Exception { - Connection con = mock(Connection.class); - final SessionFactory sf = mock(SessionFactory.class); - Session session = mock(Session.class); - Transaction tx = mock(Transaction.class); - - given(sf.openSession()).willReturn(session); - given(session.beginTransaction()).willReturn(tx); - given(session.isOpen()).willReturn(true); - given(session.isConnected()).willReturn(true); - given(session.connection()).willReturn(con); - - PlatformTransactionManager tm = new HibernateTransactionManager(sf); - TransactionTemplate tt = new TransactionTemplate(tm); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - try { - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - HibernateTemplate ht = new HibernateTemplate(sf); - return ht.executeFind(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) { - throw new RuntimeException("application exception"); - } - }); - } - }); - fail("Should have thrown RuntimeException"); - } - catch (RuntimeException ex) { - // expected - } - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - verify(session).close(); - verify(tx).rollback(); - } - - @Test - public void testTransactionRollbackOnly() throws Exception { - Connection con = mock(Connection.class); - final SessionFactory sf = mock(SessionFactory.class); - Session session = mock(Session.class); - Transaction tx = mock(Transaction.class); - - given(sf.openSession()).willReturn(session); - given(session.beginTransaction()).willReturn(tx); - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - given(session.isConnected()).willReturn(true); - given(session.connection()).willReturn(con); - - PlatformTransactionManager tm = new HibernateTransactionManager(sf); - TransactionTemplate tt = new TransactionTemplate(tm); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - HibernateTemplate ht = new HibernateTemplate(sf); - ht.setFlushMode(HibernateTemplate.FLUSH_EAGER); - ht.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) { - return null; - } - }); - status.setRollbackOnly(); - return null; - } - }); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - verify(session).flush(); - verify(session).close(); - verify(tx).rollback(); - } - - @Test - public void testTransactionCommitWithEarlyFlush() throws Exception { - final DataSource ds = mock(DataSource.class); - Connection con = mock(Connection.class); - final SessionFactory sf = mock(SessionFactory.class); - final Session session = mock(Session.class); - Transaction tx = mock(Transaction.class); - Query query = mock(Query.class); - - final List list = new ArrayList(); - list.add("test"); - given(con.getTransactionIsolation()).willReturn(Connection.TRANSACTION_READ_COMMITTED); - given(sf.openSession()).willReturn(session); - given(session.getTransaction()).willReturn(tx); - given(session.connection()).willReturn(con); - given(session.isOpen()).willReturn(true); - given(session.createQuery("some query string")).willReturn(query); - given(query.list()).willReturn(list); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - given(session.isConnected()).willReturn(true); - - LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean() { - @Override - protected SessionFactory newSessionFactory(Configuration config) throws HibernateException { - return sf; - } - }; - lsfb.afterPropertiesSet(); - final SessionFactory sfProxy = lsfb.getObject(); - - HibernateTransactionManager tm = new HibernateTransactionManager(); - tm.setJdbcExceptionTranslator(new SQLStateSQLExceptionTranslator()); - tm.setSessionFactory(sfProxy); - tm.setDataSource(ds); - tm.setEarlyFlushBeforeCommit(true); - TransactionTemplate tt = new TransactionTemplate(tm); - tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE); - tt.setTimeout(10); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sfProxy)); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - Object result = tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sfProxy)); - assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); - HibernateTemplate ht = new HibernateTemplate(sfProxy); - return ht.find("some query string"); - } - }); - assertTrue("Correct result list", result == list); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sfProxy)); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - InOrder ordered = inOrder(con); - ordered.verify(con).setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); - ordered.verify(con).setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); - verify(tx).setTimeout(10); - verify(tx).begin(); - verify(session).flush(); - verify(session).setFlushMode(FlushMode.MANUAL); - verify(tx).commit(); - verify(session).close(); - } - - @Test - public void testParticipatingTransactionWithCommit() throws Exception { - Connection con = mock(Connection.class); - final SessionFactory sf = mock(SessionFactory.class); - final Session session = mock(Session.class); - Transaction tx = mock(Transaction.class); - - given(sf.openSession()).willReturn(session); - given(session.beginTransaction()).willReturn(tx); - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - given(session.isConnected()).willReturn(true); - given(session.connection()).willReturn(con); - - LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean() { - @Override - protected SessionFactory newSessionFactory(Configuration config) throws HibernateException { - return sf; - } - }; - lsfb.afterPropertiesSet(); - final SessionFactory sfProxy = lsfb.getObject(); - - PlatformTransactionManager tm = new HibernateTransactionManager(sfProxy); - final TransactionTemplate tt = new TransactionTemplate(tm); - final List l = new ArrayList(); - l.add("test"); - - Object result = tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - return tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - HibernateTemplate ht = new HibernateTemplate(sfProxy); - ht.setFlushMode(HibernateTemplate.FLUSH_EAGER); - return ht.executeFind(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) { - return l; - } - }); - } - }); - } - }); - assertTrue("Correct result list", result == l); - - verify(session).flush(); - verify(session).close(); - verify(tx).commit(); - } - - @Test - public void testParticipatingTransactionWithRollback() throws Exception { - Connection con = mock(Connection.class); - final SessionFactory sf = mock(SessionFactory.class); - Session session = mock(Session.class); - Transaction tx = mock(Transaction.class); - - given(sf.openSession()).willReturn(session); - given(session.beginTransaction()).willReturn(tx); - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - given(session.isConnected()).willReturn(true); - given(session.connection()).willReturn(con); - - PlatformTransactionManager tm = new HibernateTransactionManager(sf); - final TransactionTemplate tt = new TransactionTemplate(tm); - try { - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - return tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - HibernateTemplate ht = new HibernateTemplate(sf); - ht.setFlushMode(HibernateTemplate.FLUSH_EAGER); - return ht.executeFind(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) { - throw new RuntimeException("application exception"); - } - }); - } - }); - } - }); - fail("Should have thrown RuntimeException"); - } - catch (RuntimeException ex) { - // expected - } - - verify(session).close(); - verify(tx).rollback(); - } - - @Test - public void testParticipatingTransactionWithRollbackOnly() throws Exception { - Connection con = mock(Connection.class); - final SessionFactory sf = mock(SessionFactory.class); - Session session = mock(Session.class); - Transaction tx = mock(Transaction.class); - - given(sf.openSession()).willReturn(session); - given(session.beginTransaction()).willReturn(tx); - given(session.isOpen()).willReturn(true); - given(session.isConnected()).willReturn(true); - given(session.connection()).willReturn(con); - - PlatformTransactionManager tm = new HibernateTransactionManager(sf); - final TransactionTemplate tt = new TransactionTemplate(tm); - final List l = new ArrayList(); - l.add("test"); - - try { - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - return tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - HibernateTemplate ht = new HibernateTemplate(sf); - ht.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) { - return l; - } - }); - status.setRollbackOnly(); - return null; - } - }); - } - }); - fail("Should have thrown UnexpectedRollbackException"); - } - catch (UnexpectedRollbackException ex) { - // expected - } - - verify(session).close(); - verify(tx).rollback(); - } - - @Test - public void testParticipatingTransactionWithRequiresNew() throws Exception { - final SessionFactory sf = mock(SessionFactory.class); - Session session1 = mock(Session.class); - Session session2 = mock(Session.class); - Connection con = mock(Connection.class); - Transaction tx = mock(Transaction.class); - - given(sf.openSession()).willReturn(session1, session2); - given(session1.beginTransaction()).willReturn(tx); - given(session1.isOpen()).willReturn(true); - given(session2.beginTransaction()).willReturn(tx); - given(session2.isOpen()).willReturn(true); - given(session2.getFlushMode()).willReturn(FlushMode.AUTO); - given(session1.isConnected()).willReturn(true); - given(session1.connection()).willReturn(con); - given(session2.isConnected()).willReturn(true); - given(session2.connection()).willReturn(con); - - PlatformTransactionManager tm = new HibernateTransactionManager(sf); - final TransactionTemplate tt = new TransactionTemplate(tm); - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - final SessionHolder holder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); - assertTrue("Has thread session", holder != null); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - HibernateTemplate ht = new HibernateTemplate(sf); - ht.setFlushMode(HibernateTemplate.FLUSH_EAGER); - return ht.executeFind(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) { - assertTrue("Not enclosing session", session != holder.getSession()); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); - return null; - } - }); - } - }); - assertTrue("Same thread session as before", - holder.getSession() == SessionFactoryUtils.getSession(sf, false)); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); - return null; - } - }); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - - verify(session2).flush(); - verify(session1).close(); - verify(session2).close(); - verify(tx, times(2)).commit(); - } - - @Test - public void testParticipatingTransactionWithNotSupported() throws Exception { - final SessionFactory sf = mock(SessionFactory.class); - Session session = mock(Session.class); - Connection con = mock(Connection.class); - Transaction tx = mock(Transaction.class); - - given(sf.openSession()).willReturn(session); - given(session.getSessionFactory()).willReturn(sf); - given(session.beginTransaction()).willReturn(tx); - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(FlushMode.AUTO); - given(session.isConnected()).willReturn(true); - given(session.connection()).willReturn(con); - - HibernateTransactionManager tm = new HibernateTransactionManager(sf); - final TransactionTemplate tt = new TransactionTemplate(tm); - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - SessionHolder holder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); - assertTrue("Has thread session", holder != null); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED); - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); - HibernateTemplate ht = new HibernateTemplate(sf); - ht.setFlushMode(HibernateTemplate.FLUSH_EAGER); - return ht.executeFind(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) { - return null; - } - }); - } - }); - assertTrue("Same thread session as before", - holder.getSession() == SessionFactoryUtils.getSession(sf, false)); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); - return null; - } - }); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - - verify(session, times(2)).flush(); - verify(session, times(2)).close(); - verify(tx).commit(); - } - - @Test - public void testTransactionWithPropagationSupports() throws Exception { - final SessionFactory sf = mock(SessionFactory.class); - final Session session = mock(Session.class); - - given(sf.openSession()).willReturn(session); - given(session.getSessionFactory()).willReturn(sf); - given(session.getFlushMode()).willReturn(FlushMode.MANUAL); - - LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean() { - @Override - protected SessionFactory newSessionFactory(Configuration config) throws HibernateException { - return sf; - } - }; - lsfb.afterPropertiesSet(); - final SessionFactory sfProxy = lsfb.getObject(); - - PlatformTransactionManager tm = new HibernateTransactionManager(sfProxy); - TransactionTemplate tt = new TransactionTemplate(tm); - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sfProxy)); - - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sfProxy)); - assertTrue("Is not new transaction", !status.isNewTransaction()); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); - HibernateTemplate ht = new HibernateTemplate(sfProxy); - ht.setFlushMode(HibernateTemplate.FLUSH_EAGER); - ht.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) { - return null; - } - }); - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sfProxy)); - return null; - } - }); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sfProxy)); - InOrder ordered = inOrder(session); - ordered.verify(session).setFlushMode(FlushMode.AUTO); - ordered.verify(session).flush(); - ordered.verify(session).setFlushMode(FlushMode.MANUAL); - ordered.verify(session).close(); - } - - @Test - public void testTransactionWithPropagationSupportsAndCurrentSession() throws Exception { - final SessionFactoryImplementor sf = mock(SessionFactoryImplementor.class); - final Session session = mock(Session.class); - - given(sf.openSession()).willReturn(session); - given(session.getSessionFactory()).willReturn(sf); - given(session.getFlushMode()).willReturn(FlushMode.MANUAL); - - LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean() { - @Override - protected SessionFactory newSessionFactory(Configuration config) throws HibernateException { - return sf; - } - }; - lsfb.afterPropertiesSet(); - final SessionFactory sfProxy = lsfb.getObject(); - - PlatformTransactionManager tm = new HibernateTransactionManager(sfProxy); - TransactionTemplate tt = new TransactionTemplate(tm); - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sfProxy)); - - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sfProxy)); - assertTrue("Is not new transaction", !status.isNewTransaction()); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); - Session session = new SpringSessionContext(sf).currentSession(); - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sfProxy)); - session.flush(); - return null; - } - }); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sfProxy)); - InOrder ordered = inOrder(session); - ordered.verify(session).flush(); - ordered.verify(session).close(); - } - - @Test - public void testTransactionWithPropagationSupportsAndInnerTransaction() throws Exception { - final SessionFactory sf = mock(SessionFactory.class); - final Session session1 = mock(Session.class); - final Session session2 = mock(Session.class); - Connection con = mock(Connection.class); - Transaction tx = mock(Transaction.class); - - given(sf.openSession()).willReturn(session1, session2); - given(session1.getSessionFactory()).willReturn(sf); - given(session1.getFlushMode()).willReturn(FlushMode.AUTO); - given(session2.beginTransaction()).willReturn(tx); - given(session2.connection()).willReturn(con); - given(session2.getFlushMode()).willReturn(FlushMode.AUTO); - given(session2.isOpen()).willReturn(true); - given(session2.isConnected()).willReturn(true); - - LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean() { - @Override - protected SessionFactory newSessionFactory(Configuration config) throws HibernateException { - return sf; - } - }; - lsfb.afterPropertiesSet(); - final SessionFactory sfProxy = lsfb.getObject(); - - PlatformTransactionManager tm = new HibernateTransactionManager(sfProxy); - TransactionTemplate tt = new TransactionTemplate(tm); - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); - final TransactionTemplate tt2 = new TransactionTemplate(tm); - tt2.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); - - final HibernateTemplate ht = new HibernateTemplate(sfProxy); - ht.setFlushMode(HibernateTemplate.FLUSH_EAGER); - ht.setExposeNativeSession(true); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sfProxy)); - assertTrue("Is not new transaction", !status.isNewTransaction()); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); - ht.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) { - assertSame(session1, session); - return null; - } - }); - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sfProxy)); - tt2.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - return ht.executeFind(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) { - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); - assertSame(session2, session); - return null; - } - }); - } - }); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); - return null; - } - }); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - - verify(session1, times(2)).flush(); - verify(session1).disconnect(); - verify(session1).close(); - verify(session2).flush(); - verify(session2).close(); - verify(tx).commit(); - } - - @Test - public void testTransactionCommitWithEntityInterceptor() throws Exception { - Interceptor entityInterceptor = mock(Interceptor.class); - Connection con = mock(Connection.class); - final SessionFactory sf = mock(SessionFactory.class); - Session session = mock(Session.class); - Transaction tx = mock(Transaction.class); - - given(sf.openSession(entityInterceptor)).willReturn(session); - given(session.beginTransaction()).willReturn(tx); - given(session.isOpen()).willReturn(true); - given(session.isConnected()).willReturn(true); - given(session.connection()).willReturn(con); - - HibernateTransactionManager tm = new HibernateTransactionManager(sf); - tm.setEntityInterceptor(entityInterceptor); - TransactionTemplate tt = new TransactionTemplate(tm); - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - final List l = new ArrayList(); - l.add("test"); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - Object result = tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - HibernateTemplate ht = new HibernateTemplate(sf); - return ht.executeFind(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - return l; - } - }); - } - }); - assertTrue("Correct result list", result == l); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - verify(session).close(); - verify(tx).commit(); - } - - @Test - public void testTransactionCommitWithEntityInterceptorBeanName() throws Exception { - Interceptor entityInterceptor = mock(Interceptor.class); - Interceptor entityInterceptor2 = mock(Interceptor.class); - Connection con = mock(Connection.class); - final SessionFactory sf = mock(SessionFactory.class); - Session session = mock(Session.class); - Transaction tx = mock(Transaction.class); - - given(sf.openSession(entityInterceptor)).willReturn(session); - given(sf.openSession(entityInterceptor2)).willReturn(session); - given(session.beginTransaction()).willReturn(tx); - given(session.isOpen()).willReturn(true); - given(session.isConnected()).willReturn(true); - given(session.connection()).willReturn(con); - - BeanFactory beanFactory = mock(BeanFactory.class); - given(beanFactory.getBean("entityInterceptor", Interceptor.class)).willReturn( - entityInterceptor, entityInterceptor2); - - HibernateTransactionManager tm = new HibernateTransactionManager(sf); - tm.setEntityInterceptorBeanName("entityInterceptor"); - tm.setBeanFactory(beanFactory); - - TransactionTemplate tt = new TransactionTemplate(tm); - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - for (int i = 0; i < 2; i++) { - tt.execute(new TransactionCallbackWithoutResult() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - HibernateTemplate ht = new HibernateTemplate(sf); - ht.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - return null; - } - }); - } - }); - } - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - verify(session, times(2)).close(); - verify(tx, times(2)).commit(); - } - - @Test - public void testTransactionCommitWithReadOnly() throws Exception { - Connection con = mock(Connection.class); - final SessionFactory sf = mock(SessionFactory.class); - Session session = mock(Session.class); - Transaction tx = mock(Transaction.class); - Query query = mock(Query.class); - - final List list = new ArrayList(); - list.add("test"); - given(sf.openSession()).willReturn(session); - given(session.beginTransaction()).willReturn(tx); - given(session.connection()).willReturn(con); - given(session.isOpen()).willReturn(true); - given(session.createQuery("some query string")).willReturn(query); - given(query.list()).willReturn(list); - given(session.isConnected()).willReturn(true); - given(con.isReadOnly()).willReturn(true); - - HibernateTransactionManager tm = new HibernateTransactionManager(sf); - TransactionTemplate tt = new TransactionTemplate(tm); - tt.setReadOnly(true); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - Object result = tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertTrue(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); - HibernateTemplate ht = new HibernateTemplate(sf); - return ht.find("some query string"); - } - }); - assertTrue("Correct result list", result == list); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - verify(session).setFlushMode(FlushMode.MANUAL); - verify(con).setReadOnly(true); - verify(tx).commit(); - verify(con).setReadOnly(false); - verify(session).close(); - } - - @Test - public void testTransactionCommitWithFlushFailure() throws Exception { - doTestTransactionCommitWithFlushFailure(false); - } - - @Test - public void testTransactionCommitWithFlushFailureAndFallbackTranslation() throws Exception { - doTestTransactionCommitWithFlushFailure(true); - } - - private void doTestTransactionCommitWithFlushFailure(boolean fallbackTranslation) throws Exception { - Connection con = mock(Connection.class); - final SessionFactory sf = mock(SessionFactory.class); - Session session = mock(Session.class); - Transaction tx = mock(Transaction.class); - - given(sf.openSession()).willReturn(session); - given(session.beginTransaction()).willReturn(tx); - given(session.isOpen()).willReturn(true); - SQLException sqlEx = new SQLException("argh", "27"); - Exception rootCause = null; - if (fallbackTranslation) { - GenericJDBCException jdbcEx = new GenericJDBCException("mymsg", sqlEx); - rootCause = sqlEx; - willThrow(jdbcEx).given(tx).commit(); - } - else { - ConstraintViolationException jdbcEx = new ConstraintViolationException("mymsg", sqlEx, null); - rootCause = jdbcEx; - willThrow(jdbcEx).given(tx).commit(); - } - given(session.isConnected()).willReturn(true); - given(session.connection()).willReturn(con); - - HibernateTransactionManager tm = new HibernateTransactionManager(sf); - TransactionTemplate tt = new TransactionTemplate(tm); - final List l = new ArrayList(); - l.add("test"); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - try { - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - HibernateTemplate ht = new HibernateTemplate(sf); - return ht.executeFind(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session session) throws HibernateException { - return l; - } - }); - } - }); - fail("Should have thrown DataIntegrityViolationException"); - } - catch (DataIntegrityViolationException ex) { - // expected - assertEquals(rootCause, ex.getCause()); - assertTrue(ex.getMessage().contains("mymsg")); - } - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - verify(session).close(); - verify(tx).rollback(); - } - - @Test - public void testTransactionCommitWithPreBound() throws Exception { - final DataSource ds = mock(DataSource.class); - Connection con = mock(Connection.class); - final SessionFactory sf = mock(SessionFactory.class); - final Session session = mock(Session.class); - Transaction tx = mock(Transaction.class); - - given(session.beginTransaction()).willReturn(tx); - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(FlushMode.MANUAL); - given(session.connection()).willReturn(con); - given(con.getTransactionIsolation()).willReturn(Connection.TRANSACTION_READ_COMMITTED); - given(session.isConnected()).willReturn(true); - - HibernateTransactionManager tm = new HibernateTransactionManager(); - tm.setSessionFactory(sf); - tm.setDataSource(ds); - TransactionTemplate tt = new TransactionTemplate(tm); - tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE); - final List l = new ArrayList(); - l.add("test"); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session)); - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - - Object result = tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); - SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); - assertTrue("Has thread transaction", sessionHolder.getTransaction() != null); - HibernateTemplate ht = new HibernateTemplate(sf); - ht.setExposeNativeSession(true); - return ht.executeFind(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session sess) throws HibernateException { - assertEquals(session, sess); - return l; - } - }); - } - }); - assertTrue("Correct result list", result == l); - - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); - assertTrue("Hasn't thread transaction", sessionHolder.getTransaction() == null); - TransactionSynchronizationManager.unbindResource(sf); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - InOrder ordered = inOrder(session, con); - ordered.verify(con).setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); - ordered.verify(session).setFlushMode(FlushMode.AUTO); - ordered.verify(con).setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); - ordered.verify(session).setFlushMode(FlushMode.MANUAL); - verify(tx).commit(); - verify(session).disconnect(); - } - - @Test - public void testTransactionRollbackWithPreBound() throws Exception { - final DataSource ds = mock(DataSource.class); - Connection con = mock(Connection.class); - final SessionFactory sf = mock(SessionFactory.class); - final Session session = mock(Session.class); - final Transaction tx1 = mock(Transaction.class); - final Transaction tx2 = mock(Transaction.class); - - given(session.beginTransaction()).willReturn(tx1, tx2); - given(session.isOpen()).willReturn(true); - given(session.getFlushMode()).willReturn(FlushMode.MANUAL); - given(session.isConnected()).willReturn(true); - given(session.connection()).willReturn(con); - - HibernateTransactionManager tm = new HibernateTransactionManager(); - tm.setSessionFactory(sf); - tm.setDataSource(ds); - final TransactionTemplate tt = new TransactionTemplate(tm); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session)); - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - - try { - tt.execute(new TransactionCallbackWithoutResult() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); - SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); - assertEquals(tx1, sessionHolder.getTransaction()); - tt.execute(new TransactionCallbackWithoutResult() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - status.setRollbackOnly(); - HibernateTemplate ht = new HibernateTemplate(sf); - ht.setExposeNativeSession(true); - ht.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session sess) throws HibernateException { - assertEquals(session, sess); - return null; - } - }); - } - }); - } - }); - fail("Should have thrown UnexpectedRollbackException"); - } - catch (UnexpectedRollbackException ex) { - // expected - } - - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); - assertTrue("Hasn't thread transaction", sessionHolder.getTransaction() == null); - assertTrue("Not marked rollback-only", !sessionHolder.isRollbackOnly()); - - tt.execute(new TransactionCallbackWithoutResult() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); - SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); - assertEquals(tx2, sessionHolder.getTransaction()); - HibernateTemplate ht = new HibernateTemplate(sf); - ht.setExposeNativeSession(true); - ht.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session sess) throws HibernateException { - assertEquals(session, sess); - return null; - } - }); - } - }); - - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Hasn't thread transaction", sessionHolder.getTransaction() == null); - TransactionSynchronizationManager.unbindResource(sf); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - verify(tx1).rollback(); - verify(tx2).commit(); - InOrder ordered = inOrder(session); - ordered.verify(session).clear(); - ordered.verify(session).setFlushMode(FlushMode.AUTO); - ordered.verify(session).setFlushMode(FlushMode.MANUAL); - ordered.verify(session).disconnect(); - } - - @Test - public void testTransactionRollbackWithHibernateManagedSession() throws Exception { - final SessionFactory sf = mock(SessionFactory.class); - final Session session = mock(Session.class); - final Transaction tx1 = mock(Transaction.class); - final Transaction tx2 = mock(Transaction.class); - - given(sf.getCurrentSession()).willReturn(session); - given(session.isOpen()).willReturn(true); - given(session.getTransaction()).willReturn(tx1, tx2); - given(session.beginTransaction()).willReturn(tx1, tx2); - given(session.getFlushMode()).willReturn(FlushMode.MANUAL); - - HibernateTransactionManager tm = new HibernateTransactionManager(); - tm.setSessionFactory(sf); - tm.setPrepareConnection(false); - tm.setHibernateManagedSession(true); - final TransactionTemplate tt = new TransactionTemplate(tm); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - - try { - tt.execute(new TransactionCallbackWithoutResult() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - tt.execute(new TransactionCallbackWithoutResult() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - status.setRollbackOnly(); - HibernateTemplate ht = new HibernateTemplate(sf); - ht.setAllowCreate(false); - ht.setExposeNativeSession(true); - ht.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session sess) throws HibernateException { - assertEquals(session, sess); - return null; - } - }); - } - }); - } - }); - fail("Should have thrown UnexpectedRollbackException"); - } - catch (UnexpectedRollbackException ex) { - // expected - } - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - - tt.execute(new TransactionCallbackWithoutResult() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - HibernateTemplate ht = new HibernateTemplate(sf); - ht.setAllowCreate(false); - ht.setExposeNativeSession(true); - ht.execute(new HibernateCallback() { - @Override - public Object doInHibernate(org.hibernate.Session sess) throws HibernateException { - assertEquals(session, sess); - return null; - } - }); - } - }); - - verify(tx1).rollback(); - verify(tx2).commit(); - InOrder ordered = inOrder(session); - ordered.verify(session).setFlushMode(FlushMode.AUTO); - ordered.verify(session).setFlushMode(FlushMode.MANUAL); - } - - @Test - public void testExistingTransactionWithPropagationNestedAndRollback() throws Exception { - doTestExistingTransactionWithPropagationNestedAndRollback(false); - } - - @Test - public void testExistingTransactionWithManualSavepointAndRollback() throws Exception { - doTestExistingTransactionWithPropagationNestedAndRollback(true); - } - - private void doTestExistingTransactionWithPropagationNestedAndRollback(final boolean manualSavepoint) - throws Exception { - - final DataSource ds = mock(DataSource.class); - Connection con = mock(Connection.class); - DatabaseMetaData md = mock(DatabaseMetaData.class); - Savepoint sp = mock(Savepoint.class); - final SessionFactory sf = mock(SessionFactory.class); - Session session = mock(Session.class); - Transaction tx = mock(Transaction.class); - Query query = mock(Query.class); - - final List list = new ArrayList(); - list.add("test"); - given(sf.openSession()).willReturn(session); - given(session.beginTransaction()).willReturn(tx); - given(session.connection()).willReturn(con); - given(session.isOpen()).willReturn(true); - given(md.supportsSavepoints()).willReturn(true); - given(con.getMetaData()).willReturn(md); - given(con.setSavepoint(ConnectionHolder.SAVEPOINT_NAME_PREFIX + 1)).willReturn(sp); - given(session.createQuery("some query string")).willReturn(query); - given(query.list()).willReturn(list); - given(session.isConnected()).willReturn(true); - - HibernateTransactionManager tm = new HibernateTransactionManager(); - tm.setJdbcExceptionTranslator(new SQLStateSQLExceptionTranslator()); - tm.setNestedTransactionAllowed(true); - tm.setSessionFactory(sf); - tm.setDataSource(ds); - final TransactionTemplate tt = new TransactionTemplate(tm); - tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - Object result = tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); - if (manualSavepoint) { - Object savepoint = status.createSavepoint(); - status.rollbackToSavepoint(savepoint); - } - else { - tt.execute(new TransactionCallbackWithoutResult() { - @Override - protected void doInTransactionWithoutResult(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); - status.setRollbackOnly(); - } - }); - } - HibernateTemplate ht = new HibernateTemplate(sf); - return ht.find("some query string"); - } - }); - assertTrue("Correct result list", result == list); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - verify(con).setSavepoint(ConnectionHolder.SAVEPOINT_NAME_PREFIX + 1); - verify(con).rollback(sp); - verify(session).close(); - verify(tx).commit(); - } - - @Test - public void testTransactionCommitWithNonExistingDatabase() throws Exception { - final DriverManagerDataSource ds = new DriverManagerDataSource(); - LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean(); - lsfb.setDataSource(ds); - Properties props = new Properties(); - props.setProperty("hibernate.dialect", HSQLDialect.class.getName()); - props.setProperty("hibernate.cache.provider_class", NoCacheProvider.class.getName()); - lsfb.setHibernateProperties(props); - lsfb.afterPropertiesSet(); - final SessionFactory sf = lsfb.getObject(); - - HibernateTransactionManager tm = new HibernateTransactionManager(); - tm.setSessionFactory(sf); - tm.afterPropertiesSet(); - TransactionTemplate tt = new TransactionTemplate(tm); - tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE); - tt.setTimeout(10); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - try { - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); - HibernateTemplate ht = new HibernateTemplate(sf); - return ht.find("from java.lang.Object"); - } - }); - fail("Should have thrown CannotCreateTransactionException"); - } - catch (CannotCreateTransactionException ex) { - // expected - } - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - } - - @Test - public void testTransactionCommitWithPreBoundSessionAndNonExistingDatabase() throws Exception { - final DriverManagerDataSource ds = new DriverManagerDataSource(); - LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean(); - lsfb.setDataSource(ds); - Properties props = new Properties(); - props.setProperty("hibernate.dialect", HSQLDialect.class.getName()); - props.setProperty("hibernate.cache.provider_class", NoCacheProvider.class.getName()); - lsfb.setHibernateProperties(props); - lsfb.afterPropertiesSet(); - final SessionFactory sf = lsfb.getObject(); - - HibernateTransactionManager tm = new HibernateTransactionManager(); - tm.setSessionFactory(sf); - tm.afterPropertiesSet(); - TransactionTemplate tt = new TransactionTemplate(tm); - tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE); - tt.setTimeout(10); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - Session session = sf.openSession(); - TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session)); - try { - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); - HibernateTemplate ht = new HibernateTemplate(sf); - return ht.find("from java.lang.Object"); - } - }); - fail("Should have thrown CannotCreateTransactionException"); - } - catch (CannotCreateTransactionException ex) { - // expected - SessionHolder holder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); - assertFalse(holder.isSynchronizedWithTransaction()); - } - finally { - TransactionSynchronizationManager.unbindResource(sf); - session.close(); - } - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - } - - @Test - public void testTransactionCommitWithNonExistingDatabaseAndLazyConnection() throws Exception { - DriverManagerDataSource dsTarget = new DriverManagerDataSource(); - final LazyConnectionDataSourceProxy ds = new LazyConnectionDataSourceProxy(); - ds.setTargetDataSource(dsTarget); - ds.setDefaultAutoCommit(true); - ds.setDefaultTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); - //ds.setDefaultTransactionIsolationName("TRANSACTION_READ_COMMITTED"); - - LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean(); - lsfb.setDataSource(ds); - Properties props = new Properties(); - props.setProperty("hibernate.dialect", HSQLDialect.class.getName()); - props.setProperty("hibernate.cache.provider_class", NoCacheProvider.class.getName()); - props.setProperty("hibernate.temp.use_jdbc_metadata_defaults", "false"); - lsfb.setHibernateProperties(props); - lsfb.afterPropertiesSet(); - final SessionFactory sf = lsfb.getObject(); - - HibernateTransactionManager tm = new HibernateTransactionManager(); - tm.setSessionFactory(sf); - tm.afterPropertiesSet(); - TransactionTemplate tt = new TransactionTemplate(tm); - tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE); - tt.setTimeout(10); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); - HibernateTemplate ht = new HibernateTemplate(sf); - return ht.find("from java.lang.Object"); - } - }); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - } - - @Test - public void testTransactionFlush() throws Exception { - final SessionFactory sf = mock(SessionFactory.class); - final Session session = mock(Session.class); - Transaction tx = mock(Transaction.class); - - given(sf.openSession()).willReturn(session); - given(session.beginTransaction()).willReturn(tx); - - HibernateTransactionManager tm = new HibernateTransactionManager(sf); - tm.setPrepareConnection(false); - TransactionTemplate tt = new TransactionTemplate(tm); - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - tt.execute(new TransactionCallbackWithoutResult() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); - assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); - assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); - status.flush(); - } - }); - - assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); - assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); - - verify(session).flush(); - verify(tx).commit(); - verify(session).close(); - } - -} diff --git a/spring-orm/src/test/java/org/springframework/orm/hibernate3/LocalSessionFactoryBeanTests.java b/spring-orm/src/test/java/org/springframework/orm/hibernate3/LocalSessionFactoryBeanTests.java deleted file mode 100644 index 0f51dbbf5a..0000000000 --- a/spring-orm/src/test/java/org/springframework/orm/hibernate3/LocalSessionFactoryBeanTests.java +++ /dev/null @@ -1,659 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import javax.transaction.TransactionManager; - -import org.hibernate.HibernateException; -import org.hibernate.Interceptor; -import org.hibernate.SessionFactory; -import org.hibernate.cache.RegionFactory; -import org.hibernate.cache.impl.NoCachingRegionFactory; -import org.hibernate.cfg.Configuration; -import org.hibernate.cfg.Environment; -import org.hibernate.cfg.ImprovedNamingStrategy; -import org.hibernate.cfg.Mappings; -import org.hibernate.cfg.NamingStrategy; -import org.hibernate.connection.UserSuppliedConnectionProvider; -import org.hibernate.engine.FilterDefinition; -import org.hibernate.event.MergeEvent; -import org.hibernate.event.MergeEventListener; -import org.hibernate.mapping.TypeDef; -import org.junit.Test; - -import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.FileSystemResource; -import org.springframework.core.io.Resource; -import org.springframework.jdbc.datasource.DriverManagerDataSource; - -import static org.junit.Assert.*; -import static org.mockito.BDDMockito.*; - -/** - * @author Juergen Hoeller - * @author Phillip Webb - * @since 05.03.2005 - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public class LocalSessionFactoryBeanTests { - - @Test - @SuppressWarnings("serial") - public void testLocalSessionFactoryBeanWithDataSource() throws Exception { - final DriverManagerDataSource ds = new DriverManagerDataSource(); - final List invocations = new ArrayList(); - LocalSessionFactoryBean sfb = new LocalSessionFactoryBean() { - @Override - protected Configuration newConfiguration() { - return new Configuration() { - @Override - public Configuration addInputStream(InputStream is) { - try { - is.close(); - } - catch (IOException ex) { - } - invocations.add("addResource"); - return this; - } - }; - } - @Override - protected SessionFactory newSessionFactory(Configuration config) { - assertEquals(LocalDataSourceConnectionProvider.class.getName(), - config.getProperty(Environment.CONNECTION_PROVIDER)); - assertEquals(ds, LocalSessionFactoryBean.getConfigTimeDataSource()); - invocations.add("newSessionFactory"); - return null; - } - }; - sfb.setDataSource(ds); - sfb.afterPropertiesSet(); - assertTrue(sfb.getConfiguration() != null); - assertEquals("newSessionFactory", invocations.get(0)); - } - - @Test - @SuppressWarnings("serial") - public void testLocalSessionFactoryBeanWithCacheRegionFactory() throws Exception { - final RegionFactory regionFactory = new NoCachingRegionFactory(null); - final List invocations = new ArrayList(); - LocalSessionFactoryBean sfb = new LocalSessionFactoryBean() { - @Override - protected Configuration newConfiguration() { - return new Configuration() { - @Override - public Configuration addInputStream(InputStream is) { - try { - is.close(); - } - catch (IOException ex) { - } - invocations.add("addResource"); - return this; - } - }; - } - @Override - protected SessionFactory newSessionFactory(Configuration config) { - assertEquals(LocalRegionFactoryProxy.class.getName(), - config.getProperty(Environment.CACHE_REGION_FACTORY)); - assertSame(regionFactory, LocalSessionFactoryBean.getConfigTimeRegionFactory()); - invocations.add("newSessionFactory"); - return null; - } - }; - sfb.setCacheRegionFactory(regionFactory); - sfb.afterPropertiesSet(); - assertTrue(sfb.getConfiguration() != null); - assertEquals("newSessionFactory", invocations.get(0)); - } - - @Test - @SuppressWarnings("serial") - public void testLocalSessionFactoryBeanWithTransactionAwareDataSource() throws Exception { - final DriverManagerDataSource ds = new DriverManagerDataSource(); - final List invocations = new ArrayList(); - LocalSessionFactoryBean sfb = new LocalSessionFactoryBean() { - @Override - protected Configuration newConfiguration() { - return new Configuration() { - @Override - public Configuration addInputStream(InputStream is) { - try { - is.close(); - } - catch (IOException ex) { - } - invocations.add("addResource"); - return this; - } - }; - } - - @Override - protected SessionFactory newSessionFactory(Configuration config) { - assertEquals(TransactionAwareDataSourceConnectionProvider.class.getName(), - config.getProperty(Environment.CONNECTION_PROVIDER)); - assertEquals(ds, LocalSessionFactoryBean.getConfigTimeDataSource()); - invocations.add("newSessionFactory"); - return null; - } - }; - sfb.setDataSource(ds); - sfb.setUseTransactionAwareDataSource(true); - sfb.afterPropertiesSet(); - assertTrue(sfb.getConfiguration() != null); - assertEquals("newSessionFactory", invocations.get(0)); - } - - @Test - @SuppressWarnings("serial") - public void testLocalSessionFactoryBeanWithDataSourceAndMappingResources() throws Exception { - final DriverManagerDataSource ds = new DriverManagerDataSource(); - final TransactionManager tm = mock(TransactionManager.class); - final List invocations = new ArrayList(); - LocalSessionFactoryBean sfb = new LocalSessionFactoryBean() { - @Override - protected Configuration newConfiguration() { - return new Configuration() { - @Override - public Configuration addInputStream(InputStream is) { - try { - is.close(); - } - catch (IOException ex) { - } - invocations.add("addResource"); - return this; - } - }; - } - - @Override - protected SessionFactory newSessionFactory(Configuration config) { - assertEquals(LocalJtaDataSourceConnectionProvider.class.getName(), - config.getProperty(Environment.CONNECTION_PROVIDER)); - assertEquals(ds, LocalSessionFactoryBean.getConfigTimeDataSource()); - assertEquals(LocalTransactionManagerLookup.class.getName(), - config.getProperty(Environment.TRANSACTION_MANAGER_STRATEGY)); - assertEquals(tm, LocalSessionFactoryBean.getConfigTimeTransactionManager()); - invocations.add("newSessionFactory"); - return null; - } - }; - sfb.setMappingResources(new String[]{ - "/org/springframework/beans/factory/xml/test.xml", - "/org/springframework/beans/factory/xml/child.xml"}); - sfb.setDataSource(ds); - sfb.setJtaTransactionManager(tm); - sfb.afterPropertiesSet(); - assertTrue(sfb.getConfiguration() != null); - assertEquals("addResource", invocations.get(0)); - assertEquals("addResource", invocations.get(1)); - assertEquals("newSessionFactory", invocations.get(2)); - } - - @Test - @SuppressWarnings("serial") - public void testLocalSessionFactoryBeanWithDataSourceAndMappingJarLocations() throws Exception { - final DriverManagerDataSource ds = new DriverManagerDataSource(); - final Set invocations = new HashSet(); - LocalSessionFactoryBean sfb = new LocalSessionFactoryBean() { - @Override - protected Configuration newConfiguration() { - return new Configuration() { - @Override - public Configuration addJar(File file) { - invocations.add("addResource " + file.getPath()); - return this; - } - }; - } - - @Override - protected SessionFactory newSessionFactory(Configuration config) { - assertEquals(LocalDataSourceConnectionProvider.class.getName(), - config.getProperty(Environment.CONNECTION_PROVIDER)); - assertEquals(ds, LocalSessionFactoryBean.getConfigTimeDataSource()); - invocations.add("newSessionFactory"); - return null; - } - }; - sfb.setMappingJarLocations(new Resource[]{ - new FileSystemResource("mapping.hbm.jar"), new FileSystemResource("mapping2.hbm.jar")}); - sfb.setDataSource(ds); - sfb.afterPropertiesSet(); - assertTrue(sfb.getConfiguration() != null); - assertTrue(invocations.contains("addResource mapping.hbm.jar")); - assertTrue(invocations.contains("addResource mapping2.hbm.jar")); - assertTrue(invocations.contains("newSessionFactory")); - } - - @Test - @SuppressWarnings("serial") - public void testLocalSessionFactoryBeanWithDataSourceAndProperties() throws Exception { - final DriverManagerDataSource ds = new DriverManagerDataSource(); - final Set invocations = new HashSet(); - LocalSessionFactoryBean sfb = new LocalSessionFactoryBean() { - @Override - protected Configuration newConfiguration() { - return new Configuration() { - @Override - public Configuration addInputStream(InputStream is) { - try { - is.close(); - } - catch (IOException ex) { - } - invocations.add("addResource"); - return this; - } - }; - } - - @Override - protected SessionFactory newSessionFactory(Configuration config) { - assertEquals(LocalDataSourceConnectionProvider.class.getName(), - config.getProperty(Environment.CONNECTION_PROVIDER)); - assertEquals(ds, LocalSessionFactoryBean.getConfigTimeDataSource()); - assertEquals("myValue", config.getProperty("myProperty")); - invocations.add("newSessionFactory"); - return null; - } - }; - sfb.setMappingLocations(new Resource[]{ - new ClassPathResource("/org/springframework/beans/factory/xml/test.xml")}); - sfb.setDataSource(ds); - Properties prop = new Properties(); - prop.setProperty(Environment.CONNECTION_PROVIDER, "myClass"); - prop.setProperty("myProperty", "myValue"); - sfb.setHibernateProperties(prop); - sfb.afterPropertiesSet(); - assertTrue(sfb.getConfiguration() != null); - assertTrue(invocations.contains("addResource")); - assertTrue(invocations.contains("newSessionFactory")); - } - - @Test - public void testLocalSessionFactoryBeanWithValidProperties() throws Exception { - final Set invocations = new HashSet(); - LocalSessionFactoryBean sfb = new LocalSessionFactoryBean() { - @Override - protected SessionFactory newSessionFactory(Configuration config) { - assertEquals(UserSuppliedConnectionProvider.class.getName(), - config.getProperty(Environment.CONNECTION_PROVIDER)); - assertEquals("myValue", config.getProperty("myProperty")); - invocations.add("newSessionFactory"); - return null; - } - }; - Properties prop = new Properties(); - prop.setProperty(Environment.CONNECTION_PROVIDER, UserSuppliedConnectionProvider.class.getName()); - prop.setProperty("myProperty", "myValue"); - sfb.setHibernateProperties(prop); - sfb.afterPropertiesSet(); - assertTrue(sfb.getConfiguration() != null); - assertTrue(invocations.contains("newSessionFactory")); - } - - @Test - public void testLocalSessionFactoryBeanWithInvalidProperties() throws Exception { - LocalSessionFactoryBean sfb = new LocalSessionFactoryBean(); - sfb.setMappingResources(new String[0]); - Properties prop = new Properties(); - prop.setProperty(Environment.CONNECTION_PROVIDER, "myClass"); - sfb.setHibernateProperties(prop); - try { - sfb.afterPropertiesSet(); - } - catch (HibernateException ex) { - // expected, provider class not found - } - } - - @Test - public void testLocalSessionFactoryBeanWithInvalidMappings() throws Exception { - LocalSessionFactoryBean sfb = new LocalSessionFactoryBean(); - sfb.setMappingResources(new String[]{"mapping.hbm.xml"}); - try { - sfb.afterPropertiesSet(); - } - catch (IOException ex) { - // expected, mapping resource not found - } - } - - @Test - public void testLocalSessionFactoryBeanWithCustomSessionFactory() throws Exception { - final SessionFactory sessionFactory = mock(SessionFactory.class); - LocalSessionFactoryBean sfb = new LocalSessionFactoryBean() { - @Override - protected SessionFactory newSessionFactory(Configuration config) { - return sessionFactory; - } - }; - sfb.setMappingResources(new String[0]); - sfb.setDataSource(new DriverManagerDataSource()); - sfb.setExposeTransactionAwareSessionFactory(false); - sfb.afterPropertiesSet(); - assertTrue(sessionFactory == sfb.getObject()); - sfb.destroy(); - verify(sessionFactory).close(); - } - - @Test - @SuppressWarnings("serial") - public void testLocalSessionFactoryBeanWithEntityInterceptor() throws Exception { - LocalSessionFactoryBean sfb = new LocalSessionFactoryBean() { - @Override - protected Configuration newConfiguration() { - return new Configuration() { - @Override - public Configuration setInterceptor(Interceptor interceptor) { - throw new IllegalArgumentException(interceptor.toString()); - } - }; - } - }; - sfb.setMappingResources(new String[0]); - sfb.setDataSource(new DriverManagerDataSource()); - Interceptor entityInterceptor = mock(Interceptor.class); - sfb.setEntityInterceptor(entityInterceptor); - try { - sfb.afterPropertiesSet(); - fail("Should have thrown IllegalArgumentException"); - } - catch (IllegalArgumentException ex) { - // expected - assertTrue("Correct exception", ex.getMessage().equals(entityInterceptor.toString())); - } - } - - @Test - @SuppressWarnings("serial") - public void testLocalSessionFactoryBeanWithNamingStrategy() throws Exception { - LocalSessionFactoryBean sfb = new LocalSessionFactoryBean() { - @Override - protected Configuration newConfiguration() { - return new Configuration() { - @Override - public Configuration setNamingStrategy(NamingStrategy namingStrategy) { - throw new IllegalArgumentException(namingStrategy.toString()); - } - }; - } - }; - sfb.setMappingResources(new String[0]); - sfb.setDataSource(new DriverManagerDataSource()); - sfb.setNamingStrategy(ImprovedNamingStrategy.INSTANCE); - try { - sfb.afterPropertiesSet(); - fail("Should have thrown IllegalArgumentException"); - } - catch (IllegalArgumentException ex) { - // expected - assertTrue("Correct exception", ex.getMessage().equals(ImprovedNamingStrategy.INSTANCE.toString())); - } - } - - @Test - @SuppressWarnings("serial") - public void testLocalSessionFactoryBeanWithCacheStrategies() throws Exception { - final Properties registeredClassCache = new Properties(); - final Properties registeredCollectionCache = new Properties(); - LocalSessionFactoryBean sfb = new LocalSessionFactoryBean() { - @Override - protected Configuration newConfiguration() { - return new Configuration() { - @Override - public Configuration setCacheConcurrencyStrategy(String clazz, String concurrencyStrategy) { - registeredClassCache.setProperty(clazz, concurrencyStrategy); - return this; - } - @Override - public Configuration setCollectionCacheConcurrencyStrategy(String collectionRole, String concurrencyStrategy) { - registeredCollectionCache.setProperty(collectionRole, concurrencyStrategy); - return this; - } - }; - } - @Override - protected SessionFactory newSessionFactory(Configuration config) { - return null; - } - }; - - sfb.setMappingResources(new String[0]); - sfb.setDataSource(new DriverManagerDataSource()); - Properties classCache = new Properties(); - classCache.setProperty("org.springframework.tests.sample.beans.TestBean", "read-write"); - sfb.setEntityCacheStrategies(classCache); - Properties collectionCache = new Properties(); - collectionCache.setProperty("org.springframework.tests.sample.beans.TestBean.friends", "read-only"); - sfb.setCollectionCacheStrategies(collectionCache); - sfb.afterPropertiesSet(); - - assertEquals(classCache, registeredClassCache); - assertEquals(collectionCache, registeredCollectionCache); - } - - @Test - @SuppressWarnings("serial") - public void testLocalSessionFactoryBeanWithCacheStrategiesAndRegions() throws Exception { - final Properties registeredClassCache = new Properties(); - final Properties registeredCollectionCache = new Properties(); - LocalSessionFactoryBean sfb = new LocalSessionFactoryBean() { - @Override - protected Configuration newConfiguration() { - return new Configuration() { - @Override - public Configuration setCacheConcurrencyStrategy(String clazz, String concurrencyStrategy, String regionName) { - registeredClassCache.setProperty(clazz, concurrencyStrategy + "," + regionName); - return this; - } - @Override - public void setCollectionCacheConcurrencyStrategy(String collectionRole, String concurrencyStrategy, String regionName) { - registeredCollectionCache.setProperty(collectionRole, concurrencyStrategy + "," + regionName); - } - }; - } - @Override - protected SessionFactory newSessionFactory(Configuration config) { - return null; - } - }; - - sfb.setMappingResources(new String[0]); - sfb.setDataSource(new DriverManagerDataSource()); - Properties classCache = new Properties(); - classCache.setProperty("org.springframework.tests.sample.beans.TestBean", "read-write,myRegion"); - sfb.setEntityCacheStrategies(classCache); - Properties collectionCache = new Properties(); - collectionCache.setProperty("org.springframework.tests.sample.beans.TestBean.friends", "read-only,myRegion"); - sfb.setCollectionCacheStrategies(collectionCache); - sfb.afterPropertiesSet(); - - assertEquals(classCache, registeredClassCache); - assertEquals(collectionCache, registeredCollectionCache); - } - - @Test - @SuppressWarnings("serial") - public void testLocalSessionFactoryBeanWithEventListeners() throws Exception { - final Map registeredListeners = new HashMap(); - LocalSessionFactoryBean sfb = new LocalSessionFactoryBean() { - @Override - protected Configuration newConfiguration() { - return new Configuration() { - @Override - public void setListener(String type, Object listener) { - registeredListeners.put(type, listener); - } - }; - } - @Override - protected SessionFactory newSessionFactory(Configuration config) { - return null; - } - }; - sfb.setMappingResources(new String[0]); - sfb.setDataSource(new DriverManagerDataSource()); - Map listeners = new HashMap(); - listeners.put("flush", "myListener"); - listeners.put("create", "yourListener"); - sfb.setEventListeners(listeners); - sfb.afterPropertiesSet(); - assertEquals(listeners, registeredListeners); - } - - @Test - @SuppressWarnings("serial") - public void testLocalSessionFactoryBeanWithEventListenerSet() throws Exception { - final Map registeredListeners = new HashMap(); - LocalSessionFactoryBean sfb = new LocalSessionFactoryBean() { - @Override - protected Configuration newConfiguration() { - return new Configuration() { - @Override - public void setListeners(String type, Object[] listeners) { - assertTrue(listeners instanceof MergeEventListener[]); - registeredListeners.put(type, new HashSet(Arrays.asList(listeners))); - } - }; - } - @Override - protected SessionFactory newSessionFactory(Configuration config) { - return null; - } - }; - sfb.setMappingResources(new String[0]); - sfb.setDataSource(new DriverManagerDataSource()); - Map listeners = new HashMap(); - Set mergeSet = new HashSet(); - mergeSet.add(new DummyMergeEventListener()); - mergeSet.add(new DummyMergeEventListener()); - listeners.put("merge", mergeSet); - sfb.setEventListeners(listeners); - sfb.afterPropertiesSet(); - assertEquals(listeners, registeredListeners); - } - - /* - @Test - public void testLocalSessionFactoryBeanWithFilterDefinitions() throws Exception { - XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("filterDefinitions.xml", getClass())); - FilterTestLocalSessionFactoryBean sf = (FilterTestLocalSessionFactoryBean) xbf.getBean("&sessionFactory"); - assertEquals(2, sf.registeredFilterDefinitions.size()); - FilterDefinition filter1 = (FilterDefinition) sf.registeredFilterDefinitions.get(0); - FilterDefinition filter2 = (FilterDefinition) sf.registeredFilterDefinitions.get(1); - - assertEquals("filter1", filter1.getFilterName()); - assertEquals(2, filter1.getParameterNames().size()); - assertEquals(Hibernate.STRING, filter1.getParameterType("param1")); - assertEquals(Hibernate.LONG, filter1.getParameterType("otherParam")); - assertEquals("someCondition", filter1.getDefaultFilterCondition()); - - assertEquals("filter2", filter2.getFilterName()); - assertEquals(1, filter2.getParameterNames().size()); - assertEquals(Hibernate.INTEGER, filter2.getParameterType("myParam")); - } - */ - - @Test - public void testLocalSessionFactoryBeanWithTypeDefinitions() throws Exception { - DefaultListableBeanFactory xbf = new DefaultListableBeanFactory(); - new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(new ClassPathResource("typeDefinitions.xml", getClass())); - TypeTestLocalSessionFactoryBean sf = (TypeTestLocalSessionFactoryBean) xbf.getBean("&sessionFactory"); - // Requires re-compilation when switching to Hibernate 3.5/3.6 - // since Mappings changed from a class to an interface - TypeDef type1 = sf.mappings.getTypeDef("type1"); - TypeDef type2 = sf.mappings.getTypeDef("type2"); - - assertEquals("mypackage.MyTypeClass", type1.getTypeClass()); - assertEquals(2, type1.getParameters().size()); - assertEquals("value1", type1.getParameters().getProperty("param1")); - assertEquals("othervalue", type1.getParameters().getProperty("otherParam")); - - assertEquals("mypackage.MyOtherTypeClass", type2.getTypeClass()); - assertEquals(1, type2.getParameters().size()); - assertEquals("myvalue", type2.getParameters().getProperty("myParam")); - } - - - @SuppressWarnings("serial") - public static class FilterTestLocalSessionFactoryBean extends LocalSessionFactoryBean { - - public List registeredFilterDefinitions = new LinkedList(); - - @Override - protected Configuration newConfiguration() throws HibernateException { - return new Configuration() { - @Override - public void addFilterDefinition(FilterDefinition definition) { - registeredFilterDefinitions.add(definition); - } - }; - } - - @Override - protected SessionFactory newSessionFactory(Configuration config) { - return null; - } - } - - - public static class TypeTestLocalSessionFactoryBean extends LocalSessionFactoryBean { - - public Mappings mappings; - - @Override - protected SessionFactory newSessionFactory(Configuration config) { - this.mappings = config.createMappings(); - return null; - } - } - - - @SuppressWarnings("serial") - public static class DummyMergeEventListener implements MergeEventListener { - - @Override - public void onMerge(MergeEvent event) throws HibernateException { - } - - @Override - public void onMerge(MergeEvent event, Map copiedAlready) throws HibernateException { - } - } - -} diff --git a/spring-orm/src/test/java/org/springframework/orm/hibernate3/support/HibernateDaoSupportTests.java b/spring-orm/src/test/java/org/springframework/orm/hibernate3/support/HibernateDaoSupportTests.java deleted file mode 100644 index 8ffe0754e1..0000000000 --- a/spring-orm/src/test/java/org/springframework/orm/hibernate3/support/HibernateDaoSupportTests.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3.support; - -import java.util.ArrayList; -import java.util.List; - -import org.hibernate.SessionFactory; -import org.junit.Test; - -import org.springframework.orm.hibernate3.HibernateTemplate; - -import static org.junit.Assert.*; -import static org.mockito.BDDMockito.*; - -/** - * @author Juergen Hoeller - * @author Phillip Webb - * @since 05.03.2005 - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public class HibernateDaoSupportTests { - - @Test - public void testHibernateDaoSupportWithSessionFactory() throws Exception { - SessionFactory sf = mock(SessionFactory.class); - final List test = new ArrayList(); - HibernateDaoSupport dao = new HibernateDaoSupport() { - @Override - protected void initDao() { - test.add("test"); - } - }; - dao.setSessionFactory(sf); - dao.afterPropertiesSet(); - assertEquals("Correct SessionFactory", sf, dao.getSessionFactory()); - assertEquals("Correct HibernateTemplate", sf, dao.getHibernateTemplate().getSessionFactory()); - assertEquals("initDao called", test.size(), 1); - } - - @Test - public void testHibernateDaoSupportWithHibernateTemplate() throws Exception { - HibernateTemplate template = new HibernateTemplate(); - final List test = new ArrayList(); - HibernateDaoSupport dao = new HibernateDaoSupport() { - @Override - protected void initDao() { - test.add("test"); - } - }; - dao.setHibernateTemplate(template); - dao.afterPropertiesSet(); - assertEquals("Correct HibernateTemplate", template, dao.getHibernateTemplate()); - assertEquals("initDao called", test.size(), 1); - } - -} diff --git a/spring-orm/src/test/java/org/springframework/orm/hibernate3/support/LobTypeTests.java b/spring-orm/src/test/java/org/springframework/orm/hibernate3/support/LobTypeTests.java deleted file mode 100644 index 48a590a6aa..0000000000 --- a/spring-orm/src/test/java/org/springframework/orm/hibernate3/support/LobTypeTests.java +++ /dev/null @@ -1,506 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3.support; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; -import java.util.Arrays; -import java.util.List; -import javax.transaction.Status; -import javax.transaction.Synchronization; -import javax.transaction.TransactionManager; - -import org.hibernate.SessionFactory; -import org.hibernate.classic.Session; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.jdbc.support.lob.LobCreator; -import org.springframework.jdbc.support.lob.LobHandler; -import org.springframework.orm.hibernate3.SessionFactoryUtils; -import org.springframework.tests.transaction.MockJtaTransaction; -import org.springframework.transaction.support.TransactionSynchronization; -import org.springframework.transaction.support.TransactionSynchronizationManager; - -import static org.junit.Assert.*; -import static org.mockito.BDDMockito.*; - -/** - * @author Juergen Hoeller - * @author Phillip Webb - * @since 05.03.2005 - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public class LobTypeTests { - - private ResultSet rs = mock(ResultSet.class); - private PreparedStatement ps = mock(PreparedStatement.class); - private LobHandler lobHandler = mock(LobHandler.class); - private LobCreator lobCreator = mock(LobCreator.class); - - @Before - public void setUp() throws SQLException { - given(lobHandler.getLobCreator()).willReturn(lobCreator); - } - - @After - public void tearDown() { - assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty()); - assertFalse(TransactionSynchronizationManager.isSynchronizationActive()); - verify(lobCreator).close(); - } - - @Test - public void testClobStringType() throws Exception { - given(lobHandler.getClobAsString(rs, "column")).willReturn("content"); - - ClobStringType type = new ClobStringType(lobHandler, null); - assertEquals(1, type.sqlTypes().length); - assertEquals(Types.CLOB, type.sqlTypes()[0]); - assertEquals(String.class, type.returnedClass()); - assertTrue(type.equals("content", "content")); - assertEquals("content", type.deepCopy("content")); - assertFalse(type.isMutable()); - - assertEquals("content", type.nullSafeGet(rs, new String[] {"column"}, null)); - TransactionSynchronizationManager.initSynchronization(); - try { - type.nullSafeSet(ps, "content", 1); - List synchs = TransactionSynchronizationManager.getSynchronizations(); - assertEquals(1, synchs.size()); - assertTrue(synchs.get(0).getClass().getName().endsWith("SpringLobCreatorSynchronization")); - ((TransactionSynchronization) synchs.get(0)).beforeCompletion(); - ((TransactionSynchronization) synchs.get(0)).afterCompletion(TransactionSynchronization.STATUS_COMMITTED); - } - finally { - TransactionSynchronizationManager.clearSynchronization(); - } - verify(lobCreator).setClobAsString(ps, 1, "content"); - } - - @Test - public void testClobStringTypeWithSynchronizedSession() throws Exception { - SessionFactory sf = mock(SessionFactory.class); - Session session = mock(Session.class); - given(sf.openSession()).willReturn(session); - given(session.getSessionFactory()).willReturn(sf); - given(lobHandler.getClobAsString(rs, "column")).willReturn("content"); - - ClobStringType type = new ClobStringType(lobHandler, null); - assertEquals(1, type.sqlTypes().length); - assertEquals(Types.CLOB, type.sqlTypes()[0]); - assertEquals(String.class, type.returnedClass()); - assertTrue(type.equals("content", "content")); - assertEquals("content", type.deepCopy("content")); - assertFalse(type.isMutable()); - - assertEquals("content", type.nullSafeGet(rs, new String[] {"column"}, null)); - TransactionSynchronizationManager.initSynchronization(); - try { - SessionFactoryUtils.getSession(sf, true); - type.nullSafeSet(ps, "content", 1); - List synchs = TransactionSynchronizationManager.getSynchronizations(); - assertEquals(2, synchs.size()); - assertTrue(synchs.get(0).getClass().getName().endsWith("SpringLobCreatorSynchronization")); - ((TransactionSynchronization) synchs.get(0)).beforeCompletion(); - ((TransactionSynchronization) synchs.get(0)).afterCompletion(TransactionSynchronization.STATUS_COMMITTED); - ((TransactionSynchronization) synchs.get(1)).beforeCompletion(); - ((TransactionSynchronization) synchs.get(1)).afterCompletion(TransactionSynchronization.STATUS_COMMITTED); - } - finally { - TransactionSynchronizationManager.clearSynchronization(); - } - - verify(session).close(); - verify(lobCreator).setClobAsString(ps, 1, "content"); - } - - @Test - public void testClobStringTypeWithFlushOnCommit() throws Exception { - given(lobHandler.getClobAsString(rs, "column")).willReturn("content"); - - ClobStringType type = new ClobStringType(lobHandler, null); - assertEquals(1, type.sqlTypes().length); - assertEquals(Types.CLOB, type.sqlTypes()[0]); - assertEquals(String.class, type.returnedClass()); - assertTrue(type.equals("content", "content")); - assertEquals("content", type.deepCopy("content")); - assertFalse(type.isMutable()); - - assertEquals("content", type.nullSafeGet(rs, new String[] {"column"}, null)); - TransactionSynchronizationManager.initSynchronization(); - try { - type.nullSafeSet(ps, "content", 1); - List synchs = TransactionSynchronizationManager.getSynchronizations(); - assertEquals(1, synchs.size()); - ((TransactionSynchronization) synchs.get(0)).afterCompletion(TransactionSynchronization.STATUS_COMMITTED); - } - finally { - TransactionSynchronizationManager.clearSynchronization(); - } - verify(lobCreator).setClobAsString(ps, 1, "content"); - } - - @Test - public void testClobStringTypeWithJtaSynchronization() throws Exception { - TransactionManager tm = mock(TransactionManager.class); - MockJtaTransaction transaction = new MockJtaTransaction(); - given(tm.getStatus()).willReturn(Status.STATUS_ACTIVE); - given(tm.getTransaction()).willReturn(transaction); - - given(lobHandler.getClobAsString(rs, "column")).willReturn("content"); - - ClobStringType type = new ClobStringType(lobHandler, tm); - assertEquals("content", type.nullSafeGet(rs, new String[] {"column"}, null)); - type.nullSafeSet(ps, "content", 1); - Synchronization synch = transaction.getSynchronization(); - assertNotNull(synch); - synch.beforeCompletion(); - synch.afterCompletion(Status.STATUS_COMMITTED); - verify(lobCreator).setClobAsString(ps, 1, "content"); - } - - @Test - public void testClobStringTypeWithJtaSynchronizationAndRollback() throws Exception { - TransactionManager tm = mock(TransactionManager.class); - MockJtaTransaction transaction = new MockJtaTransaction(); - given(tm.getStatus()).willReturn(Status.STATUS_ACTIVE); - given(tm.getTransaction()).willReturn(transaction); - given(lobHandler.getClobAsString(rs, "column")).willReturn("content"); - - ClobStringType type = new ClobStringType(lobHandler, tm); - assertEquals("content", type.nullSafeGet(rs, new String[] {"column"}, null)); - type.nullSafeSet(ps, "content", 1); - Synchronization synch = transaction.getSynchronization(); - assertNotNull(synch); - synch.afterCompletion(Status.STATUS_ROLLEDBACK); - - verify(lobCreator).setClobAsString(ps, 1, "content"); - } - - @Test - public void testBlobStringType() throws Exception { - String content = "content"; - byte[] contentBytes = content.getBytes(); - given(lobHandler.getBlobAsBytes(rs, "column")).willReturn(contentBytes); - - BlobStringType type = new BlobStringType(lobHandler, null); - assertEquals(1, type.sqlTypes().length); - assertEquals(Types.BLOB, type.sqlTypes()[0]); - assertEquals(String.class, type.returnedClass()); - assertTrue(type.equals("content", "content")); - assertEquals("content", type.deepCopy("content")); - assertFalse(type.isMutable()); - - assertEquals(content, type.nullSafeGet(rs, new String[] {"column"}, null)); - TransactionSynchronizationManager.initSynchronization(); - try { - type.nullSafeSet(ps, content, 1); - List synchs = TransactionSynchronizationManager.getSynchronizations(); - assertEquals(1, synchs.size()); - ((TransactionSynchronization) synchs.get(0)).beforeCompletion(); - ((TransactionSynchronization) synchs.get(0)).afterCompletion(TransactionSynchronization.STATUS_COMMITTED); - } - finally { - TransactionSynchronizationManager.clearSynchronization(); - } - verify(lobCreator).setBlobAsBytes(ps, 1, contentBytes); - } - - @Test - public void testBlobStringTypeWithNull() throws Exception { - given(lobHandler.getBlobAsBytes(rs, "column")).willReturn(null); - - BlobStringType type = new BlobStringType(lobHandler, null); - assertEquals(null, type.nullSafeGet(rs, new String[] {"column"}, null)); - TransactionSynchronizationManager.initSynchronization(); - try { - type.nullSafeSet(ps, null, 1); - List synchs = TransactionSynchronizationManager.getSynchronizations(); - assertEquals(1, synchs.size()); - ((TransactionSynchronization) synchs.get(0)).beforeCompletion(); - } - finally { - TransactionSynchronizationManager.clearSynchronization(); - } - - verify(lobCreator).setBlobAsBytes(ps, 1, null); - } - - @Test - public void testBlobStringTypeWithJtaSynchronization() throws Exception { - TransactionManager tm = mock(TransactionManager.class); - MockJtaTransaction transaction = new MockJtaTransaction(); - given(tm.getStatus()).willReturn(Status.STATUS_ACTIVE); - given(tm.getTransaction()).willReturn(transaction); - - String content = "content"; - byte[] contentBytes = content.getBytes(); - given(lobHandler.getBlobAsBytes(rs, "column")).willReturn(contentBytes); - - BlobStringType type = new BlobStringType(lobHandler, tm); - assertEquals(content, type.nullSafeGet(rs, new String[] {"column"}, null)); - type.nullSafeSet(ps, content, 1); - Synchronization synch = transaction.getSynchronization(); - assertNotNull(synch); - synch.beforeCompletion(); - synch.afterCompletion(Status.STATUS_COMMITTED); - - verify(lobCreator).setBlobAsBytes(ps, 1, contentBytes); - } - - @Test - public void testBlobStringTypeWithJtaSynchronizationAndRollback() throws Exception { - TransactionManager tm = mock(TransactionManager.class); - MockJtaTransaction transaction = new MockJtaTransaction(); - given(tm.getStatus()).willReturn(Status.STATUS_ACTIVE); - given(tm.getTransaction()).willReturn(transaction); - - String content = "content"; - byte[] contentBytes = content.getBytes(); - given(lobHandler.getBlobAsBytes(rs, "column")).willReturn(contentBytes); - - BlobStringType type = new BlobStringType(lobHandler, tm); - assertEquals(content, type.nullSafeGet(rs, new String[] {"column"}, null)); - type.nullSafeSet(ps, content, 1); - Synchronization synch = transaction.getSynchronization(); - assertNotNull(synch); - synch.afterCompletion(Status.STATUS_ROLLEDBACK); - verify(lobCreator).setBlobAsBytes(ps, 1, contentBytes); - } - - @Test - public void testBlobByteArrayType() throws Exception { - byte[] content = "content".getBytes(); - given(lobHandler.getBlobAsBytes(rs, "column")).willReturn(content); - - BlobByteArrayType type = new BlobByteArrayType(lobHandler, null); - assertEquals(1, type.sqlTypes().length); - assertEquals(Types.BLOB, type.sqlTypes()[0]); - assertEquals(byte[].class, type.returnedClass()); - assertTrue(type.equals(new byte[] {(byte) 255}, new byte[] {(byte) 255})); - assertTrue(Arrays.equals(new byte[] {(byte) 255}, (byte[]) type.deepCopy(new byte[] {(byte) 255}))); - assertTrue(type.isMutable()); - - assertEquals(content, type.nullSafeGet(rs, new String[] {"column"}, null)); - TransactionSynchronizationManager.initSynchronization(); - try { - type.nullSafeSet(ps, content, 1); - List synchs = TransactionSynchronizationManager.getSynchronizations(); - assertEquals(1, synchs.size()); - ((TransactionSynchronization) synchs.get(0)).beforeCompletion(); - ((TransactionSynchronization) synchs.get(0)).afterCompletion(TransactionSynchronization.STATUS_COMMITTED); - } - finally { - TransactionSynchronizationManager.clearSynchronization(); - } - verify(lobCreator).setBlobAsBytes(ps, 1, content); - } - - @Test - public void testBlobByteArrayTypeWithJtaSynchronization() throws Exception { - TransactionManager tm = mock(TransactionManager.class); - MockJtaTransaction transaction = new MockJtaTransaction(); - given(tm.getStatus()).willReturn(Status.STATUS_ACTIVE); - given(tm.getTransaction()).willReturn(transaction); - - byte[] content = "content".getBytes(); - given(lobHandler.getBlobAsBytes(rs, "column")).willReturn(content); - - BlobByteArrayType type = new BlobByteArrayType(lobHandler, tm); - assertEquals(content, type.nullSafeGet(rs, new String[] {"column"}, null)); - type.nullSafeSet(ps, content, 1); - Synchronization synch = transaction.getSynchronization(); - assertNotNull(synch); - synch.beforeCompletion(); - synch.afterCompletion(Status.STATUS_COMMITTED); - verify(lobCreator).setBlobAsBytes(ps, 1, content); - } - - @Test - public void testBlobByteArrayTypeWithJtaSynchronizationAndRollback() throws Exception { - TransactionManager tm = mock(TransactionManager.class); - MockJtaTransaction transaction = new MockJtaTransaction(); - given(tm.getStatus()).willReturn(Status.STATUS_ACTIVE); - given(tm.getTransaction()).willReturn(transaction); - - byte[] content = "content".getBytes(); - given(lobHandler.getBlobAsBytes(rs, "column")).willReturn(content); - - BlobByteArrayType type = new BlobByteArrayType(lobHandler, tm); - assertEquals(content, type.nullSafeGet(rs, new String[] {"column"}, null)); - type.nullSafeSet(ps, content, 1); - Synchronization synch = transaction.getSynchronization(); - assertNotNull(synch); - synch.afterCompletion(Status.STATUS_ROLLEDBACK); - verify(lobCreator).setBlobAsBytes(ps, 1, content); - } - - @Test - public void testBlobSerializableType() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(baos); - oos.writeObject("content"); - oos.close(); - - given(lobHandler.getBlobAsBinaryStream(rs, "column")).willReturn(new ByteArrayInputStream(baos.toByteArray())); - - BlobSerializableType type = new BlobSerializableType(lobHandler, null); - assertEquals(1, type.sqlTypes().length); - assertEquals(Types.BLOB, type.sqlTypes()[0]); - assertEquals(Serializable.class, type.returnedClass()); - assertTrue(type.isMutable()); - - assertEquals("content", type.nullSafeGet(rs, new String[] {"column"}, null)); - TransactionSynchronizationManager.initSynchronization(); - try { - type.nullSafeSet(ps, "content", 1); - List synchs = TransactionSynchronizationManager.getSynchronizations(); - assertEquals(1, synchs.size()); - ((TransactionSynchronization) synchs.get(0)).beforeCompletion(); - ((TransactionSynchronization) synchs.get(0)).afterCompletion(TransactionSynchronization.STATUS_COMMITTED); - } - finally { - TransactionSynchronizationManager.clearSynchronization(); - } - verify(lobCreator).setBlobAsBytes(ps, 1, baos.toByteArray()); - } - - @Test - public void testBlobSerializableTypeWithNull() throws Exception { - given(lobHandler.getBlobAsBinaryStream(rs, "column")).willReturn(null); - - BlobSerializableType type = new BlobSerializableType(lobHandler, null); - assertEquals(null, type.nullSafeGet(rs, new String[] {"column"}, null)); - TransactionSynchronizationManager.initSynchronization(); - try { - type.nullSafeSet(ps, null, 1); - List synchs = TransactionSynchronizationManager.getSynchronizations(); - assertEquals(1, synchs.size()); - ((TransactionSynchronization) synchs.get(0)).beforeCompletion(); - } - finally { - TransactionSynchronizationManager.clearSynchronization(); - } - verify(lobCreator).setBlobAsBytes(ps, 1, null); - } - - @Test - public void testBlobSerializableTypeWithJtaSynchronization() throws Exception { - TransactionManager tm = mock(TransactionManager.class); - MockJtaTransaction transaction = new MockJtaTransaction(); - given(tm.getStatus()).willReturn(Status.STATUS_ACTIVE); - given(tm.getTransaction()).willReturn(transaction); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(baos); - oos.writeObject("content"); - oos.close(); - - given(lobHandler.getBlobAsBinaryStream(rs, "column")).willReturn( - new ByteArrayInputStream(baos.toByteArray())); - - BlobSerializableType type = new BlobSerializableType(lobHandler, tm); - assertEquals(1, type.sqlTypes().length); - assertEquals(Types.BLOB, type.sqlTypes()[0]); - assertEquals(Serializable.class, type.returnedClass()); - assertTrue(type.isMutable()); - - assertEquals("content", type.nullSafeGet(rs, new String[] {"column"}, null)); - type.nullSafeSet(ps, "content", 1); - Synchronization synch = transaction.getSynchronization(); - assertNotNull(synch); - synch.beforeCompletion(); - synch.afterCompletion(Status.STATUS_COMMITTED); - verify(lobCreator).setBlobAsBytes(ps, 1, baos.toByteArray()); - } - - @Test - public void testBlobSerializableTypeWithJtaSynchronizationAndRollback() throws Exception { - TransactionManager tm = mock(TransactionManager.class); - MockJtaTransaction transaction = new MockJtaTransaction(); - given(tm.getStatus()).willReturn(Status.STATUS_ACTIVE); - given(tm.getTransaction()).willReturn(transaction); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(baos); - oos.writeObject("content"); - oos.close(); - - given(lobHandler.getBlobAsBinaryStream(rs, "column")).willReturn( - new ByteArrayInputStream(baos.toByteArray())); - - BlobSerializableType type = new BlobSerializableType(lobHandler, tm); - assertEquals(1, type.sqlTypes().length); - assertEquals(Types.BLOB, type.sqlTypes()[0]); - assertEquals(Serializable.class, type.returnedClass()); - assertTrue(type.isMutable()); - - assertEquals("content", type.nullSafeGet(rs, new String[] {"column"}, null)); - type.nullSafeSet(ps, "content", 1); - Synchronization synch = transaction.getSynchronization(); - assertNotNull(synch); - synch.afterCompletion(Status.STATUS_ROLLEDBACK); - verify(lobCreator).setBlobAsBytes(ps, 1, baos.toByteArray()); - } - - @Test - public void testHbm2JavaStyleInitialization() throws Exception { - ClobStringType cst = null; - BlobByteArrayType bbat = null; - BlobSerializableType bst = null; - try { - cst = new ClobStringType(); - bbat = new BlobByteArrayType(); - bst = new BlobSerializableType(); - } - catch (Exception ex) { - fail("Should not have thrown exception on initialization"); - } - - try { - cst.nullSafeGet(rs, new String[] {"column"}, null); - fail("Should have thrown IllegalStateException"); - } - catch (IllegalStateException ex) { - // expected - } - try { - bbat.nullSafeGet(rs, new String[] {"column"}, null); - fail("Should have thrown IllegalStateException"); - } - catch (IllegalStateException ex) { - // expected - } - try { - bst.nullSafeGet(rs, new String[] {"column"}, null); - fail("Should have thrown IllegalStateException"); - } - catch (IllegalStateException ex) { - // expected - } - lobCreator.close(); - } -} diff --git a/spring-orm/src/test/java/org/springframework/orm/hibernate3/support/OpenSessionInViewTests.java b/spring-orm/src/test/java/org/springframework/orm/hibernate3/support/OpenSessionInViewTests.java deleted file mode 100644 index e2c379e5b1..0000000000 --- a/spring-orm/src/test/java/org/springframework/orm/hibernate3/support/OpenSessionInViewTests.java +++ /dev/null @@ -1,754 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3.support; - -import java.io.IOException; -import java.sql.Connection; -import java.util.concurrent.Callable; -import java.util.concurrent.atomic.AtomicInteger; -import javax.servlet.AsyncEvent; -import javax.servlet.AsyncListener; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.transaction.TransactionManager; - -import org.hibernate.FlushMode; -import org.hibernate.SessionFactory; -import org.hibernate.Transaction; -import org.hibernate.classic.Session; -import org.hibernate.engine.SessionFactoryImplementor; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.core.task.SimpleAsyncTaskExecutor; -import org.springframework.mock.web.test.MockAsyncContext; -import org.springframework.mock.web.test.MockFilterConfig; -import org.springframework.mock.web.test.MockHttpServletRequest; -import org.springframework.mock.web.test.MockHttpServletResponse; -import org.springframework.mock.web.test.MockServletContext; -import org.springframework.mock.web.test.PassThroughFilterChain; -import org.springframework.orm.hibernate3.HibernateAccessor; -import org.springframework.orm.hibernate3.HibernateTransactionManager; -import org.springframework.orm.hibernate3.SessionFactoryUtils; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.TransactionStatus; -import org.springframework.transaction.support.DefaultTransactionDefinition; -import org.springframework.transaction.support.TransactionSynchronizationManager; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.context.request.ServletWebRequest; -import org.springframework.web.context.request.async.AsyncWebRequest; -import org.springframework.web.context.request.async.StandardServletAsyncWebRequest; -import org.springframework.web.context.request.async.WebAsyncManager; -import org.springframework.web.context.request.async.WebAsyncUtils; -import org.springframework.web.context.support.StaticWebApplicationContext; -import org.springframework.web.util.NestedServletException; - -import static org.junit.Assert.*; -import static org.mockito.BDDMockito.*; - -/** - * @author Juergen Hoeller - * @author Rossen Stoyanchev - * @author Phillip Webb - * @since 05.03.2005 - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public class OpenSessionInViewTests { - - private MockServletContext sc; - - private MockHttpServletRequest request; - - private MockHttpServletResponse response; - - private ServletWebRequest webRequest; - - - @Before - public void setup() { - this.sc = new MockServletContext(); - this.request = new MockHttpServletRequest(sc); - this.request.setAsyncSupported(true); - this.response = new MockHttpServletResponse(); - this.webRequest = new ServletWebRequest(this.request); - } - - @Test - public void testOpenSessionInterceptor() throws Exception { - final SessionFactory sf = mock(SessionFactory.class); - final Session session = mock(Session.class); - - OpenSessionInterceptor interceptor = new OpenSessionInterceptor(); - interceptor.setSessionFactory(sf); - - Runnable tb = new Runnable() { - @Override - public void run() { - assertTrue(TransactionSynchronizationManager.hasResource(sf)); - assertEquals(session, SessionFactoryUtils.getSession(sf, false)); - } - }; - ProxyFactory pf = new ProxyFactory(tb); - pf.addAdvice(interceptor); - Runnable tbProxy = (Runnable) pf.getProxy(); - - given(sf.openSession()).willReturn(session); - given(session.isOpen()).willReturn(true); - tbProxy.run(); - verify(session).setFlushMode(FlushMode.MANUAL); - verify(session).close(); - } - - @Test - public void testOpenSessionInViewInterceptorWithSingleSession() throws Exception { - SessionFactory sf = mock(SessionFactory.class); - Session session = mock(Session.class); - - OpenSessionInViewInterceptor interceptor = new OpenSessionInViewInterceptor(); - interceptor.setSessionFactory(sf); - - given(sf.openSession()).willReturn(session); - given(session.getSessionFactory()).willReturn(sf); - given(session.getSessionFactory()).willReturn(sf); - given(session.isOpen()).willReturn(true); - - interceptor.preHandle(this.webRequest); - assertTrue(TransactionSynchronizationManager.hasResource(sf)); - - // check that further invocations simply participate - interceptor.preHandle(this.webRequest); - assertEquals(session, SessionFactoryUtils.getSession(sf, false)); - - interceptor.preHandle(this.webRequest); - interceptor.postHandle(this.webRequest, null); - interceptor.afterCompletion(this.webRequest, null); - - interceptor.postHandle(this.webRequest, null); - interceptor.afterCompletion(this.webRequest, null); - - interceptor.preHandle(this.webRequest); - interceptor.postHandle(this.webRequest, null); - interceptor.afterCompletion(this.webRequest, null); - - interceptor.postHandle(this.webRequest, null); - assertTrue(TransactionSynchronizationManager.hasResource(sf)); - - interceptor.afterCompletion(this.webRequest, null); - assertFalse(TransactionSynchronizationManager.hasResource(sf)); - - verify(session).setFlushMode(FlushMode.MANUAL); - verify(session).close(); - } - - @Test - public void testOpenSessionInViewInterceptorAsyncScenario() throws Exception { - // Initial request thread - - final SessionFactory sf = mock(SessionFactory.class); - Session session = mock(Session.class); - - OpenSessionInViewInterceptor interceptor = new OpenSessionInViewInterceptor(); - interceptor.setSessionFactory(sf); - - given(sf.openSession()).willReturn(session); - given(session.getSessionFactory()).willReturn(sf); - - interceptor.preHandle(this.webRequest); - assertTrue(TransactionSynchronizationManager.hasResource(sf)); - - AsyncWebRequest asyncWebRequest = new StandardServletAsyncWebRequest(this.request, this.response); - WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(this.request); - asyncManager.setTaskExecutor(new SyncTaskExecutor()); - asyncManager.setAsyncWebRequest(asyncWebRequest); - asyncManager.startCallableProcessing(new Callable() { - @Override - public String call() throws Exception { - return "anything"; - } - }); - - interceptor.afterConcurrentHandlingStarted(this.webRequest); - assertFalse(TransactionSynchronizationManager.hasResource(sf)); - - // Async dispatch thread - - interceptor.preHandle(this.webRequest); - assertTrue("Session not bound to async thread", TransactionSynchronizationManager.hasResource(sf)); - - interceptor.postHandle(this.webRequest, null); - assertTrue(TransactionSynchronizationManager.hasResource(sf)); - - verify(session, never()).close(); - - interceptor.afterCompletion(this.webRequest, null); - assertFalse(TransactionSynchronizationManager.hasResource(sf)); - - verify(session).setFlushMode(FlushMode.MANUAL); - verify(session).close(); - } - - @Test - public void testOpenSessionInViewInterceptorAsyncTimeoutScenario() throws Exception { - // Initial request thread - - final SessionFactory sf = mock(SessionFactory.class); - Session session = mock(Session.class); - - OpenSessionInViewInterceptor interceptor = new OpenSessionInViewInterceptor(); - interceptor.setSessionFactory(sf); - - given(sf.openSession()).willReturn(session); - given(session.getSessionFactory()).willReturn(sf); - - interceptor.preHandle(this.webRequest); - assertTrue(TransactionSynchronizationManager.hasResource(sf)); - - AsyncWebRequest asyncWebRequest = new StandardServletAsyncWebRequest(this.request, this.response); - WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(this.request); - asyncManager.setTaskExecutor(new SyncTaskExecutor()); - asyncManager.setAsyncWebRequest(asyncWebRequest); - asyncManager.startCallableProcessing(new Callable() { - @Override - public String call() throws Exception { - return "anything"; - } - }); - - interceptor.afterConcurrentHandlingStarted(this.webRequest); - assertFalse(TransactionSynchronizationManager.hasResource(sf)); - verify(session, never()).close(); - - // Async request timeout - - MockAsyncContext asyncContext = (MockAsyncContext) this.request.getAsyncContext(); - for (AsyncListener listener : asyncContext.getListeners()) { - listener.onTimeout(new AsyncEvent(asyncContext)); - } - for (AsyncListener listener : asyncContext.getListeners()) { - listener.onComplete(new AsyncEvent(asyncContext)); - } - - verify(session).close(); - } - - @Test - public void testOpenSessionInViewInterceptorWithSingleSessionAndJtaTm() throws Exception { - final SessionFactoryImplementor sf = mock(SessionFactoryImplementor.class); - Session session = mock(Session.class); - - TransactionManager tm = mock(TransactionManager.class); - given(tm.getTransaction()).willReturn(null); - given(tm.getTransaction()).willReturn(null); - - OpenSessionInViewInterceptor interceptor = new OpenSessionInViewInterceptor(); - interceptor.setSessionFactory(sf); - - given(sf.openSession()).willReturn(session); - given(sf.getTransactionManager()).willReturn(tm); - given(sf.getTransactionManager()).willReturn(tm); - given(session.isOpen()).willReturn(true); - - interceptor.preHandle(this.webRequest); - assertTrue(TransactionSynchronizationManager.hasResource(sf)); - - // Check that further invocations simply participate - interceptor.preHandle(this.webRequest); - - assertEquals(session, SessionFactoryUtils.getSession(sf, false)); - - interceptor.preHandle(this.webRequest); - interceptor.postHandle(this.webRequest, null); - interceptor.afterCompletion(this.webRequest, null); - - interceptor.postHandle(this.webRequest, null); - interceptor.afterCompletion(this.webRequest, null); - - interceptor.preHandle(this.webRequest); - interceptor.postHandle(this.webRequest, null); - interceptor.afterCompletion(this.webRequest, null); - - interceptor.postHandle(this.webRequest, null); - assertTrue(TransactionSynchronizationManager.hasResource(sf)); - - interceptor.afterCompletion(this.webRequest, null); - assertFalse(TransactionSynchronizationManager.hasResource(sf)); - - verify(session).setFlushMode(FlushMode.MANUAL); - verify(session).close(); - } - - @Test - public void testOpenSessionInViewInterceptorWithSingleSessionAndFlush() throws Exception { - SessionFactory sf = mock(SessionFactory.class); - Session session = mock(Session.class); - - OpenSessionInViewInterceptor interceptor = new OpenSessionInViewInterceptor(); - interceptor.setSessionFactory(sf); - interceptor.setFlushMode(HibernateAccessor.FLUSH_AUTO); - - given(sf.openSession()).willReturn(session); - given(session.getSessionFactory()).willReturn(sf); - interceptor.preHandle(this.webRequest); - assertTrue(TransactionSynchronizationManager.hasResource(sf)); - - interceptor.postHandle(this.webRequest, null); - assertTrue(TransactionSynchronizationManager.hasResource(sf)); - - interceptor.afterCompletion(this.webRequest, null); - assertFalse(TransactionSynchronizationManager.hasResource(sf)); - verify(session).flush(); - verify(session).close(); - } - - @Test - public void testOpenSessionInViewInterceptorAndDeferredClose() throws Exception { - SessionFactory sf = mock(SessionFactory.class); - Session session = mock(Session.class); - - OpenSessionInViewInterceptor interceptor = new OpenSessionInViewInterceptor(); - interceptor.setSessionFactory(sf); - interceptor.setSingleSession(false); - - given(sf.openSession()).willReturn(session); - given(session.getSessionFactory()).willReturn(sf); - - interceptor.preHandle(this.webRequest); - org.hibernate.Session sess = SessionFactoryUtils.getSession(sf, true); - SessionFactoryUtils.releaseSession(sess, sf); - - // check that further invocations simply participate - interceptor.preHandle(this.webRequest); - - interceptor.preHandle(this.webRequest); - interceptor.postHandle(this.webRequest, null); - interceptor.afterCompletion(this.webRequest, null); - - interceptor.postHandle(this.webRequest, null); - interceptor.afterCompletion(this.webRequest, null); - - interceptor.preHandle(this.webRequest); - interceptor.postHandle(this.webRequest, null); - interceptor.afterCompletion(this.webRequest, null); - - interceptor.postHandle(this.webRequest, null); - interceptor.afterCompletion(this.webRequest, null); - - verify(session).setFlushMode(FlushMode.MANUAL); - verify(session).close(); - } - - @Test - public void testOpenSessionInViewFilterWithSingleSession() throws Exception { - final SessionFactory sf = mock(SessionFactory.class); - Session session = mock(Session.class); - - given(sf.openSession()).willReturn(session); - given(session.getSessionFactory()).willReturn(sf); - given(session.close()).willReturn(null); - - final SessionFactory sf2 = mock(SessionFactory.class); - Session session2 = mock(Session.class); - - given(sf2.openSession()).willReturn(session2); - given(session2.getSessionFactory()).willReturn(sf2); - given(session2.close()).willReturn(null); - - StaticWebApplicationContext wac = new StaticWebApplicationContext(); - wac.setServletContext(sc); - wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf); - wac.getDefaultListableBeanFactory().registerSingleton("mySessionFactory", sf2); - wac.refresh(); - sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); - - MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter"); - MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2"); - filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory"); - filterConfig2.addInitParameter("flushMode", "AUTO"); - - final OpenSessionInViewFilter filter = new OpenSessionInViewFilter(); - filter.init(filterConfig); - final OpenSessionInViewFilter filter2 = new OpenSessionInViewFilter(); - filter2.init(filterConfig2); - - final FilterChain filterChain = new FilterChain() { - @Override - public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) { - assertTrue(TransactionSynchronizationManager.hasResource(sf)); - servletRequest.setAttribute("invoked", Boolean.TRUE); - } - }; - - final FilterChain filterChain2 = new FilterChain() { - @Override - public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) - throws IOException, ServletException { - assertTrue(TransactionSynchronizationManager.hasResource(sf2)); - filter.doFilter(servletRequest, servletResponse, filterChain); - } - }; - - FilterChain filterChain3 = new PassThroughFilterChain(filter2, filterChain2); - - assertFalse(TransactionSynchronizationManager.hasResource(sf)); - assertFalse(TransactionSynchronizationManager.hasResource(sf2)); - filter2.doFilter(this.request, this.response, filterChain3); - assertFalse(TransactionSynchronizationManager.hasResource(sf)); - assertFalse(TransactionSynchronizationManager.hasResource(sf2)); - assertNotNull(this.request.getAttribute("invoked")); - - verify(session).setFlushMode(FlushMode.MANUAL); - verify(session2).setFlushMode(FlushMode.AUTO); - wac.close(); - } - - @Test - public void testOpenSessionInViewFilterAsyncScenario() throws Exception { - final SessionFactory sf = mock(SessionFactory.class); - Session session = mock(Session.class); - - // Initial request during which concurrent handling starts.. - - given(sf.openSession()).willReturn(session); - given(session.getSessionFactory()).willReturn(sf); - - StaticWebApplicationContext wac = new StaticWebApplicationContext(); - wac.setServletContext(sc); - wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf); - wac.refresh(); - sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); - - MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter"); - - final AtomicInteger count = new AtomicInteger(0); - - final OpenSessionInViewFilter filter = new OpenSessionInViewFilter(); - filter.init(filterConfig); - - final FilterChain filterChain = new FilterChain() { - @Override - public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) { - assertTrue(TransactionSynchronizationManager.hasResource(sf)); - count.incrementAndGet(); - } - }; - - AsyncWebRequest asyncWebRequest = new StandardServletAsyncWebRequest(this.request, this.response); - WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(this.request); - asyncManager.setTaskExecutor(new SyncTaskExecutor()); - asyncManager.setAsyncWebRequest(asyncWebRequest); - asyncManager.startCallableProcessing(new Callable() { - @Override - public String call() throws Exception { - return "anything"; - } - }); - - assertFalse(TransactionSynchronizationManager.hasResource(sf)); - filter.doFilter(this.request, this.response, filterChain); - assertFalse(TransactionSynchronizationManager.hasResource(sf)); - assertEquals(1, count.get()); - verify(session, never()).close(); - - // Async dispatch after concurrent handling produces result ... - - this.request.setAsyncStarted(false); - assertFalse(TransactionSynchronizationManager.hasResource(sf)); - filter.doFilter(this.request, this.response, filterChain); - assertFalse(TransactionSynchronizationManager.hasResource(sf)); - assertEquals(2, count.get()); - - verify(session).setFlushMode(FlushMode.MANUAL); - verify(session).close(); - - wac.close(); - } - - @Test - public void testOpenSessionInViewFilterAsyncTimeoutScenario() throws Exception { - final SessionFactory sf = mock(SessionFactory.class); - Session session = mock(Session.class); - - // Initial request during which concurrent handling starts.. - - given(sf.openSession()).willReturn(session); - given(session.getSessionFactory()).willReturn(sf); - - StaticWebApplicationContext wac = new StaticWebApplicationContext(); - wac.setServletContext(sc); - wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf); - wac.refresh(); - sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); - - MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter"); - final OpenSessionInViewFilter filter = new OpenSessionInViewFilter(); - filter.init(filterConfig); - - final AtomicInteger count = new AtomicInteger(0); - final AsyncWebRequest asyncWebRequest = new StandardServletAsyncWebRequest(this.request, this.response); - final MockHttpServletRequest request = this.request; - - final FilterChain filterChain = new FilterChain() { - @Override - public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) - throws NestedServletException { - - assertTrue(TransactionSynchronizationManager.hasResource(sf)); - count.incrementAndGet(); - - WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); - asyncManager.setTaskExecutor(new SyncTaskExecutor()); - asyncManager.setAsyncWebRequest(asyncWebRequest); - try { - asyncManager.startCallableProcessing(new Callable() { - @Override - public String call() throws Exception { - return "anything"; - } - }); - } - catch (Exception e) { - throw new NestedServletException("", e); - } - } - }; - - assertFalse(TransactionSynchronizationManager.hasResource(sf)); - filter.doFilter(this.request, this.response, filterChain); - assertFalse(TransactionSynchronizationManager.hasResource(sf)); - assertEquals(1, count.get()); - verify(session, never()).close(); - - // Async request timeout ... - - MockAsyncContext asyncContext = (MockAsyncContext) this.request.getAsyncContext(); - for (AsyncListener listener : asyncContext.getListeners()) { - listener.onTimeout(new AsyncEvent(asyncContext)); - } - for (AsyncListener listener : asyncContext.getListeners()) { - listener.onComplete(new AsyncEvent(asyncContext)); - } - - verify(session).close(); - - wac.close(); - } - - @Test - public void testOpenSessionInViewFilterWithSingleSessionAndPreBoundSession() throws Exception { - final SessionFactory sf = mock(SessionFactory.class); - Session session = mock(Session.class); - - given(sf.openSession()).willReturn(session); - given(session.getSessionFactory()).willReturn(sf); - - StaticWebApplicationContext wac = new StaticWebApplicationContext(); - wac.setServletContext(sc); - wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf); - wac.refresh(); - sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); - - MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter"); - MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2"); - filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory"); - - OpenSessionInViewInterceptor interceptor = new OpenSessionInViewInterceptor(); - interceptor.setSessionFactory(sf); - - interceptor.preHandle(this.webRequest); - - final OpenSessionInViewFilter filter = new OpenSessionInViewFilter(); - filter.init(filterConfig); - - final FilterChain filterChain = new FilterChain() { - @Override - public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) { - assertTrue(TransactionSynchronizationManager.hasResource(sf)); - servletRequest.setAttribute("invoked", Boolean.TRUE); - } - }; - - assertTrue(TransactionSynchronizationManager.hasResource(sf)); - filter.doFilter(this.request, this.response, filterChain); - assertTrue(TransactionSynchronizationManager.hasResource(sf)); - assertNotNull(this.request.getAttribute("invoked")); - - interceptor.postHandle(this.webRequest, null); - interceptor.afterCompletion(this.webRequest, null); - - verify(session).setFlushMode(FlushMode.MANUAL); - verify(session).close(); - - wac.close(); - } - - @Test - public void testOpenSessionInViewFilterWithDeferredClose() throws Exception { - final SessionFactory sf = mock(SessionFactory.class); - final Session session = mock(Session.class); - - given(sf.openSession()).willReturn(session); - given(session.getSessionFactory()).willReturn(sf); - given(session.getFlushMode()).willReturn(FlushMode.MANUAL); - - final SessionFactory sf2 = mock(SessionFactory.class); - final Session session2 = mock(Session.class); - - Transaction tx = mock(Transaction.class); - Connection con = mock(Connection.class); - - given(sf2.openSession()).willReturn(session2); - given(session2.connection()).willReturn(con); - given(session2.beginTransaction()).willReturn(tx); - given(session2.isConnected()).willReturn(true); - given(session2.connection()).willReturn(con); - - StaticWebApplicationContext wac = new StaticWebApplicationContext(); - wac.setServletContext(sc); - wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf); - wac.getDefaultListableBeanFactory().registerSingleton("mySessionFactory", sf2); - wac.refresh(); - sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); - - MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter"); - MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2"); - filterConfig.addInitParameter("singleSession", "false"); - filterConfig2.addInitParameter("singleSession", "false"); - filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory"); - - final OpenSessionInViewFilter filter = new OpenSessionInViewFilter(); - filter.init(filterConfig); - final OpenSessionInViewFilter filter2 = new OpenSessionInViewFilter(); - filter2.init(filterConfig2); - - final FilterChain filterChain = new FilterChain() { - @Override - public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) { - HibernateTransactionManager tm = new HibernateTransactionManager(sf); - TransactionStatus ts = tm.getTransaction( - new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_SUPPORTS)); - org.hibernate.Session sess = SessionFactoryUtils.getSession(sf, true); - SessionFactoryUtils.releaseSession(sess, sf); - tm.commit(ts); - servletRequest.setAttribute("invoked", Boolean.TRUE); - } - }; - - final FilterChain filterChain2 = new FilterChain() { - @Override - public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) - throws IOException, ServletException { - HibernateTransactionManager tm = new HibernateTransactionManager(sf2); - TransactionStatus ts = tm.getTransaction(new DefaultTransactionDefinition()); - tm.commit(ts); - filter.doFilter(servletRequest, servletResponse, filterChain); - } - }; - - FilterChain filterChain3 = new PassThroughFilterChain(filter2, filterChain2); - - filter2.doFilter(this.request, this.response, filterChain3); - assertNotNull(this.request.getAttribute("invoked")); - - verify(session).setFlushMode(FlushMode.MANUAL); - verify(tx).commit(); - verify(session2).setFlushMode(FlushMode.MANUAL); - verify(session).close(); - verify(session2).close(); - - wac.close(); - } - - @Test - public void testOpenSessionInViewFilterWithDeferredCloseAndAlreadyActiveDeferredClose() throws Exception { - final SessionFactory sf = mock(SessionFactory.class); - final Session session = mock(Session.class); - - given(sf.openSession()).willReturn(session); - given(session.getSessionFactory()).willReturn(sf); - given(session.getFlushMode()).willReturn(FlushMode.MANUAL); - - StaticWebApplicationContext wac = new StaticWebApplicationContext(); - wac.setServletContext(sc); - wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf); - wac.refresh(); - sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); - - MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter"); - MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2"); - filterConfig.addInitParameter("singleSession", "false"); - filterConfig2.addInitParameter("singleSession", "false"); - filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory"); - - OpenSessionInViewInterceptor interceptor = new OpenSessionInViewInterceptor(); - interceptor.setSessionFactory(sf); - interceptor.setSingleSession(false); - - interceptor.preHandle(webRequest); - - final OpenSessionInViewFilter filter = new OpenSessionInViewFilter(); - filter.init(filterConfig); - final OpenSessionInViewFilter filter2 = new OpenSessionInViewFilter(); - filter2.init(filterConfig2); - - final FilterChain filterChain = new FilterChain() { - @Override - public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) { - HibernateTransactionManager tm = new HibernateTransactionManager(sf); - TransactionStatus ts = tm.getTransaction( - new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_SUPPORTS)); - org.hibernate.Session sess = SessionFactoryUtils.getSession(sf, true); - SessionFactoryUtils.releaseSession(sess, sf); - tm.commit(ts); - servletRequest.setAttribute("invoked", Boolean.TRUE); - } - }; - - FilterChain filterChain2 = new FilterChain() { - @Override - public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) - throws IOException, ServletException { - filter.doFilter(servletRequest, servletResponse, filterChain); - } - }; - - filter.doFilter(this.request, this.response, filterChain2); - assertNotNull(this.request.getAttribute("invoked")); - - interceptor.postHandle(webRequest, null); - interceptor.afterCompletion(webRequest, null); - - verify(session).setFlushMode(FlushMode.MANUAL); - verify(session).close(); - - wac.close(); - } - - - @SuppressWarnings("serial") - private static class SyncTaskExecutor extends SimpleAsyncTaskExecutor { - - @Override - public void execute(Runnable task, long startTimeout) { - task.run(); - } - } - -} diff --git a/spring-orm/src/test/java/org/springframework/orm/hibernate3/support/ScopedBeanInterceptorTests.java b/spring-orm/src/test/java/org/springframework/orm/hibernate3/support/ScopedBeanInterceptorTests.java deleted file mode 100644 index 762c04443d..0000000000 --- a/spring-orm/src/test/java/org/springframework/orm/hibernate3/support/ScopedBeanInterceptorTests.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2002-2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3.support; - -import org.junit.Test; - -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.aop.scope.ScopedObject; - -import static org.junit.Assert.*; - -/** - * Unit tests for {@link ScopedBeanInterceptor}. - * - * @author Costin Leau - * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x - */ -@Deprecated -public class ScopedBeanInterceptorTests { - - private final ScopedBeanInterceptor interceptor = new ScopedBeanInterceptor(); - - @Test - public void interceptorWithPlainObject() throws Exception { - final Object realObject = new Object(); - - ScopedObject scoped = new ScopedObject() { - @Override - public Object getTargetObject() { - return realObject; - } - @Override - public void removeFromScope() { - // do nothing - } - }; - - // default contract is to return null for default behavior - assertNull(interceptor.getEntityName(realObject)); - assertEquals(realObject.getClass().getName(), interceptor.getEntityName(scoped)); - } - - @Test - public void interceptorWithCglibProxy() throws Exception { - final Object realObject = new Object(); - ProxyFactory proxyFactory = new ProxyFactory(); - proxyFactory.setTarget(realObject); - proxyFactory.setProxyTargetClass(true); - final Object proxy = proxyFactory.getProxy(); - - ScopedObject scoped = new ScopedObject() { - @Override - public Object getTargetObject() { - return proxy; - } - @Override - public void removeFromScope() { - // do nothing - } - }; - - assertEquals(realObject.getClass().getName(), interceptor.getEntityName(scoped)); - } - -} diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/hibernate/HibernateEntityManagerFactoryIntegrationTests.java b/spring-orm/src/test/java/org/springframework/orm/jpa/hibernate/HibernateEntityManagerFactoryIntegrationTests.java index 0b4fbcbabb..dcd286f01d 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/hibernate/HibernateEntityManagerFactoryIntegrationTests.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/hibernate/HibernateEntityManagerFactoryIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,12 @@ package org.springframework.orm.jpa.hibernate; -import org.hibernate.ejb.HibernateEntityManager; -import org.hibernate.ejb.HibernateEntityManagerFactory; +import org.hibernate.Session; +import org.hibernate.SessionFactory; import org.springframework.orm.jpa.AbstractContainerEntityManagerFactoryIntegrationTests; import org.springframework.orm.jpa.EntityManagerFactoryInfo; +import org.springframework.orm.jpa.EntityManagerProxy; /** * Hibernate-specific JPA tests. @@ -39,13 +40,11 @@ public class HibernateEntityManagerFactoryIntegrationTests extends public void testCanCastNativeEntityManagerFactoryToHibernateEntityManagerFactoryImpl() { EntityManagerFactoryInfo emfi = (EntityManagerFactoryInfo) entityManagerFactory; - assertTrue(emfi.getNativeEntityManagerFactory() instanceof HibernateEntityManagerFactory); + assertTrue(emfi.getNativeEntityManagerFactory() instanceof SessionFactory); // as of Hibernate 5.2 } public void testCanCastSharedEntityManagerProxyToHibernateEntityManager() { - assertTrue(sharedEntityManager instanceof HibernateEntityManager); - HibernateEntityManager hibernateEntityManager = (HibernateEntityManager) sharedEntityManager; - assertNotNull(hibernateEntityManager.getSession()); + assertTrue(((EntityManagerProxy) sharedEntityManager).getTargetEntityManager() instanceof Session); // as of Hibernate 5.2 } } diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/support/PersistenceContextTransactionTests.java b/spring-orm/src/test/java/org/springframework/orm/jpa/support/PersistenceContextTransactionTests.java index 412e11fd93..c123923361 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/support/PersistenceContextTransactionTests.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/support/PersistenceContextTransactionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; import javax.persistence.PersistenceContext; import javax.persistence.PersistenceContextType; +import javax.persistence.SynchronizationType; import org.junit.After; import org.junit.Before; @@ -28,8 +29,6 @@ import org.junit.Test; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.TransactionStatus; -import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionSynchronizationManager; import org.springframework.transaction.support.TransactionTemplate; @@ -40,7 +39,6 @@ import static org.mockito.BDDMockito.*; * @author Juergen Hoeller * @since 4.1.2 */ -@SuppressWarnings({ "rawtypes", "unchecked" }) public class PersistenceContextTransactionTests { private EntityManagerFactory factory; @@ -94,12 +92,9 @@ public class PersistenceContextTransactionTests { public void testTransactionCommitWithSharedEntityManager() { given(manager.getTransaction()).willReturn(tx); - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - bean.sharedEntityManager.flush(); - return null; - } + tt.execute(status -> { + bean.sharedEntityManager.flush(); + return null; }); verify(tx).commit(); @@ -113,12 +108,9 @@ public class PersistenceContextTransactionTests { tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - bean.sharedEntityManager.clear(); - return null; - } + tt.execute(status -> { + bean.sharedEntityManager.clear(); + return null; }); verify(manager).clear(); @@ -129,12 +121,9 @@ public class PersistenceContextTransactionTests { public void testTransactionCommitWithExtendedEntityManager() { given(manager.getTransaction()).willReturn(tx); - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - bean.extendedEntityManager.flush(); - return null; - } + tt.execute(status -> { + bean.extendedEntityManager.flush(); + return null; }); verify(tx, times(2)).commit(); @@ -148,12 +137,111 @@ public class PersistenceContextTransactionTests { tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); - tt.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - bean.extendedEntityManager.flush(); - return null; - } + tt.execute(status -> { + bean.extendedEntityManager.flush(); + return null; + }); + + verify(manager).flush(); + } + + @Test + public void testTransactionCommitWithSharedEntityManagerUnsynchronized() { + given(manager.getTransaction()).willReturn(tx); + + tt.execute(status -> { + bean.sharedEntityManagerUnsynchronized.flush(); + return null; + }); + + verify(tx).commit(); + verify(manager).flush(); + verify(manager, times(2)).close(); + } + + @Test + public void testTransactionCommitWithSharedEntityManagerUnsynchronizedAndPropagationSupports() { + given(manager.isOpen()).willReturn(true); + + tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); + + tt.execute(status -> { + bean.sharedEntityManagerUnsynchronized.clear(); + return null; + }); + + verify(manager).clear(); + verify(manager).close(); + } + + @Test + public void testTransactionCommitWithExtendedEntityManagerUnsynchronized() { + given(manager.getTransaction()).willReturn(tx); + + tt.execute(status -> { + bean.extendedEntityManagerUnsynchronized.flush(); + return null; + }); + + verify(tx).commit(); + verify(manager).flush(); + verify(manager).close(); + } + + @Test + public void testTransactionCommitWithExtendedEntityManagerUnsynchronizedAndPropagationSupports() { + given(manager.isOpen()).willReturn(true); + + tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); + + tt.execute(status -> { + bean.extendedEntityManagerUnsynchronized.flush(); + return null; + }); + + verify(manager).flush(); + } + + @Test + public void testTransactionCommitWithSharedEntityManagerUnsynchronizedJoined() { + given(manager.getTransaction()).willReturn(tx); + + tt.execute(status -> { + bean.sharedEntityManagerUnsynchronized.joinTransaction(); + bean.sharedEntityManagerUnsynchronized.flush(); + return null; + }); + + verify(tx).commit(); + verify(manager).flush(); + verify(manager, times(2)).close(); + } + + @Test + public void testTransactionCommitWithExtendedEntityManagerUnsynchronizedJoined() { + given(manager.getTransaction()).willReturn(tx); + + tt.execute(status -> { + bean.extendedEntityManagerUnsynchronized.joinTransaction(); + bean.extendedEntityManagerUnsynchronized.flush(); + return null; + }); + + verify(tx, times(2)).commit(); + verify(manager).flush(); + verify(manager).close(); + } + + @Test + public void testTransactionCommitWithExtendedEntityManagerUnsynchronizedJoinedAndPropagationSupports() { + given(manager.isOpen()).willReturn(true); + + tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); + + tt.execute(status -> { + bean.extendedEntityManagerUnsynchronized.joinTransaction(); + bean.extendedEntityManagerUnsynchronized.flush(); + return null; }); verify(manager).flush(); @@ -167,6 +255,12 @@ public class PersistenceContextTransactionTests { @PersistenceContext(type = PersistenceContextType.EXTENDED) public EntityManager extendedEntityManager; + + @PersistenceContext(synchronization = SynchronizationType.UNSYNCHRONIZED) + public EntityManager sharedEntityManagerUnsynchronized; + + @PersistenceContext(type = PersistenceContextType.EXTENDED, synchronization = SynchronizationType.UNSYNCHRONIZED) + public EntityManager extendedEntityManagerUnsynchronized; } } diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/orm/HibernateSessionFlushingTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/orm/HibernateSessionFlushingTests.java index 66e6f3a618..493b558b03 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/orm/HibernateSessionFlushingTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/orm/HibernateSessionFlushingTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,8 @@ package org.springframework.test.context.junit4.orm; +import javax.persistence.PersistenceException; + import org.hibernate.SessionFactory; import org.hibernate.exception.ConstraintViolationException; import org.junit.Before; @@ -107,10 +109,16 @@ public class HibernateSessionFlushingTests extends AbstractTransactionalJUnit4Sp } @Test(expected = ConstraintViolationException.class) - public void updateSamWithNullDriversLicenseWithSessionFlush() { + public void updateSamWithNullDriversLicenseWithSessionFlush() throws Throwable { updateSamWithNullDriversLicense(); // Manual flush is required to avoid false positive in test - sessionFactory.getCurrentSession().flush(); + try { + sessionFactory.getCurrentSession().flush(); + } + catch (PersistenceException ex) { + // Wrapped in Hibernate 5.2, with the constraint violation as cause + throw ex.getCause(); + } } } diff --git a/spring-test/src/test/resources/org/springframework/test/context/junit4/orm/HibernateSessionFlushingTests-context.xml b/spring-test/src/test/resources/org/springframework/test/context/junit4/orm/HibernateSessionFlushingTests-context.xml index 5f083e964a..fb1a6ad259 100644 --- a/spring-test/src/test/resources/org/springframework/test/context/junit4/orm/HibernateSessionFlushingTests-context.xml +++ b/spring-test/src/test/resources/org/springframework/test/context/junit4/orm/HibernateSessionFlushingTests-context.xml @@ -8,17 +8,17 @@ http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd"> - + - - + + - + org.hibernate.dialect.HSQLDialect @@ -33,7 +33,7 @@ - +