Removed deprecated JpaTemplate and JpaInterceptor classes; dropped unused EntityManager(Factory)Plus mechanism
This commit is contained in:
parent
7ceb02257e
commit
9caa514c69
|
@ -110,8 +110,6 @@ public abstract class AbstractEntityManagerFactoryBean implements
|
||||||
/** Raw EntityManagerFactory as returned by the PersistenceProvider */
|
/** Raw EntityManagerFactory as returned by the PersistenceProvider */
|
||||||
public EntityManagerFactory nativeEntityManagerFactory;
|
public EntityManagerFactory nativeEntityManagerFactory;
|
||||||
|
|
||||||
private EntityManagerFactoryPlusOperations plusOperations;
|
|
||||||
|
|
||||||
private EntityManagerFactory entityManagerFactory;
|
private EntityManagerFactory entityManagerFactory;
|
||||||
|
|
||||||
|
|
||||||
|
@ -339,10 +337,6 @@ public abstract class AbstractEntityManagerFactoryBean implements
|
||||||
ifcs.addAll(ClassUtils.getAllInterfacesForClassAsSet(emf.getClass(), this.beanClassLoader));
|
ifcs.addAll(ClassUtils.getAllInterfacesForClassAsSet(emf.getClass(), this.beanClassLoader));
|
||||||
}
|
}
|
||||||
ifcs.add(EntityManagerFactoryInfo.class);
|
ifcs.add(EntityManagerFactoryInfo.class);
|
||||||
if (getJpaDialect() != null && getJpaDialect().supportsEntityManagerFactoryPlusOperations()) {
|
|
||||||
this.plusOperations = getJpaDialect().getEntityManagerFactoryPlusOperations(emf);
|
|
||||||
ifcs.add(EntityManagerFactoryPlusOperations.class);
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
return (EntityManagerFactory) Proxy.newProxyInstance(
|
return (EntityManagerFactory) Proxy.newProxyInstance(
|
||||||
this.beanClassLoader, ifcs.toArray(new Class[ifcs.size()]),
|
this.beanClassLoader, ifcs.toArray(new Class[ifcs.size()]),
|
||||||
|
@ -363,16 +357,13 @@ public abstract class AbstractEntityManagerFactoryBean implements
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delegate an incoming invocation from the proxy, dispatching to EntityManagerFactoryInfo /
|
* Delegate an incoming invocation from the proxy, dispatching to EntityManagerFactoryInfo
|
||||||
* EntityManagerFactoryPlusOperations / the native EntityManagerFactory accordingly.
|
* or the native EntityManagerFactory accordingly.
|
||||||
*/
|
*/
|
||||||
Object invokeProxyMethod(Method method, Object[] args) throws Throwable {
|
Object invokeProxyMethod(Method method, Object[] args) throws Throwable {
|
||||||
if (method.getDeclaringClass().isAssignableFrom(EntityManagerFactoryInfo.class)) {
|
if (method.getDeclaringClass().isAssignableFrom(EntityManagerFactoryInfo.class)) {
|
||||||
return method.invoke(this, args);
|
return method.invoke(this, args);
|
||||||
}
|
}
|
||||||
else if (method.getDeclaringClass().equals(EntityManagerFactoryPlusOperations.class)) {
|
|
||||||
return method.invoke(this.plusOperations, args);
|
|
||||||
}
|
|
||||||
else if (method.getName().equals("createEntityManager") && args != null && args.length > 0 &&
|
else if (method.getName().equals("createEntityManager") && args != null && args.length > 0 &&
|
||||||
args[0] != null && args[0].getClass().isEnum() && "SYNCHRONIZED".equals(args[0].toString())) {
|
args[0] != null && args[0].getClass().isEnum() && "SYNCHRONIZED".equals(args[0].toString())) {
|
||||||
// JPA 2.1's createEntityManager(SynchronizationType, Map)
|
// JPA 2.1's createEntityManager(SynchronizationType, Map)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2013 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -18,9 +18,7 @@ package org.springframework.orm.jpa;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
import javax.persistence.EntityManagerFactory;
|
|
||||||
import javax.persistence.PersistenceException;
|
import javax.persistence.PersistenceException;
|
||||||
|
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
|
@ -31,23 +29,20 @@ import org.springframework.transaction.TransactionException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default implementation of the {@link JpaDialect} interface.
|
* Default implementation of the {@link JpaDialect} interface.
|
||||||
* Used as default dialect by {@link JpaAccessor} and {@link JpaTransactionManager}.
|
* Used as default dialect by {@link JpaTransactionManager}.
|
||||||
*
|
*
|
||||||
* <p>Simply begins a standard JPA transaction in {@link #beginTransaction}
|
* <p>Simply begins a standard JPA transaction in {@link #beginTransaction}
|
||||||
* and performs standard exception translation through {@link EntityManagerFactoryUtils}.
|
* and performs standard exception translation through {@link EntityManagerFactoryUtils}.
|
||||||
*
|
*
|
||||||
|
* <p><b>NOTE: Spring's JPA support requires JPA 2.0 or higher, as of Spring 4.0.</b>
|
||||||
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
* @see JpaAccessor#setJpaDialect
|
|
||||||
* @see JpaTransactionManager#setJpaDialect
|
* @see JpaTransactionManager#setJpaDialect
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class DefaultJpaDialect implements JpaDialect, Serializable {
|
public class DefaultJpaDialect implements JpaDialect, Serializable {
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
// Hooks for transaction management (used by JpaTransactionManager)
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This implementation invokes the standard JPA {@code Transaction.begin}
|
* This implementation invokes the standard JPA {@code Transaction.begin}
|
||||||
* method. Throws an InvalidIsolationLevelException if a non-default isolation
|
* method. Throws an InvalidIsolationLevelException if a non-default isolation
|
||||||
|
@ -110,7 +105,7 @@ public class DefaultJpaDialect implements JpaDialect, Serializable {
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
// Hook for exception translation (used by JpaTransactionManager and JpaTemplate)
|
// Hook for exception translation (used by JpaTransactionManager)
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -121,21 +116,4 @@ public class DefaultJpaDialect implements JpaDialect, Serializable {
|
||||||
return EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(ex);
|
return EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean supportsEntityManagerFactoryPlusOperations() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean supportsEntityManagerPlusOperations() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EntityManagerFactoryPlusOperations getEntityManagerFactoryPlusOperations(EntityManagerFactory rawEntityManager) {
|
|
||||||
throw new UnsupportedOperationException(getClass().getName() + " does not support EntityManagerFactoryPlusOperations");
|
|
||||||
}
|
|
||||||
|
|
||||||
public EntityManagerPlusOperations getEntityManagerPlusOperations(EntityManager rawEntityManager) {
|
|
||||||
throw new UnsupportedOperationException(getClass().getName() + " does not support EntityManagerPlusOperations");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2013 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -36,11 +36,8 @@ import org.springframework.util.CollectionUtils;
|
||||||
* Base class for any class that needs to access an EntityManagerFactory,
|
* Base class for any class that needs to access an EntityManagerFactory,
|
||||||
* usually in order to obtain an EntityManager. Defines common properties.
|
* usually in order to obtain an EntityManager. Defines common properties.
|
||||||
*
|
*
|
||||||
* <p>Not intended to be used directly. See {@link JpaAccessor}.
|
|
||||||
*
|
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
* @see JpaAccessor
|
|
||||||
* @see EntityManagerFactoryUtils
|
* @see EntityManagerFactoryUtils
|
||||||
*/
|
*/
|
||||||
public abstract class EntityManagerFactoryAccessor implements BeanFactoryAware {
|
public abstract class EntityManagerFactoryAccessor implements BeanFactoryAware {
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2002-2006 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;
|
|
||||||
|
|
||||||
import javax.persistence.EntityManagerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extension of the standard JPA EntityManagerFactory interface, linking in
|
|
||||||
* Spring's EntityManagerFactoryPlusOperations interface which defines
|
|
||||||
* additional operations (beyond JPA 1.0) in a vendor-independent fashion.
|
|
||||||
*
|
|
||||||
* @author Rod Johnson
|
|
||||||
* @since 2.0
|
|
||||||
* @see javax.persistence.EntityManager
|
|
||||||
*/
|
|
||||||
public interface EntityManagerFactoryPlus extends EntityManagerFactory, EntityManagerFactoryPlusOperations {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2002-2006 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;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface that defines common operations beyond the standard
|
|
||||||
* JPA EntityManagerFactory interface, in a vendor-independent fashion.
|
|
||||||
* To be adapted to specific JPA providers through a JpaDialect.
|
|
||||||
*
|
|
||||||
* <p>As of Spring 2.0, this interface does not define any operations yet.
|
|
||||||
* The pass-through mechanism to the underlying JpaDialect is already in
|
|
||||||
* place. Concrete operations may be added in future releases.
|
|
||||||
*
|
|
||||||
* @author Rod Johnson
|
|
||||||
* @since 2.0
|
|
||||||
* @see JpaDialect#getEntityManagerPlusOperations
|
|
||||||
* @see javax.persistence.EntityManagerFactory
|
|
||||||
*/
|
|
||||||
public interface EntityManagerFactoryPlusOperations {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2002-2006 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;
|
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extension of the standard JPA EntityManager interface, linking in
|
|
||||||
* Spring's EntityManagerPlusOperations interface which defines additional
|
|
||||||
* operations (beyond JPA 1.0) in a vendor-independent fashion.
|
|
||||||
*
|
|
||||||
* @author Rod Johnson
|
|
||||||
* @since 2.0
|
|
||||||
* @see javax.persistence.EntityManager
|
|
||||||
*/
|
|
||||||
public interface EntityManagerPlus extends EntityManager, EntityManagerPlusOperations {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2002-2006 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;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface that defines common operations beyond the standard
|
|
||||||
* JPA EntityManager interface, in a vendor-independent fashion.
|
|
||||||
* To be adapted to specific JPA providers through a JpaDialect.
|
|
||||||
*
|
|
||||||
* <p>As of Spring 2.0, this interface does not define any operations yet.
|
|
||||||
* The pass-through mechanism to the underlying JpaDialect is already in
|
|
||||||
* place. Concrete operations may be added in future releases.
|
|
||||||
*
|
|
||||||
* @author Rod Johnson
|
|
||||||
* @since 2.0
|
|
||||||
* @see JpaDialect#getEntityManagerPlusOperations
|
|
||||||
* @see javax.persistence.EntityManager
|
|
||||||
*/
|
|
||||||
public interface EntityManagerPlusOperations {
|
|
||||||
|
|
||||||
}
|
|
|
@ -59,48 +59,11 @@ import org.springframework.util.CollectionUtils;
|
||||||
public abstract class ExtendedEntityManagerCreator {
|
public abstract class ExtendedEntityManagerCreator {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an EntityManager that can join transactions with the
|
* Create an EntityManager that can join transactions with the {@code joinTransaction()}
|
||||||
* {@code joinTransaction()} method, but is not automatically
|
* method, but is not automatically managed by the container.
|
||||||
* managed by the container.
|
|
||||||
* @param rawEntityManager raw EntityManager
|
* @param rawEntityManager raw EntityManager
|
||||||
* @param plusOperations an implementation of the EntityManagerPlusOperations
|
* @param emfInfo the EntityManagerFactoryInfo to obtain the JpaDialect
|
||||||
* interface, if those operations should be exposed (may be {@code null})
|
* and PersistenceUnitInfo from
|
||||||
* @return an application-managed EntityManager that can join transactions
|
|
||||||
* but does not participate in them automatically
|
|
||||||
*/
|
|
||||||
public static EntityManager createApplicationManagedEntityManager(
|
|
||||||
EntityManager rawEntityManager, EntityManagerPlusOperations plusOperations) {
|
|
||||||
|
|
||||||
return createProxy(rawEntityManager, null, null, plusOperations, null, null, false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an EntityManager that can join transactions with the
|
|
||||||
* {@code joinTransaction()} method, but is not automatically
|
|
||||||
* managed by the container.
|
|
||||||
* @param rawEntityManager raw EntityManager
|
|
||||||
* @param plusOperations an implementation of the EntityManagerPlusOperations
|
|
||||||
* interface, if those operations should be exposed (may be {@code null})
|
|
||||||
* @param exceptionTranslator the exception translator to use for translating
|
|
||||||
* JPA commit/rollback exceptions during transaction synchronization
|
|
||||||
* (may be {@code null})
|
|
||||||
* @return an application-managed EntityManager that can join transactions
|
|
||||||
* but does not participate in them automatically
|
|
||||||
*/
|
|
||||||
public static EntityManager createApplicationManagedEntityManager(
|
|
||||||
EntityManager rawEntityManager, EntityManagerPlusOperations plusOperations,
|
|
||||||
PersistenceExceptionTranslator exceptionTranslator) {
|
|
||||||
|
|
||||||
return createProxy(rawEntityManager, null, null, plusOperations, exceptionTranslator, null, false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an EntityManager that can join transactions with the
|
|
||||||
* {@code joinTransaction()} method, but is not automatically
|
|
||||||
* managed by the container.
|
|
||||||
* @param rawEntityManager raw EntityManager
|
|
||||||
* @param emfInfo the EntityManagerFactoryInfo to obtain the
|
|
||||||
* EntityManagerPlusOperations and PersistenceUnitInfo from
|
|
||||||
* @return an application-managed EntityManager that can join transactions
|
* @return an application-managed EntityManager that can join transactions
|
||||||
* but does not participate in them automatically
|
* but does not participate in them automatically
|
||||||
*/
|
*/
|
||||||
|
@ -111,12 +74,11 @@ public abstract class ExtendedEntityManagerCreator {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an EntityManager that can join transactions with the
|
* Create an EntityManager that can join transactions with the {@code joinTransaction()}
|
||||||
* {@code joinTransaction()} method, but is not automatically
|
* method, but is not automatically managed by the container.
|
||||||
* managed by the container.
|
|
||||||
* @param rawEntityManager raw EntityManager
|
* @param rawEntityManager raw EntityManager
|
||||||
* @param emfInfo the EntityManagerFactoryInfo to obtain the
|
* @param emfInfo the EntityManagerFactoryInfo to obtain the JpaDialect
|
||||||
* EntityManagerPlusOperations and PersistenceUnitInfo from
|
* and PersistenceUnitInfo from
|
||||||
* @param synchronizedWithTransaction whether to automatically join ongoing
|
* @param synchronizedWithTransaction whether to automatically join ongoing
|
||||||
* transactions (according to the JPA 2.1 SynchronizationType rules)
|
* transactions (according to the JPA 2.1 SynchronizationType rules)
|
||||||
* @return an application-managed EntityManager that can join transactions
|
* @return an application-managed EntityManager that can join transactions
|
||||||
|
@ -128,47 +90,12 @@ public abstract class ExtendedEntityManagerCreator {
|
||||||
return createProxy(rawEntityManager, emfInfo, false, synchronizedWithTransaction);
|
return createProxy(rawEntityManager, emfInfo, false, synchronizedWithTransaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an EntityManager whose lifecycle is managed by the container and which
|
* Create an EntityManager whose lifecycle is managed by the container and which
|
||||||
* automatically joins a transaction when being invoked within its scope.
|
* automatically joins a transaction when being invoked within its scope.
|
||||||
* @param rawEntityManager raw EntityManager
|
* @param rawEntityManager raw EntityManager
|
||||||
* @param plusOperations an implementation of the EntityManagerPlusOperations
|
* @param emfInfo the EntityManagerFactoryInfo to obtain the JpaDialect
|
||||||
* interface, if those operations should be exposed (may be {@code null})
|
* and PersistenceUnitInfo from
|
||||||
* @return a container-managed EntityManager that will automatically participate
|
|
||||||
* in any managed transaction
|
|
||||||
*/
|
|
||||||
public static EntityManager createContainerManagedEntityManager(
|
|
||||||
EntityManager rawEntityManager, EntityManagerPlusOperations plusOperations) {
|
|
||||||
|
|
||||||
return createProxy(rawEntityManager, null, null, plusOperations, null, null, true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an EntityManager whose lifecycle is managed by the container and which
|
|
||||||
* automatically joins a transaction when being invoked within its scope.
|
|
||||||
* @param rawEntityManager raw EntityManager
|
|
||||||
* @param plusOperations an implementation of the EntityManagerPlusOperations
|
|
||||||
* interface, if those operations should be exposed (may be {@code null})
|
|
||||||
* @param exceptionTranslator the exception translator to use for translating
|
|
||||||
* JPA commit/rollback exceptions during transaction synchronization
|
|
||||||
* (may be {@code null})
|
|
||||||
* @return a container-managed EntityManager that will automatically participate
|
|
||||||
* in any managed transaction
|
|
||||||
*/
|
|
||||||
public static EntityManager createContainerManagedEntityManager(
|
|
||||||
EntityManager rawEntityManager, EntityManagerPlusOperations plusOperations,
|
|
||||||
PersistenceExceptionTranslator exceptionTranslator) {
|
|
||||||
|
|
||||||
return createProxy(rawEntityManager, null, null, plusOperations, exceptionTranslator, null, true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an EntityManager whose lifecycle is managed by the container and which
|
|
||||||
* automatically joins a transaction when being invoked within its scope.
|
|
||||||
* @param rawEntityManager raw EntityManager
|
|
||||||
* @param emfInfo the EntityManagerFactoryInfo to obtain the
|
|
||||||
* EntityManagerPlusOperations and PersistenceUnitInfo from
|
|
||||||
* @return a container-managed EntityManager that will automatically participate
|
* @return a container-managed EntityManager that will automatically participate
|
||||||
* in any managed transaction
|
* in any managed transaction
|
||||||
*/
|
*/
|
||||||
|
@ -182,9 +109,8 @@ public abstract class ExtendedEntityManagerCreator {
|
||||||
* Create an EntityManager whose lifecycle is managed by the container and which
|
* Create an EntityManager whose lifecycle is managed by the container and which
|
||||||
* automatically joins a transaction when being invoked within its scope.
|
* automatically joins a transaction when being invoked within its scope.
|
||||||
* @param emf the EntityManagerFactory to create the EntityManager with.
|
* @param emf the EntityManagerFactory to create the EntityManager with.
|
||||||
* If this implements the EntityManagerFactoryInfo interface, appropriate handling
|
* If this implements the EntityManagerFactoryInfo interface, the corresponding
|
||||||
* of the native EntityManagerFactory and available EntityManagerPlusOperations
|
* JpaDialect and PersistenceUnitInfo will be detected accordingly.
|
||||||
* will automatically apply.
|
|
||||||
* @return a container-managed EntityManager that will automatically participate
|
* @return a container-managed EntityManager that will automatically participate
|
||||||
* in any managed transaction
|
* in any managed transaction
|
||||||
* @see javax.persistence.EntityManagerFactory#createEntityManager()
|
* @see javax.persistence.EntityManagerFactory#createEntityManager()
|
||||||
|
@ -197,9 +123,8 @@ public abstract class ExtendedEntityManagerCreator {
|
||||||
* Create an EntityManager whose lifecycle is managed by the container and which
|
* Create an EntityManager whose lifecycle is managed by the container and which
|
||||||
* automatically joins a transaction when being invoked within its scope.
|
* automatically joins a transaction when being invoked within its scope.
|
||||||
* @param emf the EntityManagerFactory to create the EntityManager with.
|
* @param emf the EntityManagerFactory to create the EntityManager with.
|
||||||
* If this implements the EntityManagerFactoryInfo interface, appropriate handling
|
* If this implements the EntityManagerFactoryInfo interface, the corresponding
|
||||||
* of the native EntityManagerFactory and available EntityManagerPlusOperations
|
* JpaDialect and PersistenceUnitInfo will be detected accordingly.
|
||||||
* will automatically apply.
|
|
||||||
* @param properties the properties to be passed into the {@code createEntityManager}
|
* @param properties the properties to be passed into the {@code createEntityManager}
|
||||||
* call (may be {@code null})
|
* call (may be {@code null})
|
||||||
* @return a container-managed EntityManager that will automatically participate
|
* @return a container-managed EntityManager that will automatically participate
|
||||||
|
@ -214,9 +139,8 @@ public abstract class ExtendedEntityManagerCreator {
|
||||||
* Create an EntityManager whose lifecycle is managed by the container and which
|
* Create an EntityManager whose lifecycle is managed by the container and which
|
||||||
* may automatically join a transaction when being invoked within its scope.
|
* may automatically join a transaction when being invoked within its scope.
|
||||||
* @param emf the EntityManagerFactory to create the EntityManager with.
|
* @param emf the EntityManagerFactory to create the EntityManager with.
|
||||||
* If this implements the EntityManagerFactoryInfo interface, appropriate handling
|
* If this implements the EntityManagerFactoryInfo interface, the corresponding
|
||||||
* of the native EntityManagerFactory and available EntityManagerPlusOperations
|
* JpaDialect and PersistenceUnitInfo will be detected accordingly.
|
||||||
* will automatically apply.
|
|
||||||
* @param properties the properties to be passed into the {@code createEntityManager}
|
* @param properties the properties to be passed into the {@code createEntityManager}
|
||||||
* call (may be {@code null})
|
* call (may be {@code null})
|
||||||
* @param synchronizedWithTransaction whether to automatically join ongoing
|
* @param synchronizedWithTransaction whether to automatically join ongoing
|
||||||
|
@ -239,7 +163,7 @@ public abstract class ExtendedEntityManagerCreator {
|
||||||
else {
|
else {
|
||||||
EntityManager rawEntityManager = (!CollectionUtils.isEmpty(properties) ?
|
EntityManager rawEntityManager = (!CollectionUtils.isEmpty(properties) ?
|
||||||
emf.createEntityManager(properties) : emf.createEntityManager());
|
emf.createEntityManager(properties) : emf.createEntityManager());
|
||||||
return createProxy(rawEntityManager, null, null, null, null, null, true, synchronizedWithTransaction);
|
return createProxy(rawEntityManager, null, null, null, null, true, synchronizedWithTransaction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,8 +171,8 @@ public abstract class ExtendedEntityManagerCreator {
|
||||||
/**
|
/**
|
||||||
* Actually create the EntityManager proxy.
|
* Actually create the EntityManager proxy.
|
||||||
* @param rawEntityManager raw EntityManager
|
* @param rawEntityManager raw EntityManager
|
||||||
* @param emfInfo the EntityManagerFactoryInfo to obtain the
|
* @param emfInfo the EntityManagerFactoryInfo to obtain the JpaDialect
|
||||||
* EntityManagerPlusOperations and PersistenceUnitInfo from
|
* and PersistenceUnitInfo from
|
||||||
* @param containerManaged whether to follow container-managed EntityManager
|
* @param containerManaged whether to follow container-managed EntityManager
|
||||||
* or application-managed EntityManager semantics
|
* or application-managed EntityManager semantics
|
||||||
* @param synchronizedWithTransaction whether to automatically join ongoing
|
* @param synchronizedWithTransaction whether to automatically join ongoing
|
||||||
|
@ -260,14 +184,10 @@ public abstract class ExtendedEntityManagerCreator {
|
||||||
|
|
||||||
Assert.notNull(emfInfo, "EntityManagerFactoryInfo must not be null");
|
Assert.notNull(emfInfo, "EntityManagerFactoryInfo must not be null");
|
||||||
JpaDialect jpaDialect = emfInfo.getJpaDialect();
|
JpaDialect jpaDialect = emfInfo.getJpaDialect();
|
||||||
EntityManagerPlusOperations plusOperations = null;
|
|
||||||
if (jpaDialect != null && jpaDialect.supportsEntityManagerPlusOperations()) {
|
|
||||||
plusOperations = jpaDialect.getEntityManagerPlusOperations(rawEntityManager);
|
|
||||||
}
|
|
||||||
PersistenceUnitInfo pui = emfInfo.getPersistenceUnitInfo();
|
PersistenceUnitInfo pui = emfInfo.getPersistenceUnitInfo();
|
||||||
Boolean jta = (pui != null ? pui.getTransactionType() == PersistenceUnitTransactionType.JTA : null);
|
Boolean jta = (pui != null ? pui.getTransactionType() == PersistenceUnitTransactionType.JTA : null);
|
||||||
return createProxy(rawEntityManager, emfInfo.getEntityManagerInterface(),
|
return createProxy(rawEntityManager, emfInfo.getEntityManagerInterface(),
|
||||||
emfInfo.getBeanClassLoader(), plusOperations, jpaDialect, jta, containerManaged, synchronizedWithTransaction);
|
emfInfo.getBeanClassLoader(), jpaDialect, jta, containerManaged, synchronizedWithTransaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -275,8 +195,7 @@ public abstract class ExtendedEntityManagerCreator {
|
||||||
* @param rawEm raw EntityManager
|
* @param rawEm raw EntityManager
|
||||||
* @param emIfc the (potentially vendor-specific) EntityManager
|
* @param emIfc the (potentially vendor-specific) EntityManager
|
||||||
* interface to proxy, or {@code null} for default detection of all interfaces
|
* interface to proxy, or {@code null} for default detection of all interfaces
|
||||||
* @param plusOperations an implementation of the EntityManagerPlusOperations
|
* @param cl the ClassLoader to use for proxy creation (maybe {@code null})
|
||||||
* interface, if those operations should be exposed (may be {@code null})
|
|
||||||
* @param exceptionTranslator the PersistenceException translator to use
|
* @param exceptionTranslator the PersistenceException translator to use
|
||||||
* @param jta whether to create a JTA-aware EntityManager
|
* @param jta whether to create a JTA-aware EntityManager
|
||||||
* (or {@code null} if not known in advance)
|
* (or {@code null} if not known in advance)
|
||||||
|
@ -288,8 +207,8 @@ public abstract class ExtendedEntityManagerCreator {
|
||||||
*/
|
*/
|
||||||
private static EntityManager createProxy(
|
private static EntityManager createProxy(
|
||||||
EntityManager rawEm, Class<? extends EntityManager> emIfc, ClassLoader cl,
|
EntityManager rawEm, Class<? extends EntityManager> emIfc, ClassLoader cl,
|
||||||
EntityManagerPlusOperations plusOperations, PersistenceExceptionTranslator exceptionTranslator,
|
PersistenceExceptionTranslator exceptionTranslator, Boolean jta,
|
||||||
Boolean jta, boolean containerManaged, boolean synchronizedWithTransaction) {
|
boolean containerManaged, boolean synchronizedWithTransaction) {
|
||||||
|
|
||||||
Assert.notNull(rawEm, "EntityManager must not be null");
|
Assert.notNull(rawEm, "EntityManager must not be null");
|
||||||
Set<Class> ifcs = new LinkedHashSet<Class>();
|
Set<Class> ifcs = new LinkedHashSet<Class>();
|
||||||
|
@ -300,14 +219,11 @@ public abstract class ExtendedEntityManagerCreator {
|
||||||
ifcs.addAll(ClassUtils.getAllInterfacesForClassAsSet(rawEm.getClass(), cl));
|
ifcs.addAll(ClassUtils.getAllInterfacesForClassAsSet(rawEm.getClass(), cl));
|
||||||
}
|
}
|
||||||
ifcs.add(EntityManagerProxy.class);
|
ifcs.add(EntityManagerProxy.class);
|
||||||
if (plusOperations != null) {
|
|
||||||
ifcs.add(EntityManagerPlusOperations.class);
|
|
||||||
}
|
|
||||||
return (EntityManager) Proxy.newProxyInstance(
|
return (EntityManager) Proxy.newProxyInstance(
|
||||||
(cl != null ? cl : ExtendedEntityManagerCreator.class.getClassLoader()),
|
(cl != null ? cl : ExtendedEntityManagerCreator.class.getClassLoader()),
|
||||||
ifcs.toArray(new Class[ifcs.size()]),
|
ifcs.toArray(new Class[ifcs.size()]),
|
||||||
new ExtendedEntityManagerInvocationHandler(
|
new ExtendedEntityManagerInvocationHandler(
|
||||||
rawEm, plusOperations, exceptionTranslator, jta, containerManaged, synchronizedWithTransaction));
|
rawEm, exceptionTranslator, jta, containerManaged, synchronizedWithTransaction));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -321,8 +237,6 @@ public abstract class ExtendedEntityManagerCreator {
|
||||||
|
|
||||||
private final EntityManager target;
|
private final EntityManager target;
|
||||||
|
|
||||||
private final EntityManagerPlusOperations plusOperations;
|
|
||||||
|
|
||||||
private final PersistenceExceptionTranslator exceptionTranslator;
|
private final PersistenceExceptionTranslator exceptionTranslator;
|
||||||
|
|
||||||
private final boolean jta;
|
private final boolean jta;
|
||||||
|
@ -331,13 +245,11 @@ public abstract class ExtendedEntityManagerCreator {
|
||||||
|
|
||||||
private final boolean synchronizedWithTransaction;
|
private final boolean synchronizedWithTransaction;
|
||||||
|
|
||||||
private ExtendedEntityManagerInvocationHandler(
|
private ExtendedEntityManagerInvocationHandler(EntityManager target,
|
||||||
EntityManager target, EntityManagerPlusOperations plusOperations,
|
|
||||||
PersistenceExceptionTranslator exceptionTranslator, Boolean jta,
|
PersistenceExceptionTranslator exceptionTranslator, Boolean jta,
|
||||||
boolean containerManaged, boolean synchronizedWithTransaction) {
|
boolean containerManaged, boolean synchronizedWithTransaction) {
|
||||||
|
|
||||||
this.target = target;
|
this.target = target;
|
||||||
this.plusOperations = plusOperations;
|
|
||||||
this.exceptionTranslator = exceptionTranslator;
|
this.exceptionTranslator = exceptionTranslator;
|
||||||
this.jta = (jta != null ? jta : isJtaEntityManager());
|
this.jta = (jta != null ? jta : isJtaEntityManager());
|
||||||
this.containerManaged = containerManaged;
|
this.containerManaged = containerManaged;
|
||||||
|
@ -418,13 +330,8 @@ public abstract class ExtendedEntityManagerCreator {
|
||||||
|
|
||||||
// Invoke method on current EntityManager.
|
// Invoke method on current EntityManager.
|
||||||
try {
|
try {
|
||||||
if (method.getDeclaringClass().equals(EntityManagerPlusOperations.class)) {
|
|
||||||
return method.invoke(this.plusOperations, args);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return method.invoke(this.target, args);
|
return method.invoke(this.target, args);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (InvocationTargetException ex) {
|
catch (InvocationTargetException ex) {
|
||||||
throw ex.getTargetException();
|
throw ex.getTargetException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,158 +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.jpa;
|
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
import javax.persistence.EntityManagerFactory;
|
|
||||||
import javax.persistence.PersistenceException;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
|
||||||
import org.springframework.dao.support.DataAccessUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base class for JpaTemplate and JpaInterceptor, defining common
|
|
||||||
* properties such as EntityManagerFactory and flushing behavior.
|
|
||||||
*
|
|
||||||
* <p>Not intended to be used directly.
|
|
||||||
* See {@link JpaTemplate} and {@link JpaInterceptor}.
|
|
||||||
*
|
|
||||||
* @author Juergen Hoeller
|
|
||||||
* @since 2.0
|
|
||||||
* @see #setEntityManagerFactory
|
|
||||||
* @see #setEntityManager
|
|
||||||
* @see #setJpaDialect
|
|
||||||
* @see #setFlushEager
|
|
||||||
* @see JpaTemplate
|
|
||||||
* @see JpaInterceptor
|
|
||||||
* @see JpaDialect
|
|
||||||
* @deprecated as of Spring 3.1, in favor of native EntityManager usage
|
|
||||||
* (typically obtained through {@code @PersistenceContext})
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public abstract class JpaAccessor extends EntityManagerFactoryAccessor implements InitializingBean {
|
|
||||||
|
|
||||||
private EntityManager entityManager;
|
|
||||||
|
|
||||||
private JpaDialect jpaDialect = new DefaultJpaDialect();
|
|
||||||
|
|
||||||
private boolean flushEager = false;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the JPA EntityManager to use.
|
|
||||||
*/
|
|
||||||
public void setEntityManager(EntityManager entityManager) {
|
|
||||||
this.entityManager = entityManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the JPA EntityManager to use.
|
|
||||||
*/
|
|
||||||
public EntityManager getEntityManager() {
|
|
||||||
return entityManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the JPA dialect to use for this accessor.
|
|
||||||
* <p>The dialect object can be used to retrieve the underlying JDBC
|
|
||||||
* connection, for example.
|
|
||||||
*/
|
|
||||||
public void setJpaDialect(JpaDialect jpaDialect) {
|
|
||||||
this.jpaDialect = (jpaDialect != null ? jpaDialect : new DefaultJpaDialect());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the JPA dialect to use for this accessor.
|
|
||||||
* <p>Creates a default one for the specified EntityManagerFactory if none set.
|
|
||||||
*/
|
|
||||||
public JpaDialect getJpaDialect() {
|
|
||||||
return this.jpaDialect;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set if this accessor should flush changes to the database eagerly.
|
|
||||||
* <p>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:
|
|
||||||
* <ul>
|
|
||||||
* <li>additional communication roundtrips with the database, instead of a
|
|
||||||
* single batch at transaction commit;
|
|
||||||
* <li>the fact that an actual database rollback is needed if the JPA
|
|
||||||
* transaction rolls back (due to already submitted SQL statements).
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
public void setFlushEager(boolean flushEager) {
|
|
||||||
this.flushEager = flushEager;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return if this accessor should flush changes to the database eagerly.
|
|
||||||
*/
|
|
||||||
public boolean isFlushEager() {
|
|
||||||
return this.flushEager;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Eagerly initialize the JPA dialect, creating a default one
|
|
||||||
* for the specified EntityManagerFactory if none set.
|
|
||||||
*/
|
|
||||||
public void afterPropertiesSet() {
|
|
||||||
EntityManagerFactory emf = getEntityManagerFactory();
|
|
||||||
if (emf == null && getEntityManager() == null) {
|
|
||||||
throw new IllegalArgumentException("'entityManagerFactory' or 'entityManager' is required");
|
|
||||||
}
|
|
||||||
if (emf instanceof EntityManagerFactoryInfo) {
|
|
||||||
JpaDialect jpaDialect = ((EntityManagerFactoryInfo) emf).getJpaDialect();
|
|
||||||
if (jpaDialect != null) {
|
|
||||||
setJpaDialect(jpaDialect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flush the given JPA entity manager if necessary.
|
|
||||||
* @param em the current JPA PersistenceManage
|
|
||||||
* @param existingTransaction if executing within an existing transaction
|
|
||||||
* @throws javax.persistence.PersistenceException in case of JPA flushing errors
|
|
||||||
*/
|
|
||||||
protected void flushIfNecessary(EntityManager em, boolean existingTransaction) throws PersistenceException {
|
|
||||||
if (isFlushEager()) {
|
|
||||||
logger.debug("Eagerly flushing JPA entity manager");
|
|
||||||
em.flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert the given runtime exception to an appropriate exception from the
|
|
||||||
* {@code org.springframework.dao} hierarchy if necessary, or
|
|
||||||
* return the exception itself if it is not persistence related
|
|
||||||
* <p>Default implementation delegates to the JpaDialect.
|
|
||||||
* May be overridden in subclasses.
|
|
||||||
* @param ex runtime exception that occured, which may or may not
|
|
||||||
* be JPA-related
|
|
||||||
* @return the corresponding DataAccessException instance if
|
|
||||||
* wrapping should occur, otherwise the raw exception
|
|
||||||
* @see org.springframework.dao.support.DataAccessUtils#translateIfNecessary
|
|
||||||
*/
|
|
||||||
public RuntimeException translateIfNecessary(RuntimeException ex) {
|
|
||||||
return DataAccessUtils.translateIfNecessary(ex, getJpaDialect());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,61 +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.jpa;
|
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
import javax.persistence.PersistenceException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback interface for JPA code. To be used with {@link JpaTemplate}'s
|
|
||||||
* execution method, often as anonymous classes within a method implementation.
|
|
||||||
* A typical implementation will call {@code EntityManager.find/merge}
|
|
||||||
* to perform some operations on persistent objects.
|
|
||||||
*
|
|
||||||
* @author Juergen Hoeller
|
|
||||||
* @since 2.0
|
|
||||||
* @see JpaTemplate
|
|
||||||
* @see JpaTransactionManager
|
|
||||||
* @deprecated as of Spring 3.1, in favor of native EntityManager usage
|
|
||||||
* (typically obtained through {@code @PersistenceContext})
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public interface JpaCallback<T> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets called by {@code JpaTemplate.execute} with an active
|
|
||||||
* JPA {@code EntityManager}. Does not need to care about activating
|
|
||||||
* or closing the {@code EntityManager}, or handling transactions.
|
|
||||||
*
|
|
||||||
* <p>Note that JPA callback code will not flush any modifications to the
|
|
||||||
* database if not executed within a transaction. Thus, you need to make
|
|
||||||
* sure that JpaTransactionManager has initiated a JPA transaction when
|
|
||||||
* the callback gets called, at least if you want to write to the database.
|
|
||||||
*
|
|
||||||
* <p>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 em active EntityManager
|
|
||||||
* @return a result object, or {@code null} if none
|
|
||||||
* @throws PersistenceException if thrown by the JPA API
|
|
||||||
* @see JpaTemplate#execute
|
|
||||||
* @see JpaTemplate#executeFind
|
|
||||||
*/
|
|
||||||
T doInJpa(EntityManager em) throws PersistenceException;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2013 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -18,7 +18,6 @@ package org.springframework.orm.jpa;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
import javax.persistence.EntityManagerFactory;
|
|
||||||
import javax.persistence.PersistenceException;
|
import javax.persistence.PersistenceException;
|
||||||
|
|
||||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||||
|
@ -27,7 +26,7 @@ import org.springframework.transaction.TransactionDefinition;
|
||||||
import org.springframework.transaction.TransactionException;
|
import org.springframework.transaction.TransactionException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SPI strategy that encapsulates certain functionality that standard JPA 1.0
|
* SPI strategy that encapsulates certain functionality that standard JPA 2.0
|
||||||
* does not offer, such as access to the underlying JDBC Connection. This
|
* does not offer, such as access to the underlying JDBC Connection. This
|
||||||
* strategy is mainly intended for standalone usage of a JPA provider; most
|
* strategy is mainly intended for standalone usage of a JPA provider; most
|
||||||
* of its functionality is not relevant when running with JTA transactions.
|
* of its functionality is not relevant when running with JTA transactions.
|
||||||
|
@ -45,7 +44,6 @@ import org.springframework.transaction.TransactionException;
|
||||||
* @author Rod Johnson
|
* @author Rod Johnson
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
* @see DefaultJpaDialect
|
* @see DefaultJpaDialect
|
||||||
* @see JpaAccessor#setJpaDialect
|
|
||||||
* @see JpaTransactionManager#setJpaDialect
|
* @see JpaTransactionManager#setJpaDialect
|
||||||
* @see JpaVendorAdapter#getJpaDialect()
|
* @see JpaVendorAdapter#getJpaDialect()
|
||||||
* @see AbstractEntityManagerFactoryBean#setJpaDialect
|
* @see AbstractEntityManagerFactoryBean#setJpaDialect
|
||||||
|
@ -53,51 +51,6 @@ import org.springframework.transaction.TransactionException;
|
||||||
*/
|
*/
|
||||||
public interface JpaDialect extends PersistenceExceptionTranslator {
|
public interface JpaDialect extends PersistenceExceptionTranslator {
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------
|
|
||||||
// Hooks for non-standard persistence operations (used by EntityManagerFactory beans)
|
|
||||||
//-----------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return whether the EntityManagerFactoryPlus(Operations) interface is
|
|
||||||
* supported by this provider.
|
|
||||||
* @see EntityManagerFactoryPlusOperations
|
|
||||||
* @see EntityManagerFactoryPlus
|
|
||||||
*/
|
|
||||||
boolean supportsEntityManagerFactoryPlusOperations();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return whether the EntityManagerPlus(Operations) interface is
|
|
||||||
* supported by this provider.
|
|
||||||
* @see EntityManagerPlusOperations
|
|
||||||
* @see EntityManagerPlus
|
|
||||||
*/
|
|
||||||
boolean supportsEntityManagerPlusOperations();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return an EntityManagerFactoryPlusOperations implementation for
|
|
||||||
* the given raw EntityManagerFactory. This operations object can be
|
|
||||||
* used to serve the additional operations behind a proxy that
|
|
||||||
* implements the EntityManagerFactoryPlus interface.
|
|
||||||
* @param rawEntityManager the raw provider-specific EntityManagerFactory
|
|
||||||
* @return the EntityManagerFactoryPlusOperations implementation
|
|
||||||
*/
|
|
||||||
EntityManagerFactoryPlusOperations getEntityManagerFactoryPlusOperations(EntityManagerFactory rawEntityManager);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return an EntityManagerPlusOperations implementation for
|
|
||||||
* the given raw EntityManager. This operations object can be
|
|
||||||
* used to serve the additional operations behind a proxy that
|
|
||||||
* implements the EntityManagerPlus interface.
|
|
||||||
* @param rawEntityManager the raw provider-specific EntityManagerFactory
|
|
||||||
* @return the EntityManagerFactoryPlusOperations implementation
|
|
||||||
*/
|
|
||||||
EntityManagerPlusOperations getEntityManagerPlusOperations(EntityManager rawEntityManager);
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
// Hooks for transaction management (used by JpaTransactionManager)
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Begin the given JPA transaction, applying the semantics specified by the
|
* Begin the given JPA transaction, applying the semantics specified by the
|
||||||
* given Spring transaction definition (in particular, an isolation level
|
* given Spring transaction definition (in particular, an isolation level
|
||||||
|
@ -173,7 +126,7 @@ public interface JpaDialect extends PersistenceExceptionTranslator {
|
||||||
* needing access to the underlying JDBC Connection, usually within an active JPA
|
* needing access to the underlying JDBC Connection, usually within an active JPA
|
||||||
* transaction (for example, by JpaTransactionManager). The returned handle will
|
* transaction (for example, by JpaTransactionManager). The returned handle will
|
||||||
* be passed into the {@code releaseJdbcConnection} method when not needed anymore.
|
* be passed into the {@code releaseJdbcConnection} method when not needed anymore.
|
||||||
* <p>This strategy is necessary as JPA 1.0 does not provide a standard way to retrieve
|
* <p>This strategy is necessary as JPA does not provide a standard way to retrieve
|
||||||
* the underlying JDBC Connection (due to the fact that a JPA implementation might not
|
* the underlying JDBC Connection (due to the fact that a JPA implementation might not
|
||||||
* work with a relational database at all).
|
* work with a relational database at all).
|
||||||
* <p>Implementations are encouraged to return an unwrapped Connection object, i.e.
|
* <p>Implementations are encouraged to return an unwrapped Connection object, i.e.
|
||||||
|
|
|
@ -1,123 +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.jpa;
|
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
|
|
||||||
import org.aopalliance.intercept.MethodInterceptor;
|
|
||||||
import org.aopalliance.intercept.MethodInvocation;
|
|
||||||
|
|
||||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This interceptor binds a new JPA EntityManager 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 EntityManager (e.g. from JpaTransactionManager,
|
|
||||||
* or from a surrounding JPA-intercepted method), the interceptor simply participates in it.
|
|
||||||
*
|
|
||||||
* <p>Application code must retrieve a JPA EntityManager via the
|
|
||||||
* {@code EntityManagerFactoryUtils.getEntityManager} method or - preferably -
|
|
||||||
* via a shared {@code EntityManager} reference, to be able to detect a
|
|
||||||
* thread-bound EntityManager. Typically, the code will look like as follows:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* public void doSomeDataAccessAction() {
|
|
||||||
* this.entityManager...
|
|
||||||
* }</pre>
|
|
||||||
*
|
|
||||||
* <p>Note that this interceptor automatically translates PersistenceExceptions,
|
|
||||||
* via delegating to the {@code EntityManagerFactoryUtils.convertJpaAccessException}
|
|
||||||
* method that converts them to exceptions that are compatible with the
|
|
||||||
* {@code org.springframework.dao} exception hierarchy (like JpaTemplate does).
|
|
||||||
*
|
|
||||||
* <p>This class can be considered a declarative alternative to JpaTemplate's
|
|
||||||
* callback approach. The advantages are:
|
|
||||||
* <ul>
|
|
||||||
* <li>no anonymous classes necessary for callback implementations;
|
|
||||||
* <li>the possibility to throw any application exceptions from within data access code.
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* <p>The drawback is the dependency on interceptor configuration. However, note
|
|
||||||
* that this interceptor is usually <i>not</i> necessary in scenarios where the
|
|
||||||
* data access code always executes within transactions. A transaction will always
|
|
||||||
* have a thread-bound EntityManager in the first place, so adding this interceptor
|
|
||||||
* to the configuration just adds value when fine-tuning EntityManager settings
|
|
||||||
* like the flush mode - or when relying on exception translation.
|
|
||||||
*
|
|
||||||
* @author Juergen Hoeller
|
|
||||||
* @since 2.0
|
|
||||||
* @see JpaTransactionManager
|
|
||||||
* @see JpaTemplate
|
|
||||||
* @deprecated as of Spring 3.1, in favor of native EntityManager usage
|
|
||||||
* (typically obtained through {@code @PersistenceContext}) and
|
|
||||||
* AOP-driven exception translation through
|
|
||||||
* {@link org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor}
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public class JpaInterceptor extends JpaAccessor implements MethodInterceptor {
|
|
||||||
|
|
||||||
private boolean exceptionConversionEnabled = true;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set whether to convert any PersistenceException raised to a Spring DataAccessException,
|
|
||||||
* compatible with the {@code org.springframework.dao} exception hierarchy.
|
|
||||||
* <p>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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
|
|
||||||
// Determine current EntityManager: either the transactional one
|
|
||||||
// managed by the factory or a temporary one for the given invocation.
|
|
||||||
EntityManager em = getTransactionalEntityManager();
|
|
||||||
boolean isNewEm = false;
|
|
||||||
if (em == null) {
|
|
||||||
logger.debug("Creating new EntityManager for JpaInterceptor invocation");
|
|
||||||
em = createEntityManager();
|
|
||||||
isNewEm = true;
|
|
||||||
TransactionSynchronizationManager.bindResource(getEntityManagerFactory(), new EntityManagerHolder(em));
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
Object retVal = methodInvocation.proceed();
|
|
||||||
flushIfNecessary(em, !isNewEm);
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
catch (RuntimeException rawException) {
|
|
||||||
if (this.exceptionConversionEnabled) {
|
|
||||||
// Translation enabled. Translate if we understand the exception.
|
|
||||||
throw translateIfNecessary(rawException);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Translation not enabled. Don't try to translate.
|
|
||||||
throw rawException;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
if (isNewEm) {
|
|
||||||
TransactionSynchronizationManager.unbindResource(getEntityManagerFactory());
|
|
||||||
EntityManagerFactoryUtils.closeEntityManager(em);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,88 +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.jpa;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.springframework.dao.DataAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface that specifies a basic set of JPA operations,
|
|
||||||
* implemented by {@link JpaTemplate}. Not often used, but a useful
|
|
||||||
* option to enhance testability, as it can easily be mocked or stubbed.
|
|
||||||
*
|
|
||||||
* <p>Defines {@code JpaTemplate}'s data access methods that mirror
|
|
||||||
* various {@link javax.persistence.EntityManager} methods. Users are
|
|
||||||
* strongly encouraged to read the JPA {@code EntityManager}
|
|
||||||
* javadocs for details on the semantics of those methods.
|
|
||||||
*
|
|
||||||
* <p>Note that lazy loading will just work with an open JPA
|
|
||||||
* {@code EntityManager}, either within a managed transaction or within
|
|
||||||
* {@link org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter}/
|
|
||||||
* {@link org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor}.
|
|
||||||
* Furthermore, some operations just make sense within transactions,
|
|
||||||
* for example: {@code flush}, {@code clear}.
|
|
||||||
*
|
|
||||||
* @author Juergen Hoeller
|
|
||||||
* @since 2.0
|
|
||||||
* @see JpaTemplate
|
|
||||||
* @see javax.persistence.EntityManager
|
|
||||||
* @see JpaTransactionManager
|
|
||||||
* @see JpaDialect
|
|
||||||
* @see org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
|
|
||||||
* @see org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor
|
|
||||||
* @deprecated as of Spring 3.1, in favor of native EntityManager usage
|
|
||||||
* (typically obtained through {@code @PersistenceContext}).
|
|
||||||
* Note that this interface did not get upgraded to JPA 2.0 and never will.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public interface JpaOperations {
|
|
||||||
|
|
||||||
<T> T execute(JpaCallback<T> action) throws DataAccessException;
|
|
||||||
|
|
||||||
List executeFind(JpaCallback<?> action) throws DataAccessException;
|
|
||||||
|
|
||||||
<T> T find(Class<T> entityClass, Object id) throws DataAccessException;
|
|
||||||
|
|
||||||
<T> T getReference(Class<T> entityClass, Object id) throws DataAccessException;
|
|
||||||
|
|
||||||
boolean contains(Object entity) throws DataAccessException;
|
|
||||||
|
|
||||||
void refresh(Object entity) throws DataAccessException;
|
|
||||||
|
|
||||||
void persist(Object entity) throws DataAccessException;
|
|
||||||
|
|
||||||
<T> T merge(T entity) throws DataAccessException;
|
|
||||||
|
|
||||||
void remove(Object entity) throws DataAccessException;
|
|
||||||
|
|
||||||
void flush() throws DataAccessException;
|
|
||||||
|
|
||||||
List find(String queryString) throws DataAccessException;
|
|
||||||
|
|
||||||
List find(String queryString, Object... values) throws DataAccessException;
|
|
||||||
|
|
||||||
List findByNamedParams(String queryString, Map<String, ?> params) throws DataAccessException;
|
|
||||||
|
|
||||||
List findByNamedQuery(String queryName) throws DataAccessException;
|
|
||||||
|
|
||||||
List findByNamedQuery(String queryName, Object... values) throws DataAccessException;
|
|
||||||
|
|
||||||
List findByNamedQueryAndNamedParams(String queryName, Map<String, ?> params) throws DataAccessException;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,442 +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.jpa;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationHandler;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.lang.reflect.Proxy;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
import javax.persistence.EntityManagerFactory;
|
|
||||||
import javax.persistence.PersistenceException;
|
|
||||||
import javax.persistence.Query;
|
|
||||||
|
|
||||||
import org.springframework.dao.DataAccessException;
|
|
||||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
|
||||||
import org.springframework.util.Assert;
|
|
||||||
import org.springframework.util.ClassUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper class that allows for writing JPA data access code in the same style
|
|
||||||
* as with Spring's well-known JdoTemplate and HibernateTemplate classes.
|
|
||||||
* Automatically converts PersistenceExceptions into Spring DataAccessExceptions,
|
|
||||||
* following the {@code org.springframework.dao} exception hierarchy.
|
|
||||||
*
|
|
||||||
* <p>The central method is of this template is "execute", supporting JPA access code
|
|
||||||
* implementing the {@link JpaCallback} interface. It provides JPA EntityManager
|
|
||||||
* handling such that neither the JpaCallback implementation nor the calling code
|
|
||||||
* needs to explicitly care about retrieving/closing EntityManagers, or handling
|
|
||||||
* JPA lifecycle exceptions.
|
|
||||||
*
|
|
||||||
* <p>Can be used within a service implementation via direct instantiation with
|
|
||||||
* a EntityManagerFactory reference, or get prepared in an application context
|
|
||||||
* and given to services as bean reference. Note: The EntityManagerFactory 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.
|
|
||||||
*
|
|
||||||
* <p><b>NOTE: JpaTemplate mainly exists as a sibling of JdoTemplate and
|
|
||||||
* HibernateTemplate, offering the same style for people used to it. For newly
|
|
||||||
* started projects, consider adopting the standard JPA style of coding data
|
|
||||||
* access objects instead, based on a "shared EntityManager" reference injected
|
|
||||||
* via a Spring bean definition or the JPA PersistenceContext annotation.</b>
|
|
||||||
* (Using Spring's SharedEntityManagerBean / PersistenceAnnotationBeanPostProcessor,
|
|
||||||
* or using a direct JNDI lookup for an EntityManager on a Java EE 5 server.)
|
|
||||||
*
|
|
||||||
* <p>JpaTemplate can be considered as direct alternative to working with the
|
|
||||||
* native JPA EntityManager API (through a shared EntityManager reference,
|
|
||||||
* as outlined above). The major advantage is its automatic conversion to
|
|
||||||
* DataAccessExceptions; the major disadvantage is that it introduces
|
|
||||||
* another thin layer on top of the native JPA API. Note that exception
|
|
||||||
* translation can also be achieved through AOP advice; check out
|
|
||||||
* {@link org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor}.
|
|
||||||
*
|
|
||||||
* <p>{@link LocalContainerEntityManagerFactoryBean} is the preferred way of
|
|
||||||
* obtaining a reference to an EntityManagerFactory, at least outside of a full
|
|
||||||
* Java EE 5 environment. The Spring application context will manage its lifecycle,
|
|
||||||
* initializing and shutting down the factory as part of the application.
|
|
||||||
* Within a Java EE 5 environment, you will typically work with a server-managed
|
|
||||||
* EntityManagerFactory that is exposed via JNDI, obtained through Spring's
|
|
||||||
* {@link org.springframework.jndi.JndiObjectFactoryBean}.
|
|
||||||
*
|
|
||||||
* @author Juergen Hoeller
|
|
||||||
* @since 2.0
|
|
||||||
* @see #setEntityManagerFactory
|
|
||||||
* @see JpaCallback
|
|
||||||
* @see javax.persistence.EntityManager
|
|
||||||
* @see LocalEntityManagerFactoryBean
|
|
||||||
* @see LocalContainerEntityManagerFactoryBean
|
|
||||||
* @see JpaTransactionManager
|
|
||||||
* @see org.springframework.transaction.jta.JtaTransactionManager
|
|
||||||
* @see org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
|
|
||||||
* @see org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor
|
|
||||||
* @deprecated as of Spring 3.1, in favor of native EntityManager usage
|
|
||||||
* (typically obtained through {@code @PersistenceContext})
|
|
||||||
* Note that this class did not get upgraded to JPA 2.0 and never will.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public class JpaTemplate extends JpaAccessor implements JpaOperations {
|
|
||||||
|
|
||||||
private boolean exposeNativeEntityManager = false;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new JpaTemplate instance.
|
|
||||||
*/
|
|
||||||
public JpaTemplate() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new JpaTemplate instance.
|
|
||||||
* @param emf EntityManagerFactory to create EntityManagers
|
|
||||||
*/
|
|
||||||
public JpaTemplate(EntityManagerFactory emf) {
|
|
||||||
setEntityManagerFactory(emf);
|
|
||||||
afterPropertiesSet();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new JpaTemplate instance.
|
|
||||||
* @param em EntityManager to use
|
|
||||||
*/
|
|
||||||
public JpaTemplate(EntityManager em) {
|
|
||||||
setEntityManager(em);
|
|
||||||
afterPropertiesSet();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set whether to expose the native JPA EntityManager to JpaCallback
|
|
||||||
* code. Default is "false": a EntityManager proxy will be returned,
|
|
||||||
* suppressing {@code close} calls and automatically applying transaction
|
|
||||||
* timeouts (if any).
|
|
||||||
* <p>As there is often a need to cast to a provider-specific EntityManager
|
|
||||||
* class in DAOs that use the JPA 1.0 API, for JPA 2.0 previews and other
|
|
||||||
* provider-specific functionality, the exposed proxy implements all interfaces
|
|
||||||
* implemented by the original EntityManager. If this is not sufficient,
|
|
||||||
* turn this flag to "true".
|
|
||||||
* @see JpaCallback
|
|
||||||
* @see javax.persistence.EntityManager
|
|
||||||
*/
|
|
||||||
public void setExposeNativeEntityManager(boolean exposeNativeEntityManager) {
|
|
||||||
this.exposeNativeEntityManager = exposeNativeEntityManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return whether to expose the native JPA EntityManager to JpaCallback
|
|
||||||
* code, or rather an EntityManager proxy.
|
|
||||||
*/
|
|
||||||
public boolean isExposeNativeEntityManager() {
|
|
||||||
return this.exposeNativeEntityManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public <T> T execute(JpaCallback<T> action) throws DataAccessException {
|
|
||||||
return execute(action, isExposeNativeEntityManager());
|
|
||||||
}
|
|
||||||
|
|
||||||
public List executeFind(JpaCallback<?> action) throws DataAccessException {
|
|
||||||
Object result = execute(action, isExposeNativeEntityManager());
|
|
||||||
if (!(result instanceof List)) {
|
|
||||||
throw new InvalidDataAccessApiUsageException(
|
|
||||||
"Result object returned from JpaCallback isn't a List: [" + result + "]");
|
|
||||||
}
|
|
||||||
return (List) result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute the action specified by the given action object within a
|
|
||||||
* EntityManager.
|
|
||||||
* @param action callback object that specifies the JPA action
|
|
||||||
* @param exposeNativeEntityManager whether to expose the native
|
|
||||||
* JPA entity manager to callback code
|
|
||||||
* @return a result object returned by the action, or {@code null}
|
|
||||||
* @throws org.springframework.dao.DataAccessException in case of JPA errors
|
|
||||||
*/
|
|
||||||
public <T> T execute(JpaCallback<T> action, boolean exposeNativeEntityManager) throws DataAccessException {
|
|
||||||
Assert.notNull(action, "Callback object must not be null");
|
|
||||||
|
|
||||||
EntityManager em = getEntityManager();
|
|
||||||
boolean isNewEm = false;
|
|
||||||
if (em == null) {
|
|
||||||
em = getTransactionalEntityManager();
|
|
||||||
if (em == null) {
|
|
||||||
logger.debug("Creating new EntityManager for JpaTemplate execution");
|
|
||||||
em = createEntityManager();
|
|
||||||
isNewEm = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
EntityManager emToExpose = (exposeNativeEntityManager ? em : createEntityManagerProxy(em));
|
|
||||||
T result = action.doInJpa(emToExpose);
|
|
||||||
flushIfNecessary(em, !isNewEm);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
catch (RuntimeException ex) {
|
|
||||||
throw translateIfNecessary(ex);
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
if (isNewEm) {
|
|
||||||
logger.debug("Closing new EntityManager after JPA template execution");
|
|
||||||
EntityManagerFactoryUtils.closeEntityManager(em);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a close-suppressing proxy for the given JPA EntityManager.
|
|
||||||
* The proxy also prepares returned JPA Query objects.
|
|
||||||
* @param em the JPA EntityManager to create a proxy for
|
|
||||||
* @return the EntityManager proxy, implementing all interfaces
|
|
||||||
* implemented by the passed-in EntityManager object (that is,
|
|
||||||
* also implementing all provider-specific extension interfaces)
|
|
||||||
* @see javax.persistence.EntityManager#close
|
|
||||||
*/
|
|
||||||
protected EntityManager createEntityManagerProxy(EntityManager em) {
|
|
||||||
Class[] ifcs = null;
|
|
||||||
EntityManagerFactory emf = getEntityManagerFactory();
|
|
||||||
if (emf instanceof EntityManagerFactoryInfo) {
|
|
||||||
Class entityManagerInterface = ((EntityManagerFactoryInfo) emf).getEntityManagerInterface();
|
|
||||||
if (entityManagerInterface != null) {
|
|
||||||
ifcs = new Class[] {entityManagerInterface};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ifcs == null) {
|
|
||||||
ifcs = ClassUtils.getAllInterfacesForClass(em.getClass());
|
|
||||||
}
|
|
||||||
return (EntityManager) Proxy.newProxyInstance(
|
|
||||||
em.getClass().getClassLoader(), ifcs, new CloseSuppressingInvocationHandler(em));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
// Convenience methods for load, save, delete
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public <T> T find(final Class<T> entityClass, final Object id) throws DataAccessException {
|
|
||||||
return execute(new JpaCallback<T>() {
|
|
||||||
public T doInJpa(EntityManager em) throws PersistenceException {
|
|
||||||
return em.find(entityClass, id);
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> T getReference(final Class<T> entityClass, final Object id) throws DataAccessException {
|
|
||||||
return execute(new JpaCallback<T>() {
|
|
||||||
public T doInJpa(EntityManager em) throws PersistenceException {
|
|
||||||
return em.getReference(entityClass, id);
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean contains(final Object entity) throws DataAccessException {
|
|
||||||
return execute(new JpaCallback<Boolean>() {
|
|
||||||
public Boolean doInJpa(EntityManager em) throws PersistenceException {
|
|
||||||
return em.contains(entity);
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void refresh(final Object entity) throws DataAccessException {
|
|
||||||
execute(new JpaCallback<Object>() {
|
|
||||||
public Object doInJpa(EntityManager em) throws PersistenceException {
|
|
||||||
em.refresh(entity);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void persist(final Object entity) throws DataAccessException {
|
|
||||||
execute(new JpaCallback<Object>() {
|
|
||||||
public Object doInJpa(EntityManager em) throws PersistenceException {
|
|
||||||
em.persist(entity);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> T merge(final T entity) throws DataAccessException {
|
|
||||||
return execute(new JpaCallback<T>() {
|
|
||||||
public T doInJpa(EntityManager em) throws PersistenceException {
|
|
||||||
return em.merge(entity);
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void remove(final Object entity) throws DataAccessException {
|
|
||||||
execute(new JpaCallback<Object>() {
|
|
||||||
public Object doInJpa(EntityManager em) throws PersistenceException {
|
|
||||||
em.remove(entity);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void flush() throws DataAccessException {
|
|
||||||
execute(new JpaCallback<Object>() {
|
|
||||||
public Object doInJpa(EntityManager em) throws PersistenceException {
|
|
||||||
em.flush();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
// Convenience finder methods
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public List find(String queryString) throws DataAccessException {
|
|
||||||
return find(queryString, (Object[]) null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List find(final String queryString, final Object... values) throws DataAccessException {
|
|
||||||
return execute(new JpaCallback<List>() {
|
|
||||||
public List doInJpa(EntityManager em) throws PersistenceException {
|
|
||||||
Query queryObject = em.createQuery(queryString);
|
|
||||||
prepareQuery(queryObject);
|
|
||||||
if (values != null) {
|
|
||||||
for (int i = 0; i < values.length; i++) {
|
|
||||||
queryObject.setParameter(i + 1, values[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return queryObject.getResultList();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public List findByNamedParams(final String queryString, final Map<String, ?> params) throws DataAccessException {
|
|
||||||
return execute(new JpaCallback<List>() {
|
|
||||||
public List doInJpa(EntityManager em) throws PersistenceException {
|
|
||||||
Query queryObject = em.createQuery(queryString);
|
|
||||||
prepareQuery(queryObject);
|
|
||||||
if (params != null) {
|
|
||||||
for (Map.Entry<String, ?> entry : params.entrySet()) {
|
|
||||||
queryObject.setParameter(entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return queryObject.getResultList();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public List findByNamedQuery(String queryName) throws DataAccessException {
|
|
||||||
return findByNamedQuery(queryName, (Object[]) null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List findByNamedQuery(final String queryName, final Object... values) throws DataAccessException {
|
|
||||||
return execute(new JpaCallback<List>() {
|
|
||||||
public List doInJpa(EntityManager em) throws PersistenceException {
|
|
||||||
Query queryObject = em.createNamedQuery(queryName);
|
|
||||||
prepareQuery(queryObject);
|
|
||||||
if (values != null) {
|
|
||||||
for (int i = 0; i < values.length; i++) {
|
|
||||||
queryObject.setParameter(i + 1, values[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return queryObject.getResultList();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public List findByNamedQueryAndNamedParams(final String queryName, final Map<String, ?> params)
|
|
||||||
throws DataAccessException {
|
|
||||||
|
|
||||||
return execute(new JpaCallback<List>() {
|
|
||||||
public List doInJpa(EntityManager em) throws PersistenceException {
|
|
||||||
Query queryObject = em.createNamedQuery(queryName);
|
|
||||||
prepareQuery(queryObject);
|
|
||||||
if (params != null) {
|
|
||||||
for (Map.Entry<String, ?> entry : params.entrySet()) {
|
|
||||||
queryObject.setParameter(entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return queryObject.getResultList();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prepare the given JPA query object. To be used within a JpaCallback.
|
|
||||||
* <p>Applies a transaction timeout, if any. If you don't use such timeouts,
|
|
||||||
* the call is a no-op.
|
|
||||||
* <p>In general, prefer a proxied EntityManager instead, which will
|
|
||||||
* automatically apply the transaction timeout (through the use of a special
|
|
||||||
* EntityManager proxy). You need to set the "exposeNativeEntityManager"
|
|
||||||
* property to "false" to activate this. Note that you won't be able to cast
|
|
||||||
* to a provider-specific JPA EntityManager class anymore then.
|
|
||||||
* @param query the JPA query object
|
|
||||||
* @see JpaCallback#doInJpa
|
|
||||||
* @see EntityManagerFactoryUtils#applyTransactionTimeout
|
|
||||||
* @see #setExposeNativeEntityManager
|
|
||||||
*/
|
|
||||||
public void prepareQuery(Query query) {
|
|
||||||
EntityManagerFactory emf = getEntityManagerFactory();
|
|
||||||
if (emf != null) {
|
|
||||||
EntityManagerFactoryUtils.applyTransactionTimeout(query, getEntityManagerFactory());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invocation handler that suppresses close calls on JPA EntityManagers.
|
|
||||||
* Also prepares returned Query objects.
|
|
||||||
* @see javax.persistence.EntityManager#close()
|
|
||||||
*/
|
|
||||||
private class CloseSuppressingInvocationHandler implements InvocationHandler {
|
|
||||||
|
|
||||||
private final EntityManager target;
|
|
||||||
|
|
||||||
public CloseSuppressingInvocationHandler(EntityManager target) {
|
|
||||||
this.target = target;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
|
||||||
// Invocation on EntityManager interface (or provider-specific extension) 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 EntityManager proxy.
|
|
||||||
return System.identityHashCode(proxy);
|
|
||||||
}
|
|
||||||
else if (method.getName().equals("close")) {
|
|
||||||
// Handle close method: suppress, not valid.
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invoke method on target EntityManager.
|
|
||||||
try {
|
|
||||||
Object retVal = method.invoke(this.target, args);
|
|
||||||
// If return value is a JPA Query object, apply transaction timeout.
|
|
||||||
if (retVal instanceof Query) {
|
|
||||||
prepareQuery(((Query) retVal));
|
|
||||||
}
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
catch (InvocationTargetException ex) {
|
|
||||||
throw ex.getTargetException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -55,8 +55,8 @@ import org.springframework.util.CollectionUtils;
|
||||||
* {@link org.springframework.transaction.PlatformTransactionManager} implementation
|
* {@link org.springframework.transaction.PlatformTransactionManager} implementation
|
||||||
* for a single JPA {@link javax.persistence.EntityManagerFactory}. Binds a JPA
|
* for a single JPA {@link javax.persistence.EntityManagerFactory}. Binds a JPA
|
||||||
* EntityManager from the specified factory to the thread, potentially allowing for
|
* EntityManager from the specified factory to the thread, potentially allowing for
|
||||||
* one thread-bound EntityManager per factory. {@link SharedEntityManagerCreator}
|
* one thread-bound EntityManager per factory. {@link SharedEntityManagerCreator} and
|
||||||
* and {@link JpaTemplate} are aware of thread-bound entity managers and participate
|
* {@code @PersistenceContext} are aware of thread-bound entity managers and participate
|
||||||
* in such transactions automatically. Using either is required for JPA access code
|
* in such transactions automatically. Using either is required for JPA access code
|
||||||
* supporting this transaction management mechanism.
|
* supporting this transaction management mechanism.
|
||||||
*
|
*
|
||||||
|
@ -100,7 +100,6 @@ import org.springframework.util.CollectionUtils;
|
||||||
* @see #setEntityManagerFactory
|
* @see #setEntityManagerFactory
|
||||||
* @see #setDataSource
|
* @see #setDataSource
|
||||||
* @see LocalEntityManagerFactoryBean
|
* @see LocalEntityManagerFactoryBean
|
||||||
* @see JpaTemplate#execute
|
|
||||||
* @see org.springframework.orm.jpa.support.SharedEntityManagerBean
|
* @see org.springframework.orm.jpa.support.SharedEntityManagerBean
|
||||||
* @see org.springframework.jdbc.datasource.DataSourceUtils#getConnection
|
* @see org.springframework.jdbc.datasource.DataSourceUtils#getConnection
|
||||||
* @see org.springframework.jdbc.datasource.DataSourceUtils#releaseConnection
|
* @see org.springframework.jdbc.datasource.DataSourceUtils#releaseConnection
|
||||||
|
|
|
@ -65,6 +65,8 @@ import org.springframework.util.ClassUtils;
|
||||||
* plus the {@link EntityManagerFactoryInfo} interface which exposes additional
|
* plus the {@link EntityManagerFactoryInfo} interface which exposes additional
|
||||||
* metadata as assembled by this FactoryBean.
|
* metadata as assembled by this FactoryBean.
|
||||||
*
|
*
|
||||||
|
* <p><b>NOTE: Spring's JPA support requires JPA 2.0 or higher, as of Spring 4.0.</b>
|
||||||
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @author Rod Johnson
|
* @author Rod Johnson
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2013 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -52,12 +52,13 @@ import javax.persistence.spi.PersistenceProvider;
|
||||||
* to the JPA provider, consider using Spring's more powerful
|
* to the JPA provider, consider using Spring's more powerful
|
||||||
* {@link LocalContainerEntityManagerFactoryBean} instead.
|
* {@link LocalContainerEntityManagerFactoryBean} instead.
|
||||||
*
|
*
|
||||||
|
* <p><b>NOTE: Spring's JPA support requires JPA 2.0 or higher, as of Spring 4.0.</b>
|
||||||
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @author Rod Johnson
|
* @author Rod Johnson
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
* @see #setJpaProperties
|
* @see #setJpaProperties
|
||||||
* @see #setJpaVendorAdapter
|
* @see #setJpaVendorAdapter
|
||||||
* @see JpaTemplate#setEntityManagerFactory
|
|
||||||
* @see JpaTransactionManager#setEntityManagerFactory
|
* @see JpaTransactionManager#setEntityManagerFactory
|
||||||
* @see LocalContainerEntityManagerFactoryBean
|
* @see LocalContainerEntityManagerFactoryBean
|
||||||
* @see org.springframework.jndi.JndiObjectFactoryBean
|
* @see org.springframework.jndi.JndiObjectFactoryBean
|
||||||
|
|
|
@ -56,9 +56,6 @@ public abstract class SharedEntityManagerCreator {
|
||||||
* Create a transactional EntityManager proxy for the given EntityManagerFactory,
|
* Create a transactional EntityManager proxy for the given EntityManagerFactory,
|
||||||
* automatically joining ongoing transactions.
|
* automatically joining ongoing transactions.
|
||||||
* @param emf the EntityManagerFactory to delegate to.
|
* @param emf the EntityManagerFactory to delegate to.
|
||||||
* If this implements the {@link EntityManagerFactoryInfo} interface,
|
|
||||||
* appropriate handling of the native EntityManagerFactory and available
|
|
||||||
* {@link EntityManagerPlusOperations} will automatically apply.
|
|
||||||
* @return a shareable transaction EntityManager proxy
|
* @return a shareable transaction EntityManager proxy
|
||||||
*/
|
*/
|
||||||
public static EntityManager createSharedEntityManager(EntityManagerFactory emf) {
|
public static EntityManager createSharedEntityManager(EntityManagerFactory emf) {
|
||||||
|
@ -68,9 +65,6 @@ public abstract class SharedEntityManagerCreator {
|
||||||
/**
|
/**
|
||||||
* Create a transactional EntityManager proxy for the given EntityManagerFactory.
|
* Create a transactional EntityManager proxy for the given EntityManagerFactory.
|
||||||
* @param emf the EntityManagerFactory to delegate to.
|
* @param emf the EntityManagerFactory to delegate to.
|
||||||
* If this implements the {@link EntityManagerFactoryInfo} interface,
|
|
||||||
* appropriate handling of the native EntityManagerFactory and available
|
|
||||||
* {@link EntityManagerPlusOperations} will automatically apply.
|
|
||||||
* @param properties the properties to be passed into the
|
* @param properties the properties to be passed into the
|
||||||
* {@code createEntityManager} call (may be {@code null})
|
* {@code createEntityManager} call (may be {@code null})
|
||||||
* @return a shareable transaction EntityManager proxy
|
* @return a shareable transaction EntityManager proxy
|
||||||
|
@ -82,9 +76,6 @@ public abstract class SharedEntityManagerCreator {
|
||||||
/**
|
/**
|
||||||
* Create a transactional EntityManager proxy for the given EntityManagerFactory.
|
* Create a transactional EntityManager proxy for the given EntityManagerFactory.
|
||||||
* @param emf the EntityManagerFactory to delegate to.
|
* @param emf the EntityManagerFactory to delegate to.
|
||||||
* If this implements the {@link EntityManagerFactoryInfo} interface,
|
|
||||||
* appropriate handling of the native EntityManagerFactory and available
|
|
||||||
* {@link EntityManagerPlusOperations} will automatically apply.
|
|
||||||
* @param properties the properties to be passed into the
|
* @param properties the properties to be passed into the
|
||||||
* {@code createEntityManager} call (may be {@code null})
|
* {@code createEntityManager} call (may be {@code null})
|
||||||
* @param synchronizedWithTransaction whether to automatically join ongoing
|
* @param synchronizedWithTransaction whether to automatically join ongoing
|
||||||
|
@ -94,25 +85,9 @@ public abstract class SharedEntityManagerCreator {
|
||||||
public static EntityManager createSharedEntityManager(
|
public static EntityManager createSharedEntityManager(
|
||||||
EntityManagerFactory emf, Map properties, boolean synchronizedWithTransaction) {
|
EntityManagerFactory emf, Map properties, boolean synchronizedWithTransaction) {
|
||||||
|
|
||||||
Class[] emIfcs;
|
Class emIfc = (emf instanceof EntityManagerFactoryInfo ?
|
||||||
if (emf instanceof EntityManagerFactoryInfo) {
|
((EntityManagerFactoryInfo) emf).getEntityManagerInterface() : EntityManager.class);
|
||||||
EntityManagerFactoryInfo emfInfo = (EntityManagerFactoryInfo) emf;
|
return createSharedEntityManager(emf, properties, synchronizedWithTransaction, emIfc);
|
||||||
Class emIfc = emfInfo.getEntityManagerInterface();
|
|
||||||
if (emIfc == null) {
|
|
||||||
emIfc = EntityManager.class;
|
|
||||||
}
|
|
||||||
JpaDialect jpaDialect = emfInfo.getJpaDialect();
|
|
||||||
if (jpaDialect != null && jpaDialect.supportsEntityManagerPlusOperations()) {
|
|
||||||
emIfcs = new Class[] {emIfc, EntityManagerPlus.class};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
emIfcs = new Class[] {emIfc};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
emIfcs = new Class[] {EntityManager.class};
|
|
||||||
}
|
|
||||||
return createSharedEntityManager(emf, properties, synchronizedWithTransaction, emIfcs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,127 +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.jpa.support;
|
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
import javax.persistence.EntityManagerFactory;
|
|
||||||
|
|
||||||
import org.springframework.dao.support.DaoSupport;
|
|
||||||
import org.springframework.orm.jpa.JpaTemplate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convenient super class for JPA data access objects. Intended for
|
|
||||||
* JpaTemplate usage. Alternatively, JPA-based DAOs can be coded
|
|
||||||
* against the plain JPA EntityManagerFactory/EntityManager API.
|
|
||||||
*
|
|
||||||
* <p>Requires an EntityManagerFactory or EntityManager to be set,
|
|
||||||
* providing a JpaTemplate based on it to subclasses. Can alternatively
|
|
||||||
* be initialized directly via a JpaTemplate, to reuse the latter's
|
|
||||||
* settings such as the EntityManagerFactory, JpaDialect, flush mode, etc.
|
|
||||||
*
|
|
||||||
* <p>This class will create its own JpaTemplate if an EntityManagerFactory
|
|
||||||
* or EntityManager reference is passed in. A custom JpaTemplate instance
|
|
||||||
* can be used through overriding {@code createJpaTemplate}.
|
|
||||||
*
|
|
||||||
* @author Juergen Hoeller
|
|
||||||
* @since 2.0
|
|
||||||
* @see #setEntityManagerFactory
|
|
||||||
* @see #setEntityManager
|
|
||||||
* @see #createJpaTemplate
|
|
||||||
* @see #setJpaTemplate
|
|
||||||
* @see org.springframework.orm.jpa.JpaTemplate
|
|
||||||
* @deprecated as of Spring 3.1, in favor of native EntityManager usage
|
|
||||||
* (typically obtained through {@code @PersistenceContext})
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public abstract class JpaDaoSupport extends DaoSupport {
|
|
||||||
|
|
||||||
private JpaTemplate jpaTemplate;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the JPA EntityManagerFactory to be used by this DAO.
|
|
||||||
* Will automatically create a JpaTemplate for the given EntityManagerFactory.
|
|
||||||
* @see #createJpaTemplate
|
|
||||||
* @see #setJpaTemplate
|
|
||||||
*/
|
|
||||||
public final void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
|
|
||||||
if (this.jpaTemplate == null || entityManagerFactory != this.jpaTemplate.getEntityManagerFactory()) {
|
|
||||||
this.jpaTemplate = createJpaTemplate(entityManagerFactory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a JpaTemplate for the given EntityManagerFactory.
|
|
||||||
* Only invoked if populating the DAO with a EntityManagerFactory reference!
|
|
||||||
* <p>Can be overridden in subclasses to provide a JpaTemplate instance
|
|
||||||
* with different configuration, or a custom JpaTemplate subclass.
|
|
||||||
* @param entityManagerFactory the JPA EntityManagerFactory to create a JpaTemplate for
|
|
||||||
* @return the new JpaTemplate instance
|
|
||||||
* @see #setEntityManagerFactory
|
|
||||||
*/
|
|
||||||
protected JpaTemplate createJpaTemplate(EntityManagerFactory entityManagerFactory) {
|
|
||||||
return new JpaTemplate(entityManagerFactory);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the JPA EntityManager to be used by this DAO.
|
|
||||||
* Will automatically create a JpaTemplate for the given EntityManager.
|
|
||||||
* @see #createJpaTemplate
|
|
||||||
* @see #setJpaTemplate
|
|
||||||
*/
|
|
||||||
public final void setEntityManager(EntityManager entityManager) {
|
|
||||||
this.jpaTemplate = createJpaTemplate(entityManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a JpaTemplate for the given EntityManager.
|
|
||||||
* Only invoked if populating the DAO with a EntityManager reference!
|
|
||||||
* <p>Can be overridden in subclasses to provide a JpaTemplate instance
|
|
||||||
* with different configuration, or a custom JpaTemplate subclass.
|
|
||||||
* @param entityManager the JPA EntityManager to create a JpaTemplate for
|
|
||||||
* @return the new JpaTemplate instance
|
|
||||||
* @see #setEntityManagerFactory
|
|
||||||
*/
|
|
||||||
protected JpaTemplate createJpaTemplate(EntityManager entityManager) {
|
|
||||||
return new JpaTemplate(entityManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the JpaTemplate for this DAO explicitly,
|
|
||||||
* as an alternative to specifying a EntityManagerFactory.
|
|
||||||
* @see #setEntityManagerFactory
|
|
||||||
*/
|
|
||||||
public final void setJpaTemplate(JpaTemplate jpaTemplate) {
|
|
||||||
this.jpaTemplate = jpaTemplate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the JpaTemplate for this DAO, pre-initialized
|
|
||||||
* with the EntityManagerFactory or set explicitly.
|
|
||||||
*/
|
|
||||||
public final JpaTemplate getJpaTemplate() {
|
|
||||||
return jpaTemplate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected final void checkDaoConfig() {
|
|
||||||
if (this.jpaTemplate == null) {
|
|
||||||
throw new IllegalArgumentException("entityManagerFactory or jpaTemplate is required");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -61,9 +61,7 @@ import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
* @see OpenEntityManagerInViewInterceptor
|
* @see OpenEntityManagerInViewInterceptor
|
||||||
* @see org.springframework.orm.jpa.JpaInterceptor
|
|
||||||
* @see org.springframework.orm.jpa.JpaTransactionManager
|
* @see org.springframework.orm.jpa.JpaTransactionManager
|
||||||
* @see org.springframework.orm.jpa.JpaTemplate#execute
|
|
||||||
* @see org.springframework.orm.jpa.SharedEntityManagerCreator
|
* @see org.springframework.orm.jpa.SharedEntityManagerCreator
|
||||||
* @see org.springframework.transaction.support.TransactionSynchronizationManager
|
* @see org.springframework.transaction.support.TransactionSynchronizationManager
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2013 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -17,7 +17,6 @@
|
||||||
package org.springframework.orm.jpa.support;
|
package org.springframework.orm.jpa.support;
|
||||||
|
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
import javax.persistence.PersistenceException;
|
import javax.persistence.PersistenceException;
|
||||||
|
|
||||||
|
@ -49,16 +48,12 @@ import org.springframework.web.context.request.async.WebAsyncUtils;
|
||||||
*
|
*
|
||||||
* <p>In contrast to {@link OpenEntityManagerInViewFilter}, this interceptor
|
* <p>In contrast to {@link OpenEntityManagerInViewFilter}, this interceptor
|
||||||
* is set up in a Spring application context and can thus take advantage of
|
* is set up in a Spring application context and can thus take advantage of
|
||||||
* bean wiring. It inherits common JPA configuration properties from
|
* bean wiring.
|
||||||
* {@link org.springframework.orm.jpa.JpaAccessor}, to be configured in a
|
|
||||||
* bean definition.
|
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
* @see OpenEntityManagerInViewFilter
|
* @see OpenEntityManagerInViewFilter
|
||||||
* @see org.springframework.orm.jpa.JpaInterceptor
|
|
||||||
* @see org.springframework.orm.jpa.JpaTransactionManager
|
* @see org.springframework.orm.jpa.JpaTransactionManager
|
||||||
* @see org.springframework.orm.jpa.JpaTemplate#execute
|
|
||||||
* @see org.springframework.orm.jpa.SharedEntityManagerCreator
|
* @see org.springframework.orm.jpa.SharedEntityManagerCreator
|
||||||
* @see org.springframework.transaction.support.TransactionSynchronizationManager
|
* @see org.springframework.transaction.support.TransactionSynchronizationManager
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -23,8 +23,6 @@ import org.springframework.beans.factory.FactoryBean;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.springframework.orm.jpa.EntityManagerFactoryAccessor;
|
import org.springframework.orm.jpa.EntityManagerFactoryAccessor;
|
||||||
import org.springframework.orm.jpa.EntityManagerFactoryInfo;
|
import org.springframework.orm.jpa.EntityManagerFactoryInfo;
|
||||||
import org.springframework.orm.jpa.EntityManagerPlus;
|
|
||||||
import org.springframework.orm.jpa.JpaDialect;
|
|
||||||
import org.springframework.orm.jpa.SharedEntityManagerCreator;
|
import org.springframework.orm.jpa.SharedEntityManagerCreator;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
@ -88,7 +86,6 @@ public class SharedEntityManagerBean extends EntityManagerFactoryAccessor
|
||||||
if (emf == null) {
|
if (emf == null) {
|
||||||
throw new IllegalArgumentException("'entityManagerFactory' or 'persistenceUnitName' is required");
|
throw new IllegalArgumentException("'entityManagerFactory' or 'persistenceUnitName' is required");
|
||||||
}
|
}
|
||||||
Class[] ifcs = null;
|
|
||||||
if (emf instanceof EntityManagerFactoryInfo) {
|
if (emf instanceof EntityManagerFactoryInfo) {
|
||||||
EntityManagerFactoryInfo emfInfo = (EntityManagerFactoryInfo) emf;
|
EntityManagerFactoryInfo emfInfo = (EntityManagerFactoryInfo) emf;
|
||||||
if (this.entityManagerInterface == null) {
|
if (this.entityManagerInterface == null) {
|
||||||
|
@ -97,22 +94,14 @@ public class SharedEntityManagerBean extends EntityManagerFactoryAccessor
|
||||||
this.entityManagerInterface = EntityManager.class;
|
this.entityManagerInterface = EntityManager.class;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
JpaDialect jpaDialect = emfInfo.getJpaDialect();
|
|
||||||
if (jpaDialect != null && jpaDialect.supportsEntityManagerPlusOperations()) {
|
|
||||||
ifcs = new Class[] {this.entityManagerInterface, EntityManagerPlus.class};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ifcs = new Class[] {this.entityManagerInterface};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (this.entityManagerInterface == null) {
|
if (this.entityManagerInterface == null) {
|
||||||
this.entityManagerInterface = EntityManager.class;
|
this.entityManagerInterface = EntityManager.class;
|
||||||
}
|
}
|
||||||
ifcs = new Class[] {this.entityManagerInterface};
|
|
||||||
}
|
}
|
||||||
this.shared = SharedEntityManagerCreator.createSharedEntityManager(
|
this.shared = SharedEntityManagerCreator.createSharedEntityManager(
|
||||||
emf, getJpaPropertyMap(), this.synchronizedWithTransaction, ifcs);
|
emf, getJpaPropertyMap(), this.synchronizedWithTransaction, this.entityManagerInterface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Classes supporting the {@code org.springframework.orm.jpa} package.
|
* Classes supporting the {@code org.springframework.orm.jpa} package.
|
||||||
* Contains a DAO base class for JpaTemplate usage.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
package org.springframework.orm.jpa.support;
|
package org.springframework.orm.jpa.support;
|
||||||
|
|
|
@ -1,267 +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.jpa;
|
|
||||||
|
|
||||||
import java.lang.reflect.AccessibleObject;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
import javax.persistence.EntityManagerFactory;
|
|
||||||
import javax.persistence.PersistenceException;
|
|
||||||
|
|
||||||
import org.aopalliance.intercept.Interceptor;
|
|
||||||
import org.aopalliance.intercept.Invocation;
|
|
||||||
import org.aopalliance.intercept.MethodInvocation;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
import static org.mockito.BDDMockito.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Costin Leau
|
|
||||||
* @author Phillip Webb
|
|
||||||
*/
|
|
||||||
public class JpaInterceptorTests {
|
|
||||||
|
|
||||||
private EntityManagerFactory factory;
|
|
||||||
|
|
||||||
private EntityManager entityManager;
|
|
||||||
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
factory = mock(EntityManagerFactory.class);
|
|
||||||
entityManager = mock(EntityManager.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void tearDown() throws Exception {
|
|
||||||
assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty());
|
|
||||||
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testInterceptorWithNewEntityManager() throws PersistenceException {
|
|
||||||
given(factory.createEntityManager()).willReturn(entityManager);
|
|
||||||
given(entityManager.isOpen()).willReturn(true);
|
|
||||||
|
|
||||||
JpaInterceptor interceptor = new JpaInterceptor();
|
|
||||||
interceptor.setEntityManagerFactory(factory);
|
|
||||||
try {
|
|
||||||
interceptor.invoke(new TestInvocation(factory));
|
|
||||||
}
|
|
||||||
catch (Throwable t) {
|
|
||||||
fail("Should not have thrown Throwable: " + t.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
verify(entityManager).close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testInterceptorWithNewEntityManagerAndLazyFlush() throws PersistenceException {
|
|
||||||
given(factory.createEntityManager()).willReturn(entityManager);
|
|
||||||
given(entityManager.isOpen()).willReturn(true);
|
|
||||||
|
|
||||||
JpaInterceptor interceptor = new JpaInterceptor();
|
|
||||||
interceptor.setFlushEager(false);
|
|
||||||
interceptor.setEntityManagerFactory(factory);
|
|
||||||
try {
|
|
||||||
interceptor.invoke(new TestInvocation(factory));
|
|
||||||
}
|
|
||||||
catch (Throwable t) {
|
|
||||||
fail("Should not have thrown Throwable: " + t.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
verify(entityManager).close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testInterceptorWithThreadBound() {
|
|
||||||
TransactionSynchronizationManager.bindResource(factory, new EntityManagerHolder(entityManager));
|
|
||||||
JpaInterceptor interceptor = new JpaInterceptor();
|
|
||||||
interceptor.setEntityManagerFactory(factory);
|
|
||||||
try {
|
|
||||||
interceptor.invoke(new TestInvocation(factory));
|
|
||||||
}
|
|
||||||
catch (Throwable t) {
|
|
||||||
fail("Should not have thrown Throwable: " + t.getMessage());
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
TransactionSynchronizationManager.unbindResource(factory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testInterceptorWithThreadBoundAndFlushEager() throws PersistenceException {
|
|
||||||
TransactionSynchronizationManager.bindResource(factory, new EntityManagerHolder(entityManager));
|
|
||||||
JpaInterceptor interceptor = new JpaInterceptor();
|
|
||||||
interceptor.setFlushEager(true);
|
|
||||||
interceptor.setEntityManagerFactory(factory);
|
|
||||||
try {
|
|
||||||
interceptor.invoke(new TestInvocation(factory));
|
|
||||||
}
|
|
||||||
catch (Throwable t) {
|
|
||||||
fail("Should not have thrown Throwable: " + t.getMessage());
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
TransactionSynchronizationManager.unbindResource(factory);
|
|
||||||
}
|
|
||||||
|
|
||||||
verify(entityManager).flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testInterceptorWithThreadBoundAndFlushCommit() {
|
|
||||||
TransactionSynchronizationManager.bindResource(factory, new EntityManagerHolder(entityManager));
|
|
||||||
JpaInterceptor interceptor = new JpaInterceptor();
|
|
||||||
interceptor.setFlushEager(false);
|
|
||||||
interceptor.setEntityManagerFactory(factory);
|
|
||||||
try {
|
|
||||||
interceptor.invoke(new TestInvocation(factory));
|
|
||||||
}
|
|
||||||
catch (Throwable t) {
|
|
||||||
fail("Should not have thrown Throwable: " + t.getMessage());
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
TransactionSynchronizationManager.unbindResource(factory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testInterceptorWithFlushFailure() throws Throwable {
|
|
||||||
given(factory.createEntityManager()).willReturn(entityManager);
|
|
||||||
|
|
||||||
PersistenceException exception = new PersistenceException();
|
|
||||||
willThrow(exception).given(entityManager).flush();
|
|
||||||
given(entityManager.isOpen()).willReturn(true);
|
|
||||||
|
|
||||||
JpaInterceptor interceptor = new JpaInterceptor();
|
|
||||||
interceptor.setFlushEager(true);
|
|
||||||
interceptor.setEntityManagerFactory(factory);
|
|
||||||
try {
|
|
||||||
interceptor.invoke(new TestInvocation(factory));
|
|
||||||
//fail("Should have thrown JpaSystemException");
|
|
||||||
}
|
|
||||||
catch (JpaSystemException ex) {
|
|
||||||
// expected
|
|
||||||
assertEquals(exception, ex.getCause());
|
|
||||||
}
|
|
||||||
|
|
||||||
verify(entityManager).close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testInterceptorWithFlushFailureWithoutConversion() throws Throwable {
|
|
||||||
given(factory.createEntityManager()).willReturn(entityManager);
|
|
||||||
|
|
||||||
PersistenceException exception = new PersistenceException();
|
|
||||||
willThrow(exception).given(entityManager).flush();
|
|
||||||
given(entityManager.isOpen()).willReturn(true);
|
|
||||||
|
|
||||||
JpaInterceptor interceptor = new JpaInterceptor();
|
|
||||||
interceptor.setFlushEager(true);
|
|
||||||
interceptor.setExceptionConversionEnabled(false);
|
|
||||||
interceptor.setEntityManagerFactory(factory);
|
|
||||||
try {
|
|
||||||
interceptor.invoke(new TestInvocation(factory));
|
|
||||||
//fail("Should have thrown JpaSystemException");
|
|
||||||
}
|
|
||||||
catch (PersistenceException ex) {
|
|
||||||
// expected
|
|
||||||
assertEquals(exception, ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
verify(entityManager).close();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private static class TestInvocation implements MethodInvocation {
|
|
||||||
|
|
||||||
private EntityManagerFactory entityManagerFactory;
|
|
||||||
|
|
||||||
public TestInvocation(EntityManagerFactory entityManagerFactory) {
|
|
||||||
this.entityManagerFactory = entityManagerFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object proceed() throws Throwable {
|
|
||||||
if (!TransactionSynchronizationManager.hasResource(this.entityManagerFactory)) {
|
|
||||||
throw new IllegalStateException("Session not bound");
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCurrentInterceptorIndex() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getNumberOfInterceptors() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Interceptor getInterceptor(int i) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Method getMethod() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AccessibleObject getStaticPart() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object getArgument(int i) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object[] getArguments() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setArgument(int i, Object handler) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getArgumentCount() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getThis() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object getProxy() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Invocation cloneInstance() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void release() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,412 +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.jpa;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
import javax.persistence.EntityManagerFactory;
|
|
||||||
import javax.persistence.PersistenceException;
|
|
||||||
import javax.persistence.Query;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.springframework.dao.DataAccessException;
|
|
||||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
import static org.mockito.BDDMockito.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Costin Leau
|
|
||||||
* @author Phillip Webb
|
|
||||||
*/
|
|
||||||
public class JpaTemplateTests {
|
|
||||||
|
|
||||||
private JpaTemplate template;
|
|
||||||
|
|
||||||
private EntityManager manager;
|
|
||||||
|
|
||||||
private EntityManagerFactory factory;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
template = new JpaTemplate();
|
|
||||||
|
|
||||||
factory = mock(EntityManagerFactory.class);
|
|
||||||
manager = mock(EntityManager.class);
|
|
||||||
|
|
||||||
template.setEntityManager(manager);
|
|
||||||
template.afterPropertiesSet();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Test method for
|
|
||||||
* 'org.springframework.orm.jpa.JpaTemplate.JpaTemplate(EntityManagerFactory)'
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testJpaTemplateEntityManagerFactory() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Test method for
|
|
||||||
* 'org.springframework.orm.jpa.JpaTemplate.JpaTemplate(EntityManager)'
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testJpaTemplateEntityManager() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Test method for
|
|
||||||
* 'org.springframework.orm.jpa.JpaTemplate.execute(JpaCallback)'
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testExecuteJpaCallback() {
|
|
||||||
template.setExposeNativeEntityManager(true);
|
|
||||||
template.setEntityManager(manager);
|
|
||||||
template.afterPropertiesSet();
|
|
||||||
|
|
||||||
template.execute(new JpaCallback() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object doInJpa(EntityManager em) throws PersistenceException {
|
|
||||||
assertSame(em, manager);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
template.setExposeNativeEntityManager(false);
|
|
||||||
template.execute(new JpaCallback() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object doInJpa(EntityManager em) throws PersistenceException {
|
|
||||||
assertNotSame(em, manager);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Test method for
|
|
||||||
* 'org.springframework.orm.jpa.JpaTemplate.executeFind(JpaCallback)'
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testExecuteFind() {
|
|
||||||
template.setEntityManager(manager);
|
|
||||||
template.setExposeNativeEntityManager(true);
|
|
||||||
template.afterPropertiesSet();
|
|
||||||
|
|
||||||
try {
|
|
||||||
template.executeFind(new JpaCallback() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object doInJpa(EntityManager em) throws PersistenceException {
|
|
||||||
assertSame(em, manager);
|
|
||||||
return new Object();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
fail("should have thrown exception");
|
|
||||||
}
|
|
||||||
catch (DataAccessException e) {
|
|
||||||
// expected
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Test method for
|
|
||||||
* 'org.springframework.orm.jpa.JpaTemplate.execute(JpaCallback, boolean)'
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testExecuteJpaCallbackBoolean() {
|
|
||||||
template = new JpaTemplate();
|
|
||||||
template.setExposeNativeEntityManager(false);
|
|
||||||
template.setEntityManagerFactory(factory);
|
|
||||||
template.afterPropertiesSet();
|
|
||||||
|
|
||||||
given(factory.createEntityManager()).willReturn(manager);
|
|
||||||
given(manager.isOpen()).willReturn(true);
|
|
||||||
manager.close();
|
|
||||||
|
|
||||||
template.execute(new JpaCallback() {
|
|
||||||
@Override
|
|
||||||
public Object doInJpa(EntityManager em) throws PersistenceException {
|
|
||||||
assertSame(em, manager);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testExecuteJpaCallbackBooleanWithPrebound() {
|
|
||||||
template.setExposeNativeEntityManager(false);
|
|
||||||
template.setEntityManagerFactory(factory);
|
|
||||||
template.afterPropertiesSet();
|
|
||||||
|
|
||||||
TransactionSynchronizationManager.bindResource(factory, new EntityManagerHolder(manager));
|
|
||||||
|
|
||||||
try {
|
|
||||||
template.execute(new JpaCallback() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object doInJpa(EntityManager em) throws PersistenceException {
|
|
||||||
assertSame(em, manager);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
TransactionSynchronizationManager.unbindResource(factory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Test method for
|
|
||||||
* 'org.springframework.orm.jpa.JpaTemplate.createSharedEntityManager(EntityManager)'
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testCreateEntityManagerProxy() {
|
|
||||||
|
|
||||||
EntityManager proxy = template.createEntityManagerProxy(manager);
|
|
||||||
assertNotSame(manager, proxy);
|
|
||||||
assertFalse(manager.equals(proxy));
|
|
||||||
assertFalse(manager.hashCode() == proxy.hashCode());
|
|
||||||
// close call not propagated to the em
|
|
||||||
proxy.close();
|
|
||||||
proxy.clear();
|
|
||||||
|
|
||||||
verify(manager).clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Test method for 'org.springframework.orm.jpa.JpaTemplate.find(Class<T>,
|
|
||||||
* Object) <T>'
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testFindClassOfTObject() {
|
|
||||||
Integer result = new Integer(1);
|
|
||||||
Object id = new Object();
|
|
||||||
given(manager.find(Number.class, id)).willReturn(result);
|
|
||||||
|
|
||||||
assertSame(result, template.find(Number.class, id));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Test method for
|
|
||||||
* 'org.springframework.orm.jpa.JpaTemplate.getReference(Class<T>, Object)
|
|
||||||
* <T>'
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testGetReference() {
|
|
||||||
Integer reference = new Integer(1);
|
|
||||||
Object id = new Object();
|
|
||||||
given(manager.getReference(Number.class, id)).willReturn(reference);
|
|
||||||
|
|
||||||
assertSame(reference, template.getReference(Number.class, id));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Test method for
|
|
||||||
* 'org.springframework.orm.jpa.JpaTemplate.contains(Object)'
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testContains() {
|
|
||||||
boolean result = true;
|
|
||||||
Object entity = new Object();
|
|
||||||
given(manager.contains(entity)).willReturn(result);
|
|
||||||
|
|
||||||
assertSame(result, template.contains(entity));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Test method for 'org.springframework.orm.jpa.JpaTemplate.refresh(Object)'
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testRefresh() {
|
|
||||||
Object entity = new Object();
|
|
||||||
template.refresh(entity);
|
|
||||||
verify(manager).refresh(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Test method for 'org.springframework.orm.jpa.JpaTemplate.persist(Object)'
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testPersist() {
|
|
||||||
Object entity = new Object();
|
|
||||||
template.persist(entity);
|
|
||||||
verify(manager).persist(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Test method for 'org.springframework.orm.jpa.JpaTemplate.merge(T) <T>'
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testMerge() {
|
|
||||||
Object result = new Object();
|
|
||||||
Object entity = new Object();
|
|
||||||
given(manager.merge(entity)).willReturn(result);
|
|
||||||
assertSame(result, template.merge(entity));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Test method for 'org.springframework.orm.jpa.JpaTemplate.remove(Object)'
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testRemove() {
|
|
||||||
Object entity = new Object();
|
|
||||||
template.remove(entity);
|
|
||||||
verify(manager).remove(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Test method for 'org.springframework.orm.jpa.JpaTemplate.flush()'
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testFlush() {
|
|
||||||
template.flush();
|
|
||||||
verify(manager).flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Test method for 'org.springframework.orm.jpa.JpaTemplate.find(String)'
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testFindString() {
|
|
||||||
String queryString = "some query";
|
|
||||||
Query query = mock(Query.class);
|
|
||||||
List result = new ArrayList();
|
|
||||||
|
|
||||||
given(manager.createQuery(queryString)).willReturn(query);
|
|
||||||
given(query.getResultList()).willReturn(result);
|
|
||||||
assertSame(result, template.find(queryString));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Test method for 'org.springframework.orm.jpa.JpaTemplate.find(String,
|
|
||||||
* Object...)'
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testFindStringObjectArray() {
|
|
||||||
String queryString = "some query";
|
|
||||||
Query query = mock(Query.class);
|
|
||||||
List result = new ArrayList();
|
|
||||||
Object param1 = new Object();
|
|
||||||
Object param2 = new Object();
|
|
||||||
Object[] params = new Object[] { param1, param2 };
|
|
||||||
|
|
||||||
given(manager.createQuery(queryString)).willReturn(query);
|
|
||||||
given(query.getResultList()).willReturn(result);
|
|
||||||
|
|
||||||
assertSame(result, template.find(queryString, params));
|
|
||||||
|
|
||||||
verify(query).setParameter(1, param1);
|
|
||||||
verify(query).setParameter(2, param2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Test method for 'org.springframework.orm.jpa.JpaTemplate.find(String, Map<String,
|
|
||||||
* Object>)'
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testFindStringMapOfStringObject() {
|
|
||||||
String queryString = "some query";
|
|
||||||
Query query = mock(Query.class);
|
|
||||||
List result = new ArrayList();
|
|
||||||
Object param1 = new Object();
|
|
||||||
Object param2 = new Object();
|
|
||||||
Map<String, Object> params = new HashMap<String, Object>();
|
|
||||||
params.put("param1", param1);
|
|
||||||
params.put("param2", param2);
|
|
||||||
|
|
||||||
given(manager.createQuery(queryString)).willReturn(query);
|
|
||||||
given(query.getResultList()).willReturn(result);
|
|
||||||
|
|
||||||
assertSame(result, template.findByNamedParams(queryString, params));
|
|
||||||
|
|
||||||
verify(query).setParameter("param1", param1);
|
|
||||||
verify(query).setParameter("param2", param2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Test method for
|
|
||||||
* 'org.springframework.orm.jpa.JpaTemplate.findByNamedQuery(String)'
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testFindByNamedQueryString() {
|
|
||||||
String queryName = "some query name";
|
|
||||||
Query query = mock(Query.class);
|
|
||||||
List result = new ArrayList();
|
|
||||||
|
|
||||||
given(manager.createNamedQuery(queryName)).willReturn(query);
|
|
||||||
given(query.getResultList()).willReturn(result);
|
|
||||||
|
|
||||||
assertSame(result, template.findByNamedQuery(queryName));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Test method for
|
|
||||||
* 'org.springframework.orm.jpa.JpaTemplate.findByNamedQuery(String,
|
|
||||||
* Object...)'
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testFindByNamedQueryStringObjectArray() {
|
|
||||||
String queryName = "some query name";
|
|
||||||
Query query = mock(Query.class);
|
|
||||||
List result = new ArrayList();
|
|
||||||
Object param1 = new Object();
|
|
||||||
Object param2 = new Object();
|
|
||||||
Object[] params = new Object[] { param1, param2 };
|
|
||||||
|
|
||||||
given(manager.createNamedQuery(queryName)).willReturn(query);
|
|
||||||
given(query.getResultList()).willReturn(result);
|
|
||||||
|
|
||||||
assertSame(result, template.findByNamedQuery(queryName, params));
|
|
||||||
|
|
||||||
verify(query).setParameter(1, param1);
|
|
||||||
verify(query).setParameter(2, param2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Test method for
|
|
||||||
* 'org.springframework.orm.jpa.JpaTemplate.findByNamedQuery(String, Map<String,
|
|
||||||
* Object>)'
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testFindByNamedQueryStringMapOfStringObject() {
|
|
||||||
String queryName = "some query name";
|
|
||||||
Query query = mock(Query.class);
|
|
||||||
List result = new ArrayList();
|
|
||||||
Object param1 = new Object();
|
|
||||||
Object param2 = new Object();
|
|
||||||
Map<String, Object> params = new HashMap<String, Object>();
|
|
||||||
params.put("param1", param1);
|
|
||||||
params.put("param2", param2);
|
|
||||||
|
|
||||||
given(manager.createNamedQuery(queryName)).willReturn(query);
|
|
||||||
given(query.getResultList()).willReturn(result);
|
|
||||||
|
|
||||||
assertSame(result, template.findByNamedQueryAndNamedParams(queryName, params));
|
|
||||||
verify(query).setParameter("param1", param1);
|
|
||||||
verify(query).setParameter("param2", param2);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -58,8 +58,6 @@ public class JpaTransactionManagerTests {
|
||||||
|
|
||||||
private JpaTransactionManager transactionManager;
|
private JpaTransactionManager transactionManager;
|
||||||
|
|
||||||
private JpaTemplate template;
|
|
||||||
|
|
||||||
private TransactionTemplate tt;
|
private TransactionTemplate tt;
|
||||||
|
|
||||||
|
|
||||||
|
@ -70,8 +68,6 @@ public class JpaTransactionManagerTests {
|
||||||
tx = mock(EntityTransaction.class);
|
tx = mock(EntityTransaction.class);
|
||||||
|
|
||||||
transactionManager = new JpaTransactionManager(factory);
|
transactionManager = new JpaTransactionManager(factory);
|
||||||
template = new JpaTemplate(factory);
|
|
||||||
template.afterPropertiesSet();
|
|
||||||
tt = new TransactionTemplate(transactionManager);
|
tt = new TransactionTemplate(transactionManager);
|
||||||
|
|
||||||
given(factory.createEntityManager()).willReturn(manager);
|
given(factory.createEntityManager()).willReturn(manager);
|
||||||
|
@ -101,15 +97,10 @@ public class JpaTransactionManagerTests {
|
||||||
@Override
|
@Override
|
||||||
public Object doInTransaction(TransactionStatus status) {
|
public Object doInTransaction(TransactionStatus status) {
|
||||||
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
||||||
return template.execute(new JpaCallback() {
|
EntityManagerFactoryUtils.getTransactionalEntityManager(factory).flush();
|
||||||
@Override
|
|
||||||
public Object doInJpa(EntityManager em) {
|
|
||||||
em.flush();
|
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
assertSame(l, result);
|
assertSame(l, result);
|
||||||
|
|
||||||
assertTrue(!TransactionSynchronizationManager.hasResource(factory));
|
assertTrue(!TransactionSynchronizationManager.hasResource(factory));
|
||||||
|
@ -137,15 +128,10 @@ public class JpaTransactionManagerTests {
|
||||||
@Override
|
@Override
|
||||||
public Object doInTransaction(TransactionStatus status) {
|
public Object doInTransaction(TransactionStatus status) {
|
||||||
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
||||||
return template.execute(new JpaCallback() {
|
EntityManagerFactoryUtils.getTransactionalEntityManager(factory).flush();
|
||||||
@Override
|
|
||||||
public Object doInJpa(EntityManager em) {
|
|
||||||
em.flush();
|
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
assertSame(l, result);
|
assertSame(l, result);
|
||||||
}
|
}
|
||||||
catch (TransactionSystemException tse) {
|
catch (TransactionSystemException tse) {
|
||||||
|
@ -176,14 +162,10 @@ public class JpaTransactionManagerTests {
|
||||||
@Override
|
@Override
|
||||||
public Object doInTransaction(TransactionStatus status) {
|
public Object doInTransaction(TransactionStatus status) {
|
||||||
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
||||||
return template.execute(new JpaCallback() {
|
EntityManagerFactoryUtils.getTransactionalEntityManager(factory);
|
||||||
@Override
|
|
||||||
public Object doInJpa(EntityManager em) {
|
|
||||||
throw new RuntimeException("some exception");
|
throw new RuntimeException("some exception");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
fail("Should have propagated RuntimeException");
|
fail("Should have propagated RuntimeException");
|
||||||
}
|
}
|
||||||
catch (RuntimeException ex) {
|
catch (RuntimeException ex) {
|
||||||
|
@ -213,14 +195,10 @@ public class JpaTransactionManagerTests {
|
||||||
@Override
|
@Override
|
||||||
public Object doInTransaction(TransactionStatus status) {
|
public Object doInTransaction(TransactionStatus status) {
|
||||||
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
||||||
return template.execute(new JpaCallback() {
|
EntityManagerFactoryUtils.getTransactionalEntityManager(factory);
|
||||||
@Override
|
|
||||||
public Object doInJpa(EntityManager em) {
|
|
||||||
throw new RuntimeException("some exception");
|
throw new RuntimeException("some exception");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
fail("Should have propagated RuntimeException");
|
fail("Should have propagated RuntimeException");
|
||||||
}
|
}
|
||||||
catch (RuntimeException ex) {
|
catch (RuntimeException ex) {
|
||||||
|
@ -249,16 +227,10 @@ public class JpaTransactionManagerTests {
|
||||||
public Object doInTransaction(TransactionStatus status) {
|
public Object doInTransaction(TransactionStatus status) {
|
||||||
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
||||||
|
|
||||||
Object res = template.execute(new JpaCallback() {
|
EntityManagerFactoryUtils.getTransactionalEntityManager(factory).flush();
|
||||||
@Override
|
|
||||||
public Object doInJpa(EntityManager em) {
|
|
||||||
em.flush();
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
status.setRollbackOnly();
|
status.setRollbackOnly();
|
||||||
|
|
||||||
return res;
|
return l;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -288,18 +260,12 @@ public class JpaTransactionManagerTests {
|
||||||
return tt.execute(new TransactionCallback() {
|
return tt.execute(new TransactionCallback() {
|
||||||
@Override
|
@Override
|
||||||
public Object doInTransaction(TransactionStatus status) {
|
public Object doInTransaction(TransactionStatus status) {
|
||||||
|
EntityManagerFactoryUtils.getTransactionalEntityManager(factory).flush();
|
||||||
return template.execute(new JpaCallback() {
|
|
||||||
@Override
|
|
||||||
public Object doInJpa(EntityManager em) {
|
|
||||||
em.flush();
|
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
assertTrue(!TransactionSynchronizationManager.hasResource(factory));
|
assertTrue(!TransactionSynchronizationManager.hasResource(factory));
|
||||||
assertTrue(!TransactionSynchronizationManager.isSynchronizationActive());
|
assertTrue(!TransactionSynchronizationManager.isSynchronizationActive());
|
||||||
|
@ -328,12 +294,8 @@ public class JpaTransactionManagerTests {
|
||||||
return tt.execute(new TransactionCallback() {
|
return tt.execute(new TransactionCallback() {
|
||||||
@Override
|
@Override
|
||||||
public Object doInTransaction(TransactionStatus status) {
|
public Object doInTransaction(TransactionStatus status) {
|
||||||
return template.execute(new JpaCallback() {
|
EntityManagerFactoryUtils.getTransactionalEntityManager(factory);
|
||||||
@Override
|
throw new RuntimeException("some exception");
|
||||||
public Object doInJpa(EntityManager em) {
|
|
||||||
throw new RuntimeException("exception");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -374,15 +336,7 @@ public class JpaTransactionManagerTests {
|
||||||
return tt.execute(new TransactionCallback() {
|
return tt.execute(new TransactionCallback() {
|
||||||
@Override
|
@Override
|
||||||
public Object doInTransaction(TransactionStatus status) {
|
public Object doInTransaction(TransactionStatus status) {
|
||||||
|
EntityManagerFactoryUtils.getTransactionalEntityManager(factory).flush();
|
||||||
template.execute(new JpaCallback() {
|
|
||||||
@Override
|
|
||||||
public Object doInJpa(EntityManager em2) {
|
|
||||||
em2.flush();
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
status.setRollbackOnly();
|
status.setRollbackOnly();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -425,17 +379,12 @@ public class JpaTransactionManagerTests {
|
||||||
return tt.execute(new TransactionCallback() {
|
return tt.execute(new TransactionCallback() {
|
||||||
@Override
|
@Override
|
||||||
public Object doInTransaction(TransactionStatus status) {
|
public Object doInTransaction(TransactionStatus status) {
|
||||||
return template.execute(new JpaCallback() {
|
EntityManagerFactoryUtils.getTransactionalEntityManager(factory).flush();
|
||||||
@Override
|
|
||||||
public Object doInJpa(EntityManager em2) {
|
|
||||||
em2.flush();
|
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
assertSame(l, result);
|
assertSame(l, result);
|
||||||
|
|
||||||
assertTrue(!TransactionSynchronizationManager.hasResource(factory));
|
assertTrue(!TransactionSynchronizationManager.hasResource(factory));
|
||||||
|
@ -464,29 +413,18 @@ public class JpaTransactionManagerTests {
|
||||||
Object result = tt.execute(new TransactionCallback() {
|
Object result = tt.execute(new TransactionCallback() {
|
||||||
@Override
|
@Override
|
||||||
public Object doInTransaction(TransactionStatus status) {
|
public Object doInTransaction(TransactionStatus status) {
|
||||||
JpaTemplate template2 = new JpaTemplate(factory);
|
EntityManagerFactoryUtils.getTransactionalEntityManager(factory);
|
||||||
template2.execute(new JpaCallback() {
|
|
||||||
@Override
|
|
||||||
public Object doInJpa(EntityManager em) throws PersistenceException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
||||||
return tt.execute(new TransactionCallback() {
|
return tt.execute(new TransactionCallback() {
|
||||||
@Override
|
@Override
|
||||||
public Object doInTransaction(TransactionStatus status) {
|
public Object doInTransaction(TransactionStatus status) {
|
||||||
return template.execute(new JpaCallback() {
|
EntityManagerFactoryUtils.getTransactionalEntityManager(factory).flush();
|
||||||
@Override
|
|
||||||
public Object doInJpa(EntityManager em2) {
|
|
||||||
em2.flush();
|
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
assertSame(l, result);
|
assertSame(l, result);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
@ -523,17 +461,12 @@ public class JpaTransactionManagerTests {
|
||||||
return tt2.execute(new TransactionCallback() {
|
return tt2.execute(new TransactionCallback() {
|
||||||
@Override
|
@Override
|
||||||
public Object doInTransaction(TransactionStatus status) {
|
public Object doInTransaction(TransactionStatus status) {
|
||||||
return template.execute(new JpaCallback() {
|
EntityManagerFactoryUtils.getTransactionalEntityManager(factory).flush();
|
||||||
@Override
|
|
||||||
public Object doInJpa(EntityManager em2) {
|
|
||||||
em2.flush();
|
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
assertSame(l, result);
|
assertSame(l, result);
|
||||||
|
|
||||||
assertTrue(!TransactionSynchronizationManager.hasResource(factory));
|
assertTrue(!TransactionSynchronizationManager.hasResource(factory));
|
||||||
|
@ -561,13 +494,7 @@ public class JpaTransactionManagerTests {
|
||||||
Object result = tt.execute(new TransactionCallback() {
|
Object result = tt.execute(new TransactionCallback() {
|
||||||
@Override
|
@Override
|
||||||
public Object doInTransaction(TransactionStatus status) {
|
public Object doInTransaction(TransactionStatus status) {
|
||||||
JpaTemplate template2 = new JpaTemplate(factory);
|
EntityManagerFactoryUtils.getTransactionalEntityManager(factory);
|
||||||
template2.execute(new JpaCallback() {
|
|
||||||
@Override
|
|
||||||
public Object doInJpa(EntityManager em) throws PersistenceException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
||||||
TransactionTemplate tt2 = new TransactionTemplate(transactionManager);
|
TransactionTemplate tt2 = new TransactionTemplate(transactionManager);
|
||||||
|
@ -575,17 +502,12 @@ public class JpaTransactionManagerTests {
|
||||||
return tt2.execute(new TransactionCallback() {
|
return tt2.execute(new TransactionCallback() {
|
||||||
@Override
|
@Override
|
||||||
public Object doInTransaction(TransactionStatus status) {
|
public Object doInTransaction(TransactionStatus status) {
|
||||||
return template.execute(new JpaCallback() {
|
EntityManagerFactoryUtils.getTransactionalEntityManager(factory).flush();
|
||||||
@Override
|
|
||||||
public Object doInJpa(EntityManager em2) {
|
|
||||||
em2.flush();
|
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
assertSame(l, result);
|
assertSame(l, result);
|
||||||
|
|
||||||
assertTrue(!TransactionSynchronizationManager.hasResource(factory));
|
assertTrue(!TransactionSynchronizationManager.hasResource(factory));
|
||||||
|
@ -614,30 +536,19 @@ public class JpaTransactionManagerTests {
|
||||||
tt.execute(new TransactionCallback() {
|
tt.execute(new TransactionCallback() {
|
||||||
@Override
|
@Override
|
||||||
public Object doInTransaction(TransactionStatus status) {
|
public Object doInTransaction(TransactionStatus status) {
|
||||||
template.execute(new JpaCallback() {
|
EntityManagerFactoryUtils.getTransactionalEntityManager(factory).flush();
|
||||||
@Override
|
|
||||||
public Object doInJpa(EntityManager em2) {
|
|
||||||
em2.flush();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
|
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void afterCompletion(int status) {
|
public void afterCompletion(int status) {
|
||||||
tt.execute(new TransactionCallback() {
|
tt.execute(new TransactionCallback() {
|
||||||
@Override
|
@Override
|
||||||
public Object doInTransaction(TransactionStatus status) {
|
public Object doInTransaction(TransactionStatus status) {
|
||||||
return template.execute(new JpaCallback() {
|
EntityManagerFactoryUtils.getTransactionalEntityManager(factory).flush();
|
||||||
@Override
|
|
||||||
public Object doInJpa(EntityManager em2) {
|
|
||||||
em2.flush();
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -672,15 +583,10 @@ public class JpaTransactionManagerTests {
|
||||||
assertTrue(!TransactionSynchronizationManager.hasResource(factory));
|
assertTrue(!TransactionSynchronizationManager.hasResource(factory));
|
||||||
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
|
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
|
||||||
assertTrue(!status.isNewTransaction());
|
assertTrue(!status.isNewTransaction());
|
||||||
return template.execute(new JpaCallback() {
|
EntityManagerFactoryUtils.getTransactionalEntityManager(factory).flush();
|
||||||
@Override
|
|
||||||
public Object doInJpa(EntityManager em) {
|
|
||||||
em.flush();
|
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
assertSame(l, result);
|
assertSame(l, result);
|
||||||
|
|
||||||
assertTrue(!TransactionSynchronizationManager.hasResource(factory));
|
assertTrue(!TransactionSynchronizationManager.hasResource(factory));
|
||||||
|
@ -705,13 +611,7 @@ public class JpaTransactionManagerTests {
|
||||||
assertTrue(!TransactionSynchronizationManager.hasResource(factory));
|
assertTrue(!TransactionSynchronizationManager.hasResource(factory));
|
||||||
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
|
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
|
||||||
assertTrue(!status.isNewTransaction());
|
assertTrue(!status.isNewTransaction());
|
||||||
template.execute(new JpaCallback() {
|
EntityManagerFactoryUtils.getTransactionalEntityManager(factory).flush();
|
||||||
@Override
|
|
||||||
public Object doInJpa(EntityManager em) {
|
|
||||||
em.flush();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
status.setRollbackOnly();
|
status.setRollbackOnly();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -741,14 +641,10 @@ public class JpaTransactionManagerTests {
|
||||||
public Object doInTransaction(TransactionStatus status) {
|
public Object doInTransaction(TransactionStatus status) {
|
||||||
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
||||||
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
|
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
|
||||||
return template.execute(new JpaCallback() {
|
EntityManagerFactoryUtils.getTransactionalEntityManager(factory);
|
||||||
@Override
|
|
||||||
public Object doInJpa(EntityManager em) {
|
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
assertSame(l, result);
|
assertSame(l, result);
|
||||||
|
|
||||||
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
||||||
|
@ -778,12 +674,7 @@ public class JpaTransactionManagerTests {
|
||||||
public Object doInTransaction(TransactionStatus status) {
|
public Object doInTransaction(TransactionStatus status) {
|
||||||
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
||||||
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
|
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
|
||||||
template.execute(new JpaCallback() {
|
EntityManagerFactoryUtils.getTransactionalEntityManager(factory);
|
||||||
@Override
|
|
||||||
public Object doInJpa(EntityManager em) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
status.setRollbackOnly();
|
status.setRollbackOnly();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -820,15 +711,10 @@ public class JpaTransactionManagerTests {
|
||||||
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
||||||
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
|
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
|
||||||
assertTrue(!status.isNewTransaction());
|
assertTrue(!status.isNewTransaction());
|
||||||
return template.execute(new JpaCallback() {
|
EntityManagerFactoryUtils.getTransactionalEntityManager(factory).flush();
|
||||||
@Override
|
|
||||||
public Object doInJpa(EntityManager em) {
|
|
||||||
em.flush();
|
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
assertSame(l, result);
|
assertSame(l, result);
|
||||||
|
|
||||||
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
||||||
|
@ -858,13 +744,7 @@ public class JpaTransactionManagerTests {
|
||||||
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
||||||
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
|
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
|
||||||
assertTrue(!status.isNewTransaction());
|
assertTrue(!status.isNewTransaction());
|
||||||
template.execute(new JpaCallback() {
|
EntityManagerFactoryUtils.getTransactionalEntityManager(factory).flush();
|
||||||
@Override
|
|
||||||
public Object doInJpa(EntityManager em) {
|
|
||||||
em.flush();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
status.setRollbackOnly();
|
status.setRollbackOnly();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -900,15 +780,10 @@ public class JpaTransactionManagerTests {
|
||||||
public Object doInTransaction(TransactionStatus status) {
|
public Object doInTransaction(TransactionStatus status) {
|
||||||
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
||||||
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
|
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
|
||||||
return template.execute(new JpaCallback() {
|
EntityManagerFactoryUtils.getTransactionalEntityManager(factory).flush();
|
||||||
@Override
|
|
||||||
public Object doInJpa(EntityManager em) {
|
|
||||||
em.flush();
|
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
assertTrue(result == l);
|
assertTrue(result == l);
|
||||||
|
|
||||||
|
|
|
@ -1,101 +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.jpa.support;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
import javax.persistence.EntityManagerFactory;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.springframework.orm.jpa.JpaTemplate;
|
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
import static org.mockito.BDDMockito.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Costin Leau
|
|
||||||
* @author Phillip Webb
|
|
||||||
*/
|
|
||||||
public class JpaDaoSupportTests {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testJpaDaoSupportWithEntityManager() throws Exception {
|
|
||||||
EntityManager entityManager = mock(EntityManager.class);
|
|
||||||
final List test = new ArrayList();
|
|
||||||
JpaDaoSupport dao = new JpaDaoSupport() {
|
|
||||||
@Override
|
|
||||||
protected void initDao() {
|
|
||||||
test.add("test");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
dao.setEntityManager(entityManager);
|
|
||||||
dao.afterPropertiesSet();
|
|
||||||
assertNotNull("jpa template not created", dao.getJpaTemplate());
|
|
||||||
assertEquals("incorrect entity manager", entityManager, dao.getJpaTemplate().getEntityManager());
|
|
||||||
assertEquals("initDao not called", test.size(), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testJpaDaoSupportWithEntityManagerFactory() throws Exception {
|
|
||||||
EntityManagerFactory entityManagerFactory = mock(EntityManagerFactory.class);
|
|
||||||
final List test = new ArrayList();
|
|
||||||
JpaDaoSupport dao = new JpaDaoSupport() {
|
|
||||||
@Override
|
|
||||||
protected void initDao() {
|
|
||||||
test.add("test");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
dao.setEntityManagerFactory(entityManagerFactory);
|
|
||||||
dao.afterPropertiesSet();
|
|
||||||
assertNotNull("jpa template not created", dao.getJpaTemplate());
|
|
||||||
assertEquals("incorrect entity manager factory", entityManagerFactory,
|
|
||||||
dao.getJpaTemplate().getEntityManagerFactory());
|
|
||||||
assertEquals("initDao not called", test.size(), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testJpaDaoSupportWithJpaTemplate() throws Exception {
|
|
||||||
JpaTemplate template = new JpaTemplate();
|
|
||||||
final List test = new ArrayList();
|
|
||||||
JpaDaoSupport dao = new JpaDaoSupport() {
|
|
||||||
@Override
|
|
||||||
protected void initDao() {
|
|
||||||
test.add("test");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
dao.setJpaTemplate(template);
|
|
||||||
dao.afterPropertiesSet();
|
|
||||||
assertNotNull("jpa template not created", dao.getJpaTemplate());
|
|
||||||
assertEquals("incorrect JpaTemplate", template, dao.getJpaTemplate());
|
|
||||||
assertEquals("initDao not called", test.size(), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testInvalidJpaTemplate() throws Exception {
|
|
||||||
JpaDaoSupport dao = new JpaDaoSupport() {
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
dao.afterPropertiesSet();
|
|
||||||
fail("expected exception");
|
|
||||||
}
|
|
||||||
catch (IllegalArgumentException iae) {
|
|
||||||
// okay
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -19,7 +19,6 @@ package org.springframework.orm.jpa.support;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
import javax.persistence.EntityManagerFactory;
|
import javax.persistence.EntityManagerFactory;
|
||||||
import javax.servlet.FilterChain;
|
import javax.servlet.FilterChain;
|
||||||
|
@ -30,13 +29,13 @@ import javax.servlet.ServletResponse;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||||
import org.springframework.mock.web.test.MockFilterConfig;
|
import org.springframework.mock.web.test.MockFilterConfig;
|
||||||
import org.springframework.mock.web.test.MockHttpServletRequest;
|
import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||||
import org.springframework.mock.web.test.MockHttpServletResponse;
|
import org.springframework.mock.web.test.MockHttpServletResponse;
|
||||||
import org.springframework.mock.web.test.MockServletContext;
|
import org.springframework.mock.web.test.MockServletContext;
|
||||||
import org.springframework.mock.web.test.PassThroughFilterChain;
|
import org.springframework.mock.web.test.PassThroughFilterChain;
|
||||||
import org.springframework.orm.jpa.JpaTemplate;
|
|
||||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||||
import org.springframework.web.context.WebApplicationContext;
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
import org.springframework.web.context.request.ServletWebRequest;
|
import org.springframework.web.context.request.ServletWebRequest;
|
||||||
|
@ -60,17 +59,12 @@ public class OpenEntityManagerInViewTests {
|
||||||
|
|
||||||
private EntityManagerFactory factory;
|
private EntityManagerFactory factory;
|
||||||
|
|
||||||
private JpaTemplate template;
|
|
||||||
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
factory = mock(EntityManagerFactory.class);
|
factory = mock(EntityManagerFactory.class);
|
||||||
manager = mock(EntityManager.class);
|
manager = mock(EntityManager.class);
|
||||||
|
|
||||||
template = new JpaTemplate(factory);
|
|
||||||
template.afterPropertiesSet();
|
|
||||||
|
|
||||||
given(factory.createEntityManager()).willReturn(manager);
|
given(factory.createEntityManager()).willReturn(manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue