General JPA 2.0+ requirement; upgraded build and tests to EclipseLink 2.4, OpenJPA 2.2, Hibernate 3.6

This commit is contained in:
Juergen Hoeller
2013-03-19 18:34:04 +01:00
parent 90f79f3f4f
commit ceb9a05ecb
29 changed files with 86 additions and 760 deletions

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -16,18 +16,16 @@
package org.springframework.orm.hibernate3;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.hibernate.engine.FilterDefinition;
import org.hibernate.type.Type;
import org.hibernate.type.TypeFactory;
import org.hibernate.type.TypeResolver;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.ReflectionUtils;
/**
* Convenient FactoryBean for defining Hibernate FilterDefinitions.
@@ -66,29 +64,7 @@ import org.springframework.util.ReflectionUtils;
*/
public class FilterDefinitionFactoryBean implements FactoryBean<FilterDefinition>, BeanNameAware, InitializingBean {
private static Method heuristicTypeMethod;
private static Object typeResolver;
static {
// Hibernate 3.6 TypeResolver class available?
try {
Class<?> trClass = FilterDefinitionFactoryBean.class.getClassLoader().loadClass(
"org.hibernate.type.TypeResolver");
heuristicTypeMethod = trClass.getMethod("heuristicType", String.class);
typeResolver = trClass.newInstance();
}
catch (Exception ex) {
try {
heuristicTypeMethod = TypeFactory.class.getMethod("heuristicType", String.class);
typeResolver = null;
}
catch (Exception ex2) {
throw new IllegalStateException("Cannot find Hibernate's heuristicType method", ex2);
}
}
}
private final TypeResolver typeResolver = new TypeResolver();
private String filterName;
@@ -116,8 +92,7 @@ public class FilterDefinitionFactoryBean implements FactoryBean<FilterDefinition
if (parameterTypes != null) {
this.parameterTypeMap = new HashMap<String, Type>(parameterTypes.size());
for (Map.Entry<String, String> entry : parameterTypes.entrySet()) {
this.parameterTypeMap.put(entry.getKey(),
(Type) ReflectionUtils.invokeMethod(heuristicTypeMethod, typeResolver, entry.getValue()));
this.parameterTypeMap.put(entry.getKey(), this.typeResolver.heuristicType(entry.getValue()));
}
}
else {

View File

@@ -1,73 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.orm.hibernate3;
import java.util.Properties;
import org.hibernate.cache.Cache;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.CacheProvider;
/**
* Proxy for a Hibernate CacheProvider, delegating to a Spring-managed
* CacheProvider instance, determined by LocalSessionFactoryBean's
* "cacheProvider" property.
*
* @author Juergen Hoeller
* @since 2.5.1
* @see LocalSessionFactoryBean#setCacheProvider
* @deprecated as of Spring 3.0, following Hibernate 3.3's deprecation
* of the CacheProvider SPI
*/
@Deprecated
public class LocalCacheProviderProxy implements CacheProvider {
private final CacheProvider cacheProvider;
public LocalCacheProviderProxy() {
CacheProvider cp = LocalSessionFactoryBean.getConfigTimeCacheProvider();
// absolutely needs thread-bound CacheProvider to initialize
if (cp == null) {
throw new IllegalStateException("No Hibernate CacheProvider found - " +
"'cacheProvider' property must be set on LocalSessionFactoryBean");
}
this.cacheProvider = cp;
}
public Cache buildCache(String regionName, Properties properties) throws CacheException {
return this.cacheProvider.buildCache(regionName, properties);
}
public long nextTimestamp() {
return this.cacheProvider.nextTimestamp();
}
public void start(Properties properties) throws CacheException {
this.cacheProvider.start(properties);
}
public void stop() {
this.cacheProvider.stop();
}
public boolean isMinimalPutsEnabledByDefault() {
return this.cacheProvider.isMinimalPutsEnabledByDefault();
}
}

View File

@@ -34,6 +34,7 @@ import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cache.RegionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.cfg.NamingStrategy;
@@ -159,19 +160,6 @@ public class LocalSessionFactoryBean extends AbstractSessionFactoryBean implemen
return configTimeRegionFactoryHolder.get();
}
/**
* Return the CacheProvider for the currently configured Hibernate SessionFactory,
* to be used by LocalCacheProviderProxy.
* <p>This instance will be set before initialization of the corresponding
* SessionFactory, and reset immediately afterwards. It is thus only available
* during configuration.
* @see #setCacheProvider
*/
@SuppressWarnings("deprecation")
public static org.hibernate.cache.CacheProvider getConfigTimeCacheProvider() {
return configTimeCacheProviderHolder.get();
}
/**
* Return the LobHandler for the currently configured Hibernate SessionFactory,
* to be used by UserType implementations like ClobStringType.
@@ -206,10 +194,7 @@ public class LocalSessionFactoryBean extends AbstractSessionFactoryBean implemen
private TransactionManager jtaTransactionManager;
private Object cacheRegionFactory;
@SuppressWarnings("deprecation")
private org.hibernate.cache.CacheProvider cacheProvider;
private RegionFactory cacheRegionFactory;
private LobHandler lobHandler;
@@ -381,32 +366,14 @@ public class LocalSessionFactoryBean extends AbstractSessionFactoryBean implemen
/**
* Set the Hibernate RegionFactory to use for the SessionFactory.
* Allows for using a Spring-managed RegionFactory instance.
* <p>As of Hibernate 3.3, this is the preferred mechanism for configuring
* caches, superseding the {@link #setCacheProvider CacheProvider SPI}.
* For Hibernate 3.2 compatibility purposes, the accepted reference is of type
* Object: the actual type is {@code org.hibernate.cache.RegionFactory}.
* <p>Note: If this is set, the Hibernate settings should not define a
* cache provider to avoid meaningless double configuration.
* @see org.hibernate.cache.RegionFactory
*/
public void setCacheRegionFactory(Object cacheRegionFactory) {
public void setCacheRegionFactory(RegionFactory cacheRegionFactory) {
this.cacheRegionFactory = cacheRegionFactory;
}
/**
* Set the Hibernate CacheProvider to use for the SessionFactory.
* Allows for using a Spring-managed CacheProvider instance.
* <p>Note: If this is set, the Hibernate settings should not define a
* cache provider to avoid meaningless double configuration.
* @deprecated as of Spring 3.0, following Hibernate 3.3's deprecation
* of the CacheProvider SPI
* @see #setCacheRegionFactory
*/
@Deprecated
public void setCacheProvider(org.hibernate.cache.CacheProvider cacheProvider) {
this.cacheProvider = cacheProvider;
}
/**
* Set the LobHandler to be used by the SessionFactory.
* Will be exposed at config time for UserType implementations.
@@ -564,10 +531,6 @@ public class LocalSessionFactoryBean extends AbstractSessionFactoryBean implemen
// Make Spring-provided Hibernate RegionFactory available.
configTimeRegionFactoryHolder.set(this.cacheRegionFactory);
}
if (this.cacheProvider != null) {
// Make Spring-provided Hibernate CacheProvider available.
configTimeCacheProviderHolder.set(this.cacheProvider);
}
if (this.lobHandler != null) {
// Make given LobHandler available for SessionFactory configuration.
// Do early because because mapping resource might refer to custom types.
@@ -668,10 +631,6 @@ public class LocalSessionFactoryBean extends AbstractSessionFactoryBean implemen
config.setProperty(Environment.CACHE_REGION_FACTORY,
"org.springframework.orm.hibernate3.LocalRegionFactoryProxy");
}
else if (this.cacheProvider != null) {
// Expose Spring-provided Hibernate CacheProvider.
config.setProperty(Environment.CACHE_PROVIDER, LocalCacheProviderProxy.class.getName());
}
if (this.mappingResources != null) {
// Register given Hibernate mapping definitions, contained in resource files.
@@ -792,9 +751,6 @@ public class LocalSessionFactoryBean extends AbstractSessionFactoryBean implemen
if (this.cacheRegionFactory != null) {
configTimeRegionFactoryHolder.remove();
}
if (this.cacheProvider != null) {
configTimeCacheProviderHolder.remove();
}
if (this.lobHandler != null) {
configTimeLobHandlerHolder.remove();
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -17,9 +17,6 @@
package org.springframework.orm.jpa.persistenceunit;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
@@ -96,8 +93,6 @@ public class DefaultPersistenceUnitManager
private static final String ENTITY_CLASS_RESOURCE_PATTERN = "/**/*.class";
private static final boolean jpa2ApiPresent = ClassUtils.hasMethod(PersistenceUnitInfo.class, "getSharedCacheMode");
private static final TypeFilter[] entityTypeFilters = new TypeFilter[] {
new AnnotationTypeFilter(Entity.class, false),
new AnnotationTypeFilter(Embeddable.class, false),
@@ -384,12 +379,7 @@ public class DefaultPersistenceUnitManager
msg.append(this.persistenceUnitInfos.get(name).getPersistenceUnitRootUrl());
throw new IllegalStateException(msg.toString());
}
PersistenceUnitInfo puiToStore = pui;
if (jpa2ApiPresent) {
puiToStore = (PersistenceUnitInfo) Proxy.newProxyInstance(SmartPersistenceUnitInfo.class.getClassLoader(),
new Class[] {SmartPersistenceUnitInfo.class}, new Jpa2PersistenceUnitInfoDecorator(pui));
}
this.persistenceUnitInfos.put(name, puiToStore);
this.persistenceUnitInfos.put(name, pui);
}
}
@@ -503,15 +493,7 @@ public class DefaultPersistenceUnitManager
*/
protected final MutablePersistenceUnitInfo getPersistenceUnitInfo(String persistenceUnitName) {
PersistenceUnitInfo pui = this.persistenceUnitInfos.get(persistenceUnitName);
if (pui != null && Proxy.isProxyClass(pui.getClass())) {
// JPA 2.0 PersistenceUnitInfo decorator with a SpringPersistenceUnitInfo as target
Jpa2PersistenceUnitInfoDecorator dec = (Jpa2PersistenceUnitInfoDecorator) Proxy.getInvocationHandler(pui);
return dec.getTarget();
}
else {
// Must be a raw JPA 1.0 SpringPersistenceUnitInfo instance
return (MutablePersistenceUnitInfo) pui;
}
return (MutablePersistenceUnitInfo) pui;
}
/**
@@ -574,49 +556,4 @@ public class DefaultPersistenceUnitManager
return pui;
}
/**
* Decorator that exposes a JPA 2.0 compliant PersistenceUnitInfo interface for a
* JPA 1.0 based SpringPersistenceUnitInfo object, adapting the {@code getSharedCacheMode}
* and {@code getValidationMode} methods from String names to enum return values.
*/
private static class Jpa2PersistenceUnitInfoDecorator implements InvocationHandler {
private final SpringPersistenceUnitInfo target;
private final Class<? extends Enum> sharedCacheModeEnum;
private final Class<? extends Enum> validationModeEnum;
@SuppressWarnings("unchecked")
public Jpa2PersistenceUnitInfoDecorator(SpringPersistenceUnitInfo target) {
this.target = target;
try {
this.sharedCacheModeEnum = (Class<? extends Enum>)
ClassUtils.forName("javax.persistence.SharedCacheMode", PersistenceUnitInfo.class.getClassLoader());
this.validationModeEnum = (Class<? extends Enum>)
ClassUtils.forName("javax.persistence.ValidationMode", PersistenceUnitInfo.class.getClassLoader());
}
catch (Exception ex) {
throw new IllegalStateException("JPA 2.0 API enum types not present", ex);
}
}
public final SpringPersistenceUnitInfo getTarget() {
return this.target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("getSharedCacheMode")) {
return Enum.valueOf(this.sharedCacheModeEnum, this.target.getSharedCacheModeName());
}
else if (method.getName().equals("getValidationMode")) {
return Enum.valueOf(this.validationModeEnum, this.target.getValidationModeName());
}
else {
return method.invoke(this.target, args);
}
}
}
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,8 @@ import java.net.URL;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import javax.persistence.SharedCacheMode;
import javax.persistence.ValidationMode;
import javax.persistence.spi.ClassTransformer;
import javax.persistence.spi.PersistenceUnitTransactionType;
import javax.sql.DataSource;
@@ -61,9 +63,13 @@ public class MutablePersistenceUnitInfo implements SmartPersistenceUnitInfo {
private boolean excludeUnlistedClasses = false;
private SharedCacheMode sharedCacheMode = SharedCacheMode.UNSPECIFIED;
private ValidationMode validationMode = ValidationMode.AUTO;
private Properties properties = new Properties();
private String persistenceXMLSchemaVersion = "1.0";
private String persistenceXMLSchemaVersion = "2.0";
private String persistenceProviderPackageName;
@@ -154,6 +160,22 @@ public class MutablePersistenceUnitInfo implements SmartPersistenceUnitInfo {
return this.excludeUnlistedClasses;
}
public void setSharedCacheMode(SharedCacheMode sharedCacheMode) {
this.sharedCacheMode = sharedCacheMode;
}
public SharedCacheMode getSharedCacheMode() {
return this.sharedCacheMode;
}
public void setValidationMode(ValidationMode validationMode) {
this.validationMode = validationMode;
}
public ValidationMode getValidationMode() {
return this.validationMode;
}
public void addProperty(String name, String value) {
if (this.properties == null) {
this.properties = new Properties();

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,8 @@ import java.io.InputStream;
import java.net.URL;
import java.util.LinkedList;
import java.util.List;
import javax.persistence.SharedCacheMode;
import javax.persistence.ValidationMode;
import javax.persistence.spi.PersistenceUnitTransactionType;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@@ -273,13 +275,13 @@ class PersistenceUnitReader {
// set JPA 2.0 shared cache mode
String cacheMode = DomUtils.getChildElementValueByTagName(persistenceUnit, SHARED_CACHE_MODE);
if (StringUtils.hasText(cacheMode)) {
unitInfo.setSharedCacheModeName(cacheMode);
unitInfo.setSharedCacheMode(SharedCacheMode.valueOf(cacheMode));
}
// set JPA 2.0 validation mode
String validationMode = DomUtils.getChildElementValueByTagName(persistenceUnit, VALIDATION_MODE);
if (StringUtils.hasText(validationMode)) {
unitInfo.setValidationModeName(validationMode);
unitInfo.setValidationMode(ValidationMode.valueOf(validationMode));
}
parseProperties(persistenceUnit, unitInfo);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -22,7 +22,6 @@ import org.springframework.core.DecoratingClassLoader;
import org.springframework.instrument.classloading.LoadTimeWeaver;
import org.springframework.instrument.classloading.SimpleThrowawayClassLoader;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Subclass of {@link MutablePersistenceUnitInfo} that adds instrumentation hooks based on
@@ -38,39 +37,11 @@ import org.springframework.util.StringUtils;
*/
class SpringPersistenceUnitInfo extends MutablePersistenceUnitInfo {
private static final String DEFAULT_SHARED_CACHE_MODE_NAME = "UNSPECIFIED";
private static final String DEFAULT_VALIDATION_MODE_NAME = "AUTO";
private String sharedCacheModeName = DEFAULT_SHARED_CACHE_MODE_NAME;
private String validationModeName = DEFAULT_VALIDATION_MODE_NAME;
private LoadTimeWeaver loadTimeWeaver;
private ClassLoader classLoader;
public void setSharedCacheModeName(String sharedCacheModeName) {
this.sharedCacheModeName =
(StringUtils.hasLength(sharedCacheModeName) ? sharedCacheModeName : DEFAULT_SHARED_CACHE_MODE_NAME);
}
public String getSharedCacheModeName() {
return this.sharedCacheModeName;
}
public void setValidationModeName(String validationModeName) {
this.validationModeName =
(StringUtils.hasLength(validationModeName) ? validationModeName : DEFAULT_VALIDATION_MODE_NAME);
}
public String getValidationModeName() {
return this.validationModeName;
}
/**
* Initialize this PersistenceUnitInfo with the LoadTimeWeaver SPI interface
* used by Spring to add instrumentation to the current class loader.

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -34,8 +34,7 @@ import org.springframework.transaction.TransactionException;
/**
* {@link org.springframework.orm.jpa.JpaDialect} implementation for Eclipse
* Persistence Services (EclipseLink). Developed and tested against EclipseLink
* 1.0 as well as 2.0-2.3.
* Persistence Services (EclipseLink). Developed and tested against EclipseLink 2.4.
*
* <p>By default, this class acquires a EclipseLink transaction to get the JDBC Connection
* early. This allows mixing JDBC and JPA/EclipseLink operations in the same transaction.
@@ -46,10 +45,6 @@ import org.springframework.transaction.TransactionException;
* to ensure that the cost of connection acquisition is near zero until code actually
* needs a JDBC Connection.
*
* <p>This class is very analogous to {@link TopLinkJpaDialect}, since
* EclipseLink is effectively the next generation of the TopLink product.
* Thanks to Mike Keith for the original EclipseLink support prototype!
*
* @author Juergen Hoeller
* @since 2.5.2
* @see #setLazyDatabaseTransaction

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -30,19 +30,11 @@ import org.springframework.orm.jpa.JpaDialect;
/**
* {@link org.springframework.orm.jpa.JpaVendorAdapter} implementation for Eclipse
* Persistence Services (EclipseLink). Developed and tested against EclipseLink
* 1.0 as well as 2.0-2.3.
* Persistence Services (EclipseLink). Developed and tested against EclipseLink 2.4.
*
* <p>Exposes EclipseLink's persistence provider and EntityManager extension interface,
* and supports {@link AbstractJpaVendorAdapter}'s common configuration settings.
*
* <p>This class is very analogous to {@link TopLinkJpaVendorAdapter}, since
* EclipseLink is effectively the next generation of the TopLink product.
* Thanks to Mike Keith for the original EclipseLink support prototype!
*
* <p>NOTE: No need to filter out classes from the JPA providers package for
* EclipseLink (see SPR-6040)
*
* @author Juergen Hoeller
* @author Thomas Risberg
* @since 2.5.2

View File

@@ -39,9 +39,7 @@ import org.springframework.util.ReflectionUtils;
/**
* {@link org.springframework.orm.jpa.JpaDialect} implementation for
* Hibernate EntityManager. Developed against Hibernate 3.3;
* tested against 3.3, 3.5, 3.6 and 4.0 (with the latter including
* Hibernate EntityManager in the Hibernate core distribution).
* Hibernate EntityManager. Developed against Hibernate 3.6 and 4.2.
*
* @author Costin Leau
* @author Juergen Hoeller

View File

@@ -41,7 +41,7 @@ import org.springframework.orm.jpa.JpaDialect;
/**
* {@link org.springframework.orm.jpa.JpaVendorAdapter} implementation for
* Hibernate EntityManager. Developed and tested against Hibernate 3.3.
* Hibernate EntityManager. Developed and tested against Hibernate 3.6 and 4.2.
*
* <p>Exposes Hibernate's persistence provider and EntityManager extension interface,
* and supports {@link AbstractJpaVendorAdapter}'s common configuration settings.

View File

@@ -34,7 +34,7 @@ import org.springframework.transaction.TransactionException;
/**
* {@link org.springframework.orm.jpa.JpaDialect} implementation for Apache OpenJPA.
* Developed and tested against OpenJPA 1.1 as well as 2.0/2.1.
* Developed and tested against OpenJPA 2.2.
*
* @author Costin Leau
* @author Juergen Hoeller

View File

@@ -30,7 +30,7 @@ import org.springframework.orm.jpa.JpaDialect;
/**
* {@link org.springframework.orm.jpa.JpaVendorAdapter} implementation for Apache OpenJPA.
* Developed and tested against OpenJPA 1.1 as well as 2.0/2.1.
* Developed and tested against OpenJPA 2.2.
*
* <p>Exposes OpenJPA's persistence provider and EntityManager extension interface,
* and supports {@link AbstractJpaVendorAdapter}'s common configuration settings.

View File

@@ -1,114 +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.vendor;
import java.sql.Connection;
import java.sql.SQLException;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;
import oracle.toplink.essentials.internal.sessions.AbstractSession;
import oracle.toplink.essentials.sessions.Session;
import oracle.toplink.essentials.sessions.UnitOfWork;
import org.springframework.jdbc.datasource.ConnectionHandle;
import org.springframework.jdbc.datasource.SimpleConnectionHandle;
import org.springframework.orm.jpa.DefaultJpaDialect;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;
/**
* {@link org.springframework.orm.jpa.JpaDialect} implementation for
* Oracle TopLink Essentials. Developed and tested against TopLink Essentials v2.
*
* <p>By default, this class acquires a TopLink transaction to get the JDBC Connection
* early. This allows mixing JDBC and JPA/TopLink operations in the same transaction.
* In some cases, this eager acquisition of a transaction/connection may impact
* scalability. In that case, set the "lazyDatabaseTransaction" flag to true if you
* do not require mixing JDBC and JPA operations in the same transaction. Otherwise,
* use a {@link org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy}
* to ensure that the cost of connection acquisition is near zero until code actually
* needs a JDBC Connection.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 2.0
* @see #setLazyDatabaseTransaction
* @see org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy
* @deprecated as of Spring 3.1, in favor of the EclipseLink project and
* Spring's corresponding {@link EclipseLinkJpaDialect}
*/
@Deprecated
@SuppressWarnings("serial")
public class TopLinkJpaDialect extends DefaultJpaDialect {
private boolean lazyDatabaseTransaction = false;
/**
* Set whether to lazily start a database transaction within a TopLink
* transaction.
* <p>By default, database transactions are started early. This allows
* for reusing the same JDBC Connection throughout an entire transaction,
* including read operations, and also for exposing TopLink transactions
* to JDBC access code (working on the same DataSource).
* <p>It is only recommended to switch this flag to "true" when no JDBC access
* code is involved in any of the transactions, and when it is acceptable to
* perform read operations outside of the transactional JDBC Connection.
* @see oracle.toplink.essentials.sessions.UnitOfWork#beginEarlyTransaction()
*/
public void setLazyDatabaseTransaction(boolean lazyDatabaseTransaction) {
this.lazyDatabaseTransaction = lazyDatabaseTransaction;
}
@Override
public Object beginTransaction(EntityManager entityManager, TransactionDefinition definition)
throws PersistenceException, SQLException, TransactionException {
super.beginTransaction(entityManager, definition);
if (!definition.isReadOnly() && !this.lazyDatabaseTransaction) {
// This is the magic bit. As with the existing Spring TopLink integration,
// begin an early transaction to force TopLink to get a JDBC Connection
// so that Spring can manage transactions with JDBC as well as TopLink.
UnitOfWork uow = (UnitOfWork) getSession(entityManager);
uow.beginEarlyTransaction();
}
// Could return the UOW, if there were any advantage in having it later.
return null;
}
@Override
public ConnectionHandle getJdbcConnection(EntityManager em, boolean readOnly)
throws PersistenceException, SQLException {
AbstractSession session = (AbstractSession) getSession(em);
// The connection was already acquired eagerly in beginTransaction,
// unless lazyDatabaseTransaction was set to true.
Connection con = session.getAccessor().getConnection();
return (con != null ? new SimpleConnectionHandle(con) : null);
}
/**
* Get a traditional TopLink Session from the given EntityManager.
*/
protected Session getSession(EntityManager em) {
oracle.toplink.essentials.ejb.cmp3.EntityManager emi = (oracle.toplink.essentials.ejb.cmp3.EntityManager) em;
return emi.getActiveSession();
}
}

View File

@@ -1,120 +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.vendor;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import javax.persistence.EntityManager;
import javax.persistence.spi.PersistenceProvider;
import oracle.toplink.essentials.config.TargetDatabase;
import oracle.toplink.essentials.config.TopLinkProperties;
import oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider;
import org.springframework.orm.jpa.JpaDialect;
/**
* {@link org.springframework.orm.jpa.JpaVendorAdapter} implementation for
* Oracle TopLink Essentials. Developed and tested against TopLink Essentials v2.
*
* <p>Exposes TopLink's persistence provider and EntityManager extension interface,
* and supports {@link AbstractJpaVendorAdapter}'s common configuration settings.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 2.0
* @see oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider
* @see oracle.toplink.essentials.ejb.cmp3.EntityManager
* @deprecated as of Spring 3.1, in favor of the EclipseLink project and
* Spring's corresponding {@link EclipseLinkJpaVendorAdapter}
*/
@Deprecated
public class TopLinkJpaVendorAdapter extends AbstractJpaVendorAdapter {
private final PersistenceProvider persistenceProvider = new EntityManagerFactoryProvider();
private final JpaDialect jpaDialect = new TopLinkJpaDialect();
public PersistenceProvider getPersistenceProvider() {
return this.persistenceProvider;
}
@Override
public String getPersistenceProviderRootPackage() {
return "oracle.toplink.essentials";
}
@Override
public Map<String, Object> getJpaPropertyMap() {
Map<String, Object> jpaProperties = new HashMap<String, Object>();
if (getDatabasePlatform() != null) {
jpaProperties.put(TopLinkProperties.TARGET_DATABASE, getDatabasePlatform());
}
else if (getDatabase() != null) {
String targetDatabase = determineTargetDatabaseName(getDatabase());
if (targetDatabase != null) {
jpaProperties.put(TopLinkProperties.TARGET_DATABASE, targetDatabase);
}
}
if (isGenerateDdl()) {
jpaProperties.put(EntityManagerFactoryProvider.DDL_GENERATION,
EntityManagerFactoryProvider.CREATE_ONLY);
jpaProperties.put(EntityManagerFactoryProvider.DDL_GENERATION_MODE,
EntityManagerFactoryProvider.DDL_DATABASE_GENERATION);
}
if (isShowSql()) {
jpaProperties.put(TopLinkProperties.LOGGING_LEVEL, Level.FINE.toString());
}
return jpaProperties;
}
/**
* Determine the TopLink target database name for the given database.
* @param database the specified database
* @return the TopLink target database name, or {@code null} if none found
*/
protected String determineTargetDatabaseName(Database database) {
switch (database) {
case DB2: return TargetDatabase.DB2;
case DERBY: return TargetDatabase.Derby;
case HSQL: return TargetDatabase.HSQL;
case INFORMIX: return TargetDatabase.Informix;
case MYSQL: return TargetDatabase.MySQL4;
case ORACLE: return TargetDatabase.Oracle;
case POSTGRESQL: return TargetDatabase.PostgreSQL;
case SQL_SERVER: return TargetDatabase.SQLServer;
case SYBASE: return TargetDatabase.Sybase;
default: return null;
}
}
@Override
public JpaDialect getJpaDialect() {
return this.jpaDialect;
}
@Override
public Class<? extends EntityManager> getEntityManagerInterface() {
return oracle.toplink.essentials.ejb.cmp3.EntityManager.class;
}
}