diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/AbstractSessionFactory.java b/org.springframework.orm/src/main/java/org/springframework/orm/toplink/AbstractSessionFactory.java deleted file mode 100644 index 2f4d7ec7a6..0000000000 --- a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/AbstractSessionFactory.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright 2002-2008 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.toplink; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; - -import oracle.toplink.exceptions.TopLinkException; -import oracle.toplink.sessions.Session; -import oracle.toplink.sessions.UnitOfWork; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Abstract SessionFactory implementation that creates proxies for - * "managed" client Sessions and transaction-aware Session references. - * - *

Delegates to two template methods: - * - * @author Juergen Hoeller - * @since 1.2.6 - * @see #getMasterSession() - * @see #createClientSession() - */ -public abstract class AbstractSessionFactory implements SessionFactory { - - /** Logger available to subclasses */ - protected final Log logger = LogFactory.getLog(getClass()); - - - /** - * Create a plain client Session for this factory's master Session. - * @see #createClientSession() - */ - public Session createSession() throws TopLinkException { - logger.debug("Creating TopLink client Session"); - return createClientSession(); - } - - /** - * Create a "managed" client Session reference for an underlying - * client Session created for this factory. - * @see #createClientSession() - */ - public Session createManagedClientSession() throws TopLinkException { - logger.debug("Creating managed TopLink client Session"); - Session target = createClientSession(); - return (Session) Proxy.newProxyInstance(target.getClass().getClassLoader(), - new Class[] {Session.class}, new ManagedClientInvocationHandler(target)); - } - - /** - * Create a transaction-aware Session reference for this factory's master Session, - * expecting transactions to be registered for this SessionFactory. - * @see #getMasterSession() - * @see oracle.toplink.sessions.Session#getActiveSession() - * @see oracle.toplink.sessions.Session#getActiveUnitOfWork() - */ - public Session createTransactionAwareSession() throws TopLinkException { - logger.debug("Creating transaction-aware TopLink Session"); - return createTransactionAwareSession(this); - } - - /** - * Create a transaction-aware Session reference for this factory's master Session, - * expecting transactions to be registered for the given SessionFactory. - *

This method is public to allow custom SessionFactory facades to access - * it directly, if necessary. - * @param sessionFactory the SessionFactory that transactions - * are expected to be registered for - * @see #getMasterSession() - * @see oracle.toplink.sessions.Session#getActiveSession() - * @see oracle.toplink.sessions.Session#getActiveUnitOfWork() - */ - public Session createTransactionAwareSession(SessionFactory sessionFactory) throws TopLinkException { - Session target = getMasterSession(); - return (Session) Proxy.newProxyInstance( - target.getClass().getClassLoader(), new Class[] {Session.class}, - new TransactionAwareInvocationHandler(sessionFactory, target)); - } - - - /** - * Return this factory's "master" Session. - * For example, a TopLink ServerSession. - *

Used for creating transaction-aware Session reference. - */ - protected abstract Session getMasterSession(); - - /** - * Create a new client Session for this factory's master Session. - * For example, a TopLink ClientSession. - *

Used for creating plain Sessions and "managed" client Sessions. - * @throws TopLinkException if creation of a client Session failed - */ - protected abstract Session createClientSession() throws TopLinkException; - - - /** - * Invocation handler that decorates a client Session with an "active" - * UnitOfWork. For use in situations where Spring's TopLinkTransactionManager - * requires a "managed" thread-safe TopLink Session. - */ - private static class ManagedClientInvocationHandler implements InvocationHandler { - - private final Session target; - - private final UnitOfWork uow; - - public ManagedClientInvocationHandler(Session target) { - this.target = target; - this.uow = this.target.acquireUnitOfWork(); - } - - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - // Invocation on Session interface coming in... - - if (method.getName().equals("equals")) { - // Only consider equal when proxies are identical. - return (proxy == args[0] ? Boolean.TRUE : Boolean.FALSE); - } - else if (method.getName().equals("hashCode")) { - // Use hashCode of SessionFactory proxy. - return new Integer(System.identityHashCode(proxy)); - } - else if (method.getName().equals("getActiveSession")) { - return this.target; - } - else if (method.getName().equals("getActiveUnitOfWork")) { - return this.uow; - } - else if (method.getName().equals("release")) { - this.uow.release(); - this.target.release(); - } - - // Invoke method on target Session. - try { - return method.invoke(this.target, args); - } - catch (InvocationTargetException ex) { - throw ex.getTargetException(); - } - } - } - - - /** - * Invocation handler that delegates getActiveSession calls - * to SessionFactoryUtils, for being aware of thread-bound transactions. - */ - private static class TransactionAwareInvocationHandler implements InvocationHandler { - - private final SessionFactory sessionFactory; - - private final Session target; - - public TransactionAwareInvocationHandler(SessionFactory sessionFactory, Session target) { - this.sessionFactory = sessionFactory; - this.target = target; - } - - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - // Invocation on Session interface coming in... - - if (method.getName().equals("equals")) { - // Only consider equal when proxies are identical. - return (proxy == args[0] ? Boolean.TRUE : Boolean.FALSE); - } - else if (method.getName().equals("hashCode")) { - // Use hashCode of SessionFactory proxy. - return new Integer(System.identityHashCode(proxy)); - } - else if (method.getName().equals("getActiveSession")) { - // Handle getActiveSession method: return transactional Session, if any. - try { - return SessionFactoryUtils.doGetSession(this.sessionFactory, false); - } - catch (IllegalStateException ex) { - // getActiveSession is supposed to return the Session itself if no active one found. - return this.target; - } - } - else if (method.getName().equals("getActiveUnitOfWork")) { - // Handle getActiveUnitOfWork method: return transactional UnitOfWork, if any. - try { - return SessionFactoryUtils.doGetSession(this.sessionFactory, false).getActiveUnitOfWork(); - } - catch (IllegalStateException ex) { - // getActiveUnitOfWork is supposed to return null if no active one found. - return null; - } - } - - // Invoke method on target Session. - try { - return method.invoke(this.target, args); - } - catch (InvocationTargetException ex) { - throw ex.getTargetException(); - } - } - } - -} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/LocalSessionFactory.java b/org.springframework.orm/src/main/java/org/springframework/orm/toplink/LocalSessionFactory.java deleted file mode 100644 index f85ee3d203..0000000000 --- a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/LocalSessionFactory.java +++ /dev/null @@ -1,458 +0,0 @@ -/* - * Copyright 2002-2008 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.toplink; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; - -import javax.sql.DataSource; - -import oracle.toplink.exceptions.TopLinkException; -import oracle.toplink.internal.databaseaccess.DatabasePlatform; -import oracle.toplink.jndi.JNDIConnector; -import oracle.toplink.sessionbroker.SessionBroker; -import oracle.toplink.sessions.DatabaseLogin; -import oracle.toplink.sessions.DatabaseSession; -import oracle.toplink.sessions.SessionLog; -import oracle.toplink.threetier.ServerSession; -import oracle.toplink.tools.sessionconfiguration.XMLLoader; -import oracle.toplink.tools.sessionmanagement.SessionManager; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.PropertyAccessorFactory; -import org.springframework.util.ClassUtils; -import org.springframework.util.CollectionUtils; -import org.springframework.util.ReflectionUtils; - -/** - * Convenient JavaBean-style factory for a TopLink SessionFactory instance. - * Loads a TopLink sessions.xml file from the class path, exposing a - * specific TopLink Session defined there (usually a ServerSession). - * - *

TopLink Session configuration is done using a sessions.xml file. - * The most convenient way to create the sessions.xml file is to use - * the Oracle TopLink SessionsEditor workbench. The sessions.xml file - * contains all runtime configuration and points to a second XML or Class resource - * from which to load the actual TopLink project metadata (which defines mappings). - * - *

LocalSessionFactory loads the sessions.xml file during - * initialization in order to bootstrap the specified TopLink (Server)Session. - * The name of the actual config resource and the name of the Session to be loaded, - * if different from sessions.xml and "Session", respectively, can be - * configured through bean properties. - * - *

All resources (sessions.xml and Mapping Workbench metadata) are - * loaded using ClassLoader.getResourceAsStream calls by TopLink, so - * users may need to configure a ClassLoader with appropriate visibility. This is - * particularly important in J2EE environments where the TopLink metadata might be - * deployed to a different location than the Spring configuration. The ClassLoader - * used to search for the TopLink metadata and to load the persistent classes - * defined there will default to the the context ClassLoader for the current Thread. - * - *

TopLink's debug logging can be redirected to Commons Logging by passing a - * CommonsLoggingSessionLog to the "sessionLog" bean property. Otherwise, TopLink - * uses it's own DefaultSessionLog, whose levels are configured in the - * sessions.xml file. - * - *

This class has been tested against both TopLink 9.0.4 and TopLink 10.1.3. - * It will automatically adapt to the TopLink version encountered: for example, - * using an XMLSessionConfigLoader on 10.1.3, but an XMLLoader on 9.0.4. - * - *

NOTE: When defining a TopLink SessionFactory in a Spring application - * context, you will usually define a bean of type LocalSessionFactoryBean. - * LocalSessionFactoryBean is a subclass of this factory, which will automatically - * expose the created TopLink SessionFactory instance as bean reference. - * - * @author Juergen Hoeller - * @author James Clark - * @since 1.2 - * @see LocalSessionFactoryBean - * @see TopLinkTemplate#setSessionFactory - * @see TopLinkTransactionManager#setSessionFactory - * @see SingleSessionFactory - * @see ServerSessionFactory - * @see oracle.toplink.threetier.ServerSession - * @see oracle.toplink.tools.sessionconfiguration.XMLLoader - * @see oracle.toplink.tools.sessionconfiguration.XMLSessionConfigLoader - */ -public class LocalSessionFactory { - - /** - * The default location of the sessions.xml TopLink configuration file: - * "sessions.xml" in the class path. - */ - public static final String DEFAULT_SESSIONS_XML = "sessions.xml"; - - /** - * The default session name to look for in the sessions.xml: "Session". - */ - public static final String DEFAULT_SESSION_NAME = "Session"; - - - protected final Log logger = LogFactory.getLog(getClass()); - - /** - * The classpath location of the sessions TopLink configuration file. - */ - private String configLocation = DEFAULT_SESSIONS_XML; - - /** - * The session name to look for in the sessions.xml configuration file. - */ - private String sessionName = DEFAULT_SESSION_NAME; - - /** - * The ClassLoader to use to load the sessions.xml and project XML files. - */ - private ClassLoader sessionClassLoader; - - private DatabaseLogin databaseLogin; - - private final Map loginPropertyMap = new HashMap(); - - private DataSource dataSource; - - private DatabasePlatform databasePlatform; - - private SessionLog sessionLog; - - - /** - * Set the TopLink sessions.xml configuration file that defines - * TopLink Sessions, as class path resource location. - *

The sessions.xml file will usually be placed in the META-INF - * directory or root path of a JAR file, or the WEB-INF/classes - * directory of a WAR file (specifying "META-INF/toplink-sessions.xml" or - * simply "toplink-sessions.xml" as config location, respectively). - *

The default config location is "sessions.xml" in the root of the class path. - * @param configLocation the class path location of the sessions.xml file - */ - public void setConfigLocation(String configLocation) { - this.configLocation = configLocation; - } - - /** - * Set the name of the TopLink Session, as defined in TopLink's - * sessions.xml configuration file. - * The default session name is "Session". - */ - public void setSessionName(String sessionName) { - this.sessionName = sessionName; - } - - /** - * Set the ClassLoader that should be used to lookup the config resources. - * If nothing is set here, then we will try to use the Thread context ClassLoader - * and the ClassLoader that loaded this factory class, in that order. - *

This ClassLoader will be used to load the TopLink configuration files - * and the project metadata. Furthermore, the TopLink ConversionManager will - * use this ClassLoader to load all TopLink entity classes. If the latter is not - * appropriate, users can configure a pre-login SessionEvent to alter the - * ConversionManager ClassLoader that TopLink will use at runtime. - */ - public void setSessionClassLoader(ClassLoader sessionClassLoader) { - this.sessionClassLoader = sessionClassLoader; - } - - /** - * Specify the DatabaseLogin instance that carries the TopLink database - * configuration to use. This is an alternative to specifying that information - * in a <login> tag in the sessions.xml configuration file, - * allowing for configuring a DatabaseLogin instance as standard Spring bean - * definition (being able to leverage Spring's placeholder mechanism, etc). - *

The DatabaseLogin instance can either carry traditional JDBC config properties - * or hold a nested TopLink Connector instance, pointing to the connection pool to use. - * DatabaseLogin also holds the TopLink DatabasePlatform instance that defines the - * database product that TopLink is talking to (for example, HSQLPlatform). - *

WARNING: Overriding the Login instance has been reported to not - * work on TopLink 10.1.3.0 and 10.1.3.1. Specify {@link #setLoginProperties - * "loginProperties"} or {@link #getLoginPropertyMap "loginPropertyMap[...]"} - * entries instead, if you prefer to have the login configuration defined - * on the Spring LocalSessionFactory. - */ - public void setDatabaseLogin(DatabaseLogin databaseLogin) { - this.databaseLogin = databaseLogin; - } - - /** - * Specify TopLink login properties, to be passed to - * the {@link oracle.toplink.sessions.DatabaseLogin} instance. - *

Can be populated with a String "value" (parsed via PropertiesEditor) - * or a "props" element in XML bean definitions. - * @see oracle.toplink.sessions.DatabaseLogin - */ - public void setLoginProperties(Properties loginProperties) { - CollectionUtils.mergePropertiesIntoMap(loginProperties, this.loginPropertyMap); - } - - /** - * Specify TopLink login properties as a Map, to be passed to - * the {@link oracle.toplink.sessions.DatabaseLogin} instance. - *

Can be populated with a "map" or "props" element in XML bean definitions. - * @see oracle.toplink.sessions.DatabaseLogin - */ - public void setLoginPropertyMap(Map loginProperties) { - if (loginProperties != null) { - this.loginPropertyMap.putAll(loginProperties); - } - } - - /** - * Allow Map access to the TopLink login properties to be passed to the - * DatabaseLogin instance, with the option to add or override specific entries. - *

Useful for specifying entries directly, for example via - * "loginPropertyMap[tableQualifier]". - * @see oracle.toplink.sessions.DatabaseLogin - */ - public Map getLoginPropertyMap() { - return this.loginPropertyMap; - } - - /** - * Specify a standard JDBC DataSource that TopLink should use as connection pool. - * This allows for using a shared DataSource definition instead of TopLink's - * own connection pool. - *

A passed-in DataSource will be wrapped in an appropriate TopLink Connector - * and registered with the TopLink DatabaseLogin instance (either the default - * instance or one passed in through the "databaseLogin" property). The - * "usesExternalConnectionPooling" flag will automatically be set to "true". - * @see oracle.toplink.sessions.DatabaseLogin#setConnector(oracle.toplink.sessions.Connector) - * @see oracle.toplink.sessions.DatabaseLogin#setUsesExternalConnectionPooling(boolean) - * @see #setDatabaseLogin(oracle.toplink.sessions.DatabaseLogin) - */ - public void setDataSource(DataSource dataSource) { - this.dataSource = dataSource; - } - - /** - * Specify the TopLink DatabasePlatform instance that the Session should use: - * for example, HSQLPlatform. This is an alternative to specifying the platform - * in a <login> tag in the sessions.xml configuration file. - *

A passed-in DatabasePlatform will be registered with the TopLink - * DatabaseLogin instance (either the default instance or one passed in - * through the "databaseLogin" property). - * @see oracle.toplink.internal.databaseaccess.HSQLPlatform - * @see oracle.toplink.platform.database.HSQLPlatform - */ - public void setDatabasePlatform(DatabasePlatform databasePlatform) { - this.databasePlatform = databasePlatform; - } - - /** - * Specify a TopLink SessionLog instance to use for detailed logging of the - * Session's activities: for example, DefaultSessionLog (which logs to the - * console), JavaLog (which logs through JDK 1.4'S java.util.logging, - * available as of TopLink 10.1.3), or CommonsLoggingSessionLog / - * CommonsLoggingSessionLog904 (which logs through Commons Logging, - * on TopLink 10.1.3 and 9.0.4, respectively). - *

Note that detailed Session logging is usually only useful for debug - * logging, with adjustable detail level. As of TopLink 10.1.3, TopLink also - * uses different log categories, which allows for fine-grained filtering of - * log messages. For standard execution, no SessionLog needs to be specified. - * @see oracle.toplink.sessions.DefaultSessionLog - * @see oracle.toplink.logging.DefaultSessionLog - * @see oracle.toplink.logging.JavaLog - * @see org.springframework.orm.toplink.support.CommonsLoggingSessionLog - * @see org.springframework.orm.toplink.support.CommonsLoggingSessionLog904 - */ - public void setSessionLog(SessionLog sessionLog) { - this.sessionLog = sessionLog; - } - - - /** - * Create a TopLink SessionFactory according to the configuration settings. - * @return the new TopLink SessionFactory - * @throws TopLinkException in case of errors - */ - public SessionFactory createSessionFactory() throws TopLinkException { - if (logger.isInfoEnabled()) { - logger.info("Initializing TopLink SessionFactory from [" + this.configLocation + "]"); - } - - // Determine class loader to use. - ClassLoader classLoader = - (this.sessionClassLoader != null ? this.sessionClassLoader : ClassUtils.getDefaultClassLoader()); - - // Initialize the TopLink Session, using the configuration file - // and the session name. - DatabaseSession session = loadDatabaseSession(this.configLocation, this.sessionName, classLoader); - - // It is possible for SessionManager to return a null Session! - if (session == null) { - throw new IllegalStateException( - "A session named '" + this.sessionName + "' could not be loaded from resource [" + - this.configLocation + "] using ClassLoader [" + classLoader + "]. " + - "This is most likely a deployment issue: Can the class loader access the resource?"); - } - - DatabaseLogin login = (this.databaseLogin != null ? this.databaseLogin : session.getLogin()); - - // Apply specified login properties to the DatabaseLogin instance. - if (this.loginPropertyMap != null) { - PropertyAccessorFactory.forBeanPropertyAccess(login).setPropertyValues(this.loginPropertyMap); - } - - // Override default connection pool with specified DataSource, if any. - if (this.dataSource != null) { - login.setConnector(new JNDIConnector(this.dataSource)); - login.setUsesExternalConnectionPooling(true); - } - - // Override default DatabasePlatform with specified one, if any. - if (this.databasePlatform != null) { - login.usePlatform(this.databasePlatform); - } - - // Override default DatabaseLogin instance with specified one, if any. - if (this.databaseLogin != null) { - setDatabaseLogin(session, this.databaseLogin); - } - - // Override default SessionLog with specified one, if any. - if (this.sessionLog != null) { - session.setSessionLog(this.sessionLog); - session.logMessages(); - } - - // Log in and create corresponding SessionFactory. - session.login(); - return newSessionFactory(session); - } - - /** - * Handle differences between the Session.setLogin interface - * between TopLink 9.0.4 to 10.1.3. - *

The Login interface was introduced in TopLink 10.1.3. - * @param session the DatabaseSession being logged in - * @param login the DatabaseLogin injected by Spring - * @see oracle.toplink.sessions.DatabaseSession#setLogin - */ - protected void setDatabaseLogin(DatabaseSession session, DatabaseLogin login) { - Method setLoginMethod = null; - try { - // Search for the new 10.1.3 Login interface... - Class loginClass = DatabaseSession.class.getClassLoader().loadClass("oracle.toplink.sessions.Login"); - setLoginMethod = DatabaseSession.class.getMethod("setLogin", new Class[] {loginClass}); - if (logger.isDebugEnabled()) { - logger.debug("Using TopLink 10.1.3 setLogin(Login) API"); - } - } - catch (Exception ex) { - // TopLink 10.1.3 Login interface not found -> - // fall back to TopLink 9.0.4's setLogin(DatabaseLogin) - if (logger.isDebugEnabled()) { - logger.debug("Using TopLink 9.0.4 setLogin(DatabaseLogin) API"); - } - session.setLogin(login); - return; - } - - // Invoke the 10.1.3 version: Session.setLogin(Login) - ReflectionUtils.invokeMethod(setLoginMethod, session, new Object[] {login}); - } - - /** - * Load the specified DatabaseSession from the TopLink sessions.xml - * configuration file. - * @param configLocation the class path location of the sessions.xml file - * @param sessionName the name of the TopLink Session in the configuration file - * @param sessionClassLoader the class loader to use - * @return the DatabaseSession instance - * @throws TopLinkException in case of errors - */ - protected DatabaseSession loadDatabaseSession( - String configLocation, String sessionName, ClassLoader sessionClassLoader) - throws TopLinkException { - - SessionManager manager = getSessionManager(); - - // Try to find TopLink 10.1.3 XMLSessionConfigLoader. - Method getSessionMethod = null; - Object loader = null; - try { - Class loaderClass = SessionManager.class.getClassLoader().loadClass( - "oracle.toplink.tools.sessionconfiguration.XMLSessionConfigLoader"); - getSessionMethod = SessionManager.class.getMethod("getSession", - new Class[] {loaderClass, String.class, ClassLoader.class, boolean.class, boolean.class, boolean.class}); - if (logger.isDebugEnabled()) { - logger.debug("Using TopLink 10.1.3 XMLSessionConfigLoader"); - } - Constructor ctor = loaderClass.getConstructor(new Class[] {String.class}); - loader = ctor.newInstance(new Object[] {configLocation}); - } - catch (Exception ex) { - // TopLink 10.1.3 XMLSessionConfigLoader not found -> - // fall back to TopLink 9.0.4 XMLLoader. - if (logger.isDebugEnabled()) { - logger.debug("Using TopLink 9.0.4 XMLLoader"); - } - XMLLoader xmlLoader = new XMLLoader(configLocation); - return (DatabaseSession) manager.getSession(xmlLoader, sessionName, sessionClassLoader, false, false); - } - - // TopLink 10.1.3 XMLSessionConfigLoader found -> create loader instance - // through reflection and fetch specified Session from SessionManager. - // This invocation will check if the ClassLoader passed in is the same - // as the one used to a session currently loaded with the same "sessionName" - // If the ClassLoaders are different, then this LocalSessionFactory is being - // re-loaded after a hot-deploy and the existing DatabaseSession will be logged - // out and re-built from scratch. - return (DatabaseSession) ReflectionUtils.invokeMethod(getSessionMethod, manager, - new Object[] {loader, sessionName, sessionClassLoader, Boolean.FALSE, Boolean.FALSE, Boolean.TRUE}); - } - - /** - * Return the TopLink SessionManager to use for loading DatabaseSessions. - *

The default implementation creates a new plain SessionManager instance, - * leading to completely independent TopLink Session instances. Could be - * overridden to return a shared or pre-configured SessionManager. - * @return the TopLink SessionManager instance - */ - protected SessionManager getSessionManager() { - return new SessionManager(); - } - - /** - * Create a new SessionFactory for the given TopLink DatabaseSession. - *

The default implementation creates a ServerSessionFactory for a - * ServerSession and a SingleSessionFactory for a plain DatabaseSession. - * @param session the TopLink DatabaseSession to create a SessionFactory for - * @return the SessionFactory - * @throws TopLinkException in case of errors - * @see ServerSessionFactory - * @see SingleSessionFactory - * @see oracle.toplink.threetier.ServerSession - * @see oracle.toplink.sessions.DatabaseSession - */ - protected SessionFactory newSessionFactory(DatabaseSession session) { - if (session instanceof ServerSession) { - return new ServerSessionFactory((ServerSession) session); - } - else if (session instanceof SessionBroker) { - return new SessionBrokerSessionFactory((SessionBroker) session); - } - else { - return new SingleSessionFactory(session); - } - } - -} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/LocalSessionFactoryBean.java b/org.springframework.orm/src/main/java/org/springframework/orm/toplink/LocalSessionFactoryBean.java deleted file mode 100644 index 4a87c95852..0000000000 --- a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/LocalSessionFactoryBean.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright 2002-2007 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.toplink; - -import java.sql.SQLException; - -import oracle.toplink.exceptions.DatabaseException; -import oracle.toplink.exceptions.TopLinkException; - -import org.springframework.beans.factory.BeanClassLoaderAware; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.dao.DataAccessException; -import org.springframework.dao.support.PersistenceExceptionTranslator; -import org.springframework.jdbc.support.SQLExceptionTranslator; - -/** - * {@link org.springframework.beans.factory.FactoryBean} that creates a - * TopLink {@link SessionFactory}. This is the usual way to set up a shared - * TopLink SessionFactory in a Spring application context; the SessionFactory - * can then be passed to TopLink-based DAOs via dependency injection. - * - *

See the base class {@link LocalSessionFactory} for configuration details. - * - *

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

If your DAOs expect to receive a raw TopLink Session, consider defining a - * {@link org.springframework.orm.toplink.support.TransactionAwareSessionAdapter} - * in front of this bean. This adapter will provide a TopLink Session rather - * than a SessionFactory as bean reference. Your DAOs can then, for example, - * access the currently active Session and UnitOfWork via - * Session.getActiveSession() and Session.getActiveUnitOfWork(), - * respectively. Note that you can still access the SessionFactory as well, by - * defining a bean reference that points directly at the LocalSessionFactoryBean. - * - * @author Juergen Hoeller - * @since 1.2 - * @see LocalSessionFactory - * @see org.springframework.orm.toplink.support.TransactionAwareSessionAdapter - * @see org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor - */ -public class LocalSessionFactoryBean extends LocalSessionFactory - implements FactoryBean, BeanClassLoaderAware, InitializingBean, DisposableBean, PersistenceExceptionTranslator { - - private SessionFactory sessionFactory; - - private SQLExceptionTranslator jdbcExceptionTranslator; - - - /** - * Set the JDBC exception translator for this SessionFactory. - *

Applied to any SQLException root cause of a TopLink DatabaseException, - * within Spring's PersistenceExceptionTranslator mechanism. - * The default is to rely on TopLink's native exception translation. - * @see oracle.toplink.exceptions.DatabaseException - * @see org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator - * @see org.springframework.jdbc.support.SQLStateSQLExceptionTranslator - */ - public void setJdbcExceptionTranslator(SQLExceptionTranslator jdbcExceptionTranslator) { - this.jdbcExceptionTranslator = jdbcExceptionTranslator; - } - - /** - * Return the JDBC exception translator for this instance, if any. - */ - public SQLExceptionTranslator getJdbcExceptionTranslator() { - return this.jdbcExceptionTranslator; - } - - /** - * Sets the given bean ClassLoader as TopLink Session ClassLoader. - * @see #setSessionClassLoader - */ - public void setBeanClassLoader(ClassLoader classLoader) { - setSessionClassLoader(classLoader); - } - - public void afterPropertiesSet() throws TopLinkException { - this.sessionFactory = createSessionFactory(); - } - - - public Object getObject() { - return this.sessionFactory; - } - - public Class getObjectType() { - return (this.sessionFactory != null ? this.sessionFactory.getClass() : SessionFactory.class); - } - - public boolean isSingleton() { - return true; - } - - - /** - * Implementation of the PersistenceExceptionTranslator interface, - * as autodetected by Spring's PersistenceExceptionTranslationPostProcessor. - *

Converts the exception if it is a TopLinkException; - * else returns null to indicate an unknown exception. - * @see org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor - * @see #convertTopLinkAccessException - */ - public DataAccessException translateExceptionIfPossible(RuntimeException ex) { - if (ex instanceof TopLinkException) { - return convertTopLinkAccessException((TopLinkException) ex); - } - return null; - } - - /** - * Convert the given TopLinkException to an appropriate exception from the - * org.springframework.dao hierarchy. - *

Will automatically apply a specified SQLExceptionTranslator to a - * TopLink DatabaseException, else rely on TopLink's default translation. - * @param ex TopLinkException that occured - * @return a corresponding DataAccessException - * @see SessionFactoryUtils#convertTopLinkAccessException - * @see #setJdbcExceptionTranslator - */ - public DataAccessException convertTopLinkAccessException(TopLinkException ex) { - if (getJdbcExceptionTranslator() != null && ex instanceof DatabaseException) { - Throwable internalEx = ex.getInternalException(); - // Should always be a SQLException inside a DatabaseException. - if (internalEx instanceof SQLException) { - return getJdbcExceptionTranslator().translate( - "TopLink operation: " + ex.getMessage(), null, (SQLException) internalEx); - } - } - return SessionFactoryUtils.convertTopLinkAccessException(ex); - } - - - public void destroy() { - logger.info("Closing TopLink SessionFactory"); - this.sessionFactory.close(); - } - -} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/ServerSessionFactory.java b/org.springframework.orm/src/main/java/org/springframework/orm/toplink/ServerSessionFactory.java deleted file mode 100644 index 74795dfc4f..0000000000 --- a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/ServerSessionFactory.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2002-2005 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.toplink; - -import oracle.toplink.exceptions.TopLinkException; -import oracle.toplink.sessions.Session; -import oracle.toplink.threetier.ServerSession; - -/** - * Full-fledged default implementation of the SessionFactory interface: - * creates ClientSessions for a given ServerSession. - * - *

Can create a special ClientSession subclass for managed Sessions, carrying - * an active UnitOfWork that expects to be committed at transaction completion - * (just like a plain TopLink Session does within a JTA transaction). - * - *

Can also create a transaction-aware Session reference that returns the - * active transactional Session on getActiveSession. - * - * @author Juergen Hoeller - * @since 1.2 - * @see SingleSessionFactory - * @see oracle.toplink.sessions.Session#getActiveUnitOfWork() - * @see oracle.toplink.sessions.Session#getActiveSession() - */ -public class ServerSessionFactory extends AbstractSessionFactory { - - private final ServerSession serverSession; - - - /** - * Create a new ServerSessionFactory for the given ServerSession. - * @param serverSession the TopLink ServerSession to create ClientSessions for - */ - public ServerSessionFactory(ServerSession serverSession) { - this.serverSession = serverSession; - } - - - /** - * Return this factory's ServerSession as-is. - */ - @Override - protected Session getMasterSession() { - return this.serverSession; - } - - /** - * Create a plain ClientSession for this factory's ServerSession. - * @see oracle.toplink.threetier.ServerSession#acquireClientSession() - */ - @Override - protected Session createClientSession() throws TopLinkException { - return this.serverSession.acquireClientSession(); - } - - - /** - * Shut the pre-configured TopLink ServerSession down. - * @see oracle.toplink.sessions.DatabaseSession#logout() - * @see oracle.toplink.sessions.Session#release() - */ - public void close() { - this.serverSession.logout(); - this.serverSession.release(); - } - -} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/SessionBrokerSessionFactory.java b/org.springframework.orm/src/main/java/org/springframework/orm/toplink/SessionBrokerSessionFactory.java deleted file mode 100644 index 30cfe4006d..0000000000 --- a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/SessionBrokerSessionFactory.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2002-2005 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.toplink; - -import oracle.toplink.exceptions.TopLinkException; -import oracle.toplink.exceptions.ValidationException; -import oracle.toplink.sessionbroker.SessionBroker; -import oracle.toplink.sessions.Session; - -/** - * Spring SessionFactory implementation allowing users to - * inject a TopLink Session built from a TopLink SessionBroker. - * - * SessionBrokers are used identically to any other TopLink Session. DAO code - * should never have to distinguish between Sessions which broker requests to - * multiple databases and Sessions which manage requests to a single database. - * - * The only pertinent difference in the SessionBroker api involves the method - * for obtaining a thread-safe "client" Session from the SessionBroker. - * Instead of the typical acquireClientSession - * method, this SessionFactory implementation uses the - * acquireClientSessionBroker method. - * If a SessionBroker aggregates non thread-safe DatabaseSessions, - * the factory will throw UnsupportedOperationExceptions - * if used to create managed or transaction-aware Sessions. - * - * @author James Clark - * @author Juergen Hoeller - * @since 1.2.6 - * @see org.springframework.orm.toplink.ServerSessionFactory - * @see oracle.toplink.threetier.ServerSession#acquireClientSession() - * @see oracle.toplink.sessionbroker.SessionBroker#acquireClientSessionBroker() - */ -public class SessionBrokerSessionFactory extends AbstractSessionFactory { - - private final SessionBroker sessionBroker; - - - /** - * Create a new SessionBrokerSessionFactory for the given SessionBroker. - * @param broker the TopLink SessionBroker to fetch Sessions from - */ - public SessionBrokerSessionFactory(SessionBroker broker) { - this.sessionBroker = broker; - } - - - /** - * Try to create a client Session; fall back to the master Session, - * if no client Session can be created (because of the session broker's - * configuration). - * @see #createClientSession() - * @see #getMasterSession() - */ - @Override - public Session createSession() throws TopLinkException { - try { - return createClientSession(); - } - catch (ValidationException ex) { - logger.debug( - "Could not create TopLink client session for SessionBroker - returning SessionBroker itself", ex); - return getMasterSession(); - } - } - - /** - * Return this factory's SessionBroker as-is. - */ - @Override - protected Session getMasterSession() { - return this.sessionBroker; - } - - /** - * Create a plain client SessionBroker for this factory's ServerSession. - * @see oracle.toplink.sessionbroker.SessionBroker#acquireClientSessionBroker() - */ - @Override - protected Session createClientSession() throws TopLinkException { - return this.sessionBroker.acquireClientSessionBroker(); - } - - - /** - * Shut the pre-configured TopLink SessionBroker down. - * @see oracle.toplink.sessions.DatabaseSession#logout() - * @see oracle.toplink.sessions.Session#release() - */ - public void close() { - this.sessionBroker.logout(); - this.sessionBroker.release(); - } - -} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/SessionFactory.java b/org.springframework.orm/src/main/java/org/springframework/orm/toplink/SessionFactory.java deleted file mode 100644 index cc9dd3853d..0000000000 --- a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/SessionFactory.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2002-2005 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.toplink; - -import oracle.toplink.exceptions.TopLinkException; -import oracle.toplink.sessions.Session; - -/** - * The SessionFactory interface serves as factory for TopLink Sessions, - * allowing for dependency injection on thread-safe TopLink-based DAOs. - * Used by TopLinkAccessor/Template and TopLinkTransactionManager. - * - *

In contrast to JDO or Hibernate (which define native PersistenceManagerFactory - * and SessionFactory interfaces, respectively), TopLink itself does not provide - * such a factory interface: hence, it is necessary to define it within Spring. - * Note that this interface does not depend on any other Spring interfaces or - * classes, to allow for keeping TopLink-based DAOs as independent as possible. - * - * @author Juergen Hoeller - * @since 1.2 - * @see TopLinkAccessor#setSessionFactory - * @see TopLinkTransactionManager#setSessionFactory - */ -public interface SessionFactory { - - /** - * Create a plain TopLink Session for the current application context. - * Will usually be a new ClientSession for the current thread. - *

The returned Session will participate in JTA transactions (provided that - * TopLink is configured with a corresponding external transaction controller), - * but not in Spring-managed transactions (by TopLinkTransactionManager). - *

This is the factory method to be called by TopLink data access code, - * usually through the SessionFactoryUtils.getSession method - * that checks for a transactional (thread-bound) Session first. - * @return the new TopLink Session - * @throws TopLinkException in case of errors - * @see SessionFactoryUtils#getSession(SessionFactory, boolean) - */ - Session createSession() throws TopLinkException; - - /** - * Create a new managed TopLink client Session for the current context. - * Will usually be a new special ClientSession for the current thread. - *

The returned Session will be prepared to be managed within a Spring - * transaction (by TopLinkTransactionManager). It will carry an active - * UnitOfWork that expects to be committed at transaction completion, - * just like a plain TopLink Session does within a JTA transaction. - *

This method is only supposed to be called by Spring's - * TopLinkTransactionManager or similar TopLink-based transaction managers. - * If a SessionFactory does not support managed Sessions, it should throw - * an UnsupportedOperationException. - * @return the new TopLink Session - * @throws TopLinkException in case of errors - * @see oracle.toplink.sessions.Session#getActiveUnitOfWork() - */ - Session createManagedClientSession() throws TopLinkException; - - /** - * Create a new transaction-aware TopLink Session that exposes the currently - * active Session and UnitOfWork via Session.getActiveSession() - * and Session.getActiveUnitOfWork(), respectively. - *

Such a Session reference can be used analogously to a managed TopLink - * Session in a JTA environment, with Spring-managed transactions backing it. - *

It is usually preferable to let DAOs work with a full SessionFactory, - * accessing TopLink Sessions via SessionFactoryUtils.getSession. - * However, a transaction-aware TopLink Session reference does not impose any - * Spring dependency, so might be preferable if you'd like to keep your data - * access code tied to TopLink API only. - * @return the new TopLink Session - * @throws TopLinkException in case of errors - * @see oracle.toplink.sessions.Session#getActiveSession() - * @see oracle.toplink.sessions.Session#getActiveUnitOfWork() - */ - Session createTransactionAwareSession() throws TopLinkException; - - /** - * Close this SessionFactory, shutting down all internal resources. - */ - void close(); - -} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/SessionFactoryUtils.java b/org.springframework.orm/src/main/java/org/springframework/orm/toplink/SessionFactoryUtils.java deleted file mode 100644 index 2ad2837f8f..0000000000 --- a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/SessionFactoryUtils.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright 2002-2008 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.toplink; - -import oracle.toplink.exceptions.ConcurrencyException; -import oracle.toplink.exceptions.ConversionException; -import oracle.toplink.exceptions.DatabaseException; -import oracle.toplink.exceptions.OptimisticLockException; -import oracle.toplink.exceptions.QueryException; -import oracle.toplink.exceptions.TopLinkException; -import oracle.toplink.sessions.Session; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.dao.ConcurrencyFailureException; -import org.springframework.dao.DataAccessException; -import org.springframework.dao.DataAccessResourceFailureException; -import org.springframework.dao.TypeMismatchDataAccessException; -import org.springframework.transaction.support.ResourceHolder; -import org.springframework.transaction.support.ResourceHolderSynchronization; -import org.springframework.transaction.support.TransactionSynchronizationManager; -import org.springframework.util.Assert; - -/** - * Helper class featuring methods for TopLink Session handling, - * allowing for reuse of TopLink Session instances within transactions. - * Also provides support for exception translation. - * - *

Mainly intended for internal use within the framework. - * - * @author Juergen Hoeller - * @author James Clark - * @since 1.2 - */ -public abstract class SessionFactoryUtils { - - private static final Log logger = LogFactory.getLog(SessionFactoryUtils.class); - - - /** - * Get a TopLink Session for the given SessionFactory. Is aware of and will - * return any existing corresponding Session bound to the current thread, for - * example when using TopLinkTransactionManager. Will create a new Session - * otherwise, if "allowCreate" is true. - *

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

Same as getSession, but throwing the original TopLinkException. - * @param sessionFactory TopLink SessionFactory to create the session with - * @param allowCreate if a non-transactional Session should be created when no - * transactional Session can be found for the current thread - * @return the TopLink Session - * @throws TopLinkException if the Session couldn't be created - * @throws IllegalStateException if no thread-bound Session found and - * "allowCreate" is false - * @see #releaseSession - * @see TopLinkTemplate - */ - public static Session doGetSession(SessionFactory sessionFactory, boolean allowCreate) - throws TopLinkException, IllegalStateException { - - Assert.notNull(sessionFactory, "No SessionFactory specified"); - - SessionHolder sessionHolder = - (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory); - if (sessionHolder != null) { - return sessionHolder.getSession(); - } - - if (!allowCreate && !TransactionSynchronizationManager.isSynchronizationActive()) { - throw new IllegalStateException("No TopLink Session bound to thread, " + - "and configuration does not allow creation of non-transactional one here"); - } - - logger.debug("Creating TopLink Session"); - Session session = sessionFactory.createSession(); - - if (TransactionSynchronizationManager.isSynchronizationActive()) { - logger.debug("Registering new Spring transaction synchronization for new TopLink Session"); - // Use same Session for further TopLink actions within the transaction. - // Thread object will get removed by synchronization at transaction completion. - sessionHolder = new SessionHolder(session); - sessionHolder.setSynchronizedWithTransaction(true); - TransactionSynchronizationManager.registerSynchronization( - new SessionSynchronization(sessionHolder, sessionFactory)); - TransactionSynchronizationManager.bindResource(sessionFactory, sessionHolder); - } - - return session; - } - - /** - * Return whether the given TopLink Session is transactional, that is, - * bound to the current thread by Spring's transaction facilities. - * @param session the TopLink Session to check - * @param sessionFactory TopLink SessionFactory that the Session was created with - * (can be null) - * @return whether the Session is transactional - */ - public static boolean isSessionTransactional(Session session, SessionFactory sessionFactory) { - if (sessionFactory == null) { - return false; - } - SessionHolder sessionHolder = - (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory); - return (sessionHolder != null && session == sessionHolder.getSession()); - } - - /** - * Convert the given TopLinkException to an appropriate exception from the - * org.springframework.dao hierarchy. - * @param ex TopLinkException that occured - * @return the corresponding DataAccessException instance - */ - public static DataAccessException convertTopLinkAccessException(TopLinkException ex) { - if (ex instanceof DatabaseException) { - // SQLException during TopLink access: only passed in here from custom code, - // as TopLinkTemplate will use SQLExceptionTranslator-based handling. - return new TopLinkJdbcException((DatabaseException) ex); - } - if (ex instanceof OptimisticLockException) { - return new TopLinkOptimisticLockingFailureException((OptimisticLockException) ex); - } - if (ex instanceof QueryException) { - return new TopLinkQueryException((QueryException) ex); - } - if (ex instanceof ConcurrencyException) { - return new ConcurrencyFailureException(ex.getMessage(), ex); - } - if (ex instanceof ConversionException) { - return new TypeMismatchDataAccessException(ex.getMessage(), ex); - } - // fallback - return new TopLinkSystemException(ex); - } - - /** - * Close the given Session, created via the given factory, - * if it is not managed externally (i.e. not bound to the thread). - * @param session the TopLink Session to close - * @param sessionFactory TopLink SessionFactory that the Session was created with - * (can be null) - */ - public static void releaseSession(Session session, SessionFactory sessionFactory) { - if (session == null) { - return; - } - // Only release non-transactional Sessions. - if (!isSessionTransactional(session, sessionFactory)) { - doRelease(session); - } - } - - /** - * Perform the actual releasing of the TopLink Session. - * @param session the TopLink Session to release - */ - private static void doRelease(Session session) { - if (session != null) { - logger.debug("Closing TopLink Session"); - try { - session.release(); - } - catch (TopLinkException ex) { - logger.debug("Could not close TopLink Session", ex); - } - catch (Throwable ex) { - logger.debug("Unexpected exception on closing TopLink Session", ex); - } - } - } - - - /** - * Callback for resource cleanup at the end of a Spring-managed JTA transaction, - * i.e. when participating in a JtaTransactionManager transaction. - * @see org.springframework.transaction.jta.JtaTransactionManager - */ - private static class SessionSynchronization extends ResourceHolderSynchronization { - - public SessionSynchronization(SessionHolder sessionHolder, SessionFactory sessionFactory) { - super(sessionHolder, sessionFactory); - } - - @Override - protected boolean shouldReleaseBeforeCompletion() { - return false; - } - - @Override - protected void releaseResource(ResourceHolder resourceHolder, Object resourceKey) { - releaseSession(((SessionHolder) resourceHolder).getSession(), (SessionFactory) resourceKey); - } - } - -} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/SessionHolder.java b/org.springframework.orm/src/main/java/org/springframework/orm/toplink/SessionHolder.java deleted file mode 100644 index 871bd19119..0000000000 --- a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/SessionHolder.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2002-2005 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.toplink; - -import oracle.toplink.sessions.Session; - -import org.springframework.transaction.support.ResourceHolderSupport; -import org.springframework.util.Assert; - -/** - * Session holder, wrapping a TopLink Session. - * TopLinkTransactionManager binds instances of this class - * to the thread, for a given SessionFactory. - * - *

Note: This is an SPI class, not intended to be used by applications. - * - * @author Juergen Hoeller - * @since 1.2 - */ -public class SessionHolder extends ResourceHolderSupport { - - private final Session session; - - - /** - * Create a new SessionHolder for the given TopLink Session. - * @param session the TopLink Session - */ - public SessionHolder(Session session) { - Assert.notNull(session, "Session must not be null"); - this.session = session; - } - - /** - * Return this holder's TopLink Session. - */ - public Session getSession() { - return session; - } - -} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/SessionReadCallback.java b/org.springframework.orm/src/main/java/org/springframework/orm/toplink/SessionReadCallback.java deleted file mode 100644 index 3a020d33e6..0000000000 --- a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/SessionReadCallback.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2002-2005 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.toplink; - -import oracle.toplink.exceptions.TopLinkException; -import oracle.toplink.sessions.Session; -import oracle.toplink.sessions.UnitOfWork; - -/** - * Convenient abstract implementation of the TopLinkCallback interface, - * exposing either the plain TopLink Session or the TopLink UnitOfWork - * (which extends the Session interface) to code that reads persistent objects. - * - *

Exposes the UnitOfWork if there is an active one (that is, if we're running - * within a non-read-only transaction); else exposes the Session itself. - * This allows to modify returned objects within a transaction, which is - * often desired, while the same code will return shared cache objects - * if running outside a transaction. - * - *

If "enforceReadOnly" is demanded, the callback will always expose the - * Session itself, avoiding the UnitOfWork overhead in any case. - * - * @author Juergen Hoeller - * @since 1.2 - * @see oracle.toplink.sessions.Session#getActiveUnitOfWork() - * @see #readFromSession(oracle.toplink.sessions.Session) - */ -public abstract class SessionReadCallback implements TopLinkCallback { - - private final boolean enforceReadOnly; - - /** - * Create a new SessionReadCallback, not enforcing read-only objects. - */ - public SessionReadCallback() { - this.enforceReadOnly = false; - } - - /** - * Create a new SessionReadCallback, enforcing read-only objects if demanded. - * @param enforceReadOnly whether to enforce returning read-only objects, - * even if running within a non-read-only transaction - */ - public SessionReadCallback(boolean enforceReadOnly) { - this.enforceReadOnly = enforceReadOnly; - } - - /** - * Determines the Session to work on (either the active UnitOfWork - * or the plain Session) and delegates to readFromSession. - * @see #readFromSession(oracle.toplink.sessions.Session) - */ - public final Object doInTopLink(Session session) throws TopLinkException { - Session sessionToUse = session; - if (!this.enforceReadOnly) { - UnitOfWork unitOfWork = session.getActiveUnitOfWork(); - if (unitOfWork != null) { - sessionToUse = unitOfWork; - } - } - return readFromSession(sessionToUse); - } - - /** - * Called with a Session to work on, either the active UnitOfWork - * or the plain Session (as determined by the transaction status). - * @param session the TopLink Session to perform read operations on - * @return a result object, or null if none - * @throws TopLinkException in case of TopLink errors - */ - protected abstract Object readFromSession(Session session) throws TopLinkException; - -} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/SingleSessionFactory.java b/org.springframework.orm/src/main/java/org/springframework/orm/toplink/SingleSessionFactory.java deleted file mode 100644 index 0dbe4c5fbb..0000000000 --- a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/SingleSessionFactory.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2002-2005 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.toplink; - -import oracle.toplink.sessions.DatabaseSession; -import oracle.toplink.sessions.Session; - -/** - * Simple implementation of the SessionFactory interface: always returns - * the passed-in Session as-is. - * - *

Useful for testing or standalone usage of TopLink-based data access objects. - * In a server environment, use ServerSessionFactory instead. - * - * @author Juergen Hoeller - * @since 1.2 - * @see ServerSessionFactory - */ -public class SingleSessionFactory implements SessionFactory { - - private final Session session; - - - /** - * Create a new SingleSessionFactory with the given Session. - * @param session the TopLink Session to hold - */ - public SingleSessionFactory(Session session) { - this.session = session; - } - - - /** - * Return the held TopLink Session as-is. - */ - public Session createSession() { - return this.session; - } - - /** - * Throws an UnsupportedOperationException: SingleSessionFactory does not - * support managed client Sessions. Use ServerSessionFactory instead. - */ - public Session createManagedClientSession() { - throw new UnsupportedOperationException("SingleSessionFactory does not support managed client Sessions"); - } - - /** - * Throws an UnsupportedOperationException: SingleSessionFactory does not - * support transaction-aware Sessions. Use ServerSessionFactory instead. - */ - public Session createTransactionAwareSession() { - throw new UnsupportedOperationException("SingleSessionFactory does not support transaction-aware Sessions"); - } - - - /** - * Shut the pre-configured TopLink Session down. - * @see oracle.toplink.sessions.DatabaseSession#logout() - * @see oracle.toplink.sessions.Session#release() - */ - public void close() { - if (this.session instanceof DatabaseSession) { - ((DatabaseSession) this.session).logout(); - } - this.session.release(); - } - -} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkAccessor.java b/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkAccessor.java deleted file mode 100644 index d1d9ba32e0..0000000000 --- a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkAccessor.java +++ /dev/null @@ -1,131 +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.toplink; - -import java.sql.SQLException; - -import oracle.toplink.exceptions.DatabaseException; -import oracle.toplink.exceptions.TopLinkException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.dao.DataAccessException; -import org.springframework.jdbc.support.SQLExceptionTranslator; - -/** - * Base class for TopLinkTemplate and TopLinkInterceptor, defining common properties - * such as SessionFactory and JDBC exception translator. - * - *

Not intended to be used directly. See TopLinkTemplate and TopLinkInterceptor. - * - *

Thanks to Slavik Markovich for implementing the initial TopLink support prototype! - * - * @author Juergen Hoeller - * @since 1.2 - * @see TopLinkTemplate - * @see TopLinkInterceptor - */ -public abstract class TopLinkAccessor implements InitializingBean { - - /** Logger available to subclasses */ - protected final Log logger = LogFactory.getLog(getClass()); - - private SessionFactory sessionFactory; - - private SQLExceptionTranslator jdbcExceptionTranslator; - - - /** - * Set the the TopLink SessionFactory that should be used to create TopLink - * Sessions. This will usually be a ServerSessionFactory in a multi-threaded - * environment, but can also be a SingleSessionFactory for testing purposes - * or for standalone execution. - *

The passed-in SessionFactory will usually be asked for a plain Session - * to perform data access on, unless an active transaction with a thread-bound - * Session is found. - * @see ServerSessionFactory - * @see SingleSessionFactory - * @see SessionFactory#createSession() - * @see SessionFactoryUtils#getSession(SessionFactory, boolean) - */ - public void setSessionFactory(SessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; - } - - /** - * Return the TopLink SessionFactory that should be used to create - * TopLink Sessions. - */ - public SessionFactory getSessionFactory() { - return sessionFactory; - } - - /** - * Set the JDBC exception translator for this instance. - *

Applied to any SQLException root cause of a TopLink DatabaseException. - * The default is to rely on TopLink's native exception translation. - * @param jdbcExceptionTranslator the exception translator - * @see oracle.toplink.exceptions.DatabaseException - * @see org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator - * @see org.springframework.jdbc.support.SQLStateSQLExceptionTranslator - */ - public void setJdbcExceptionTranslator(SQLExceptionTranslator jdbcExceptionTranslator) { - this.jdbcExceptionTranslator = jdbcExceptionTranslator; - } - - /** - * Return the JDBC exception translator for this instance, if any. - */ - public SQLExceptionTranslator getJdbcExceptionTranslator() { - return this.jdbcExceptionTranslator; - } - - - /** - * Check that we were provided with a session to use - */ - public void afterPropertiesSet() { - if (this.sessionFactory == null) { - throw new IllegalArgumentException("sessionFactory is required"); - } - } - - - /** - * Convert the given TopLinkException to an appropriate exception from the - * org.springframework.dao hierarchy. - *

Will automatically apply a specified SQLExceptionTranslator to a - * TopLink DatabaseException, else rely on TopLink's default translation. - * @param ex TopLinkException that occured - * @return a corresponding DataAccessException - * @see SessionFactoryUtils#convertTopLinkAccessException - * @see #setJdbcExceptionTranslator - */ - public DataAccessException convertTopLinkAccessException(TopLinkException ex) { - if (getJdbcExceptionTranslator() != null && ex instanceof DatabaseException) { - Throwable internalEx = ex.getInternalException(); - // Should always be a SQLException inside a DatabaseException. - if (internalEx instanceof SQLException) { - return getJdbcExceptionTranslator().translate( - "TopLink operation: " + ex.getMessage(), null, (SQLException) internalEx); - } - } - return SessionFactoryUtils.convertTopLinkAccessException(ex); - } - -} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkCallback.java b/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkCallback.java deleted file mode 100644 index a4a38591bb..0000000000 --- a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkCallback.java +++ /dev/null @@ -1,77 +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.toplink; - -import oracle.toplink.exceptions.TopLinkException; -import oracle.toplink.sessions.Session; - -/** - * Callback interface for TopLink code. To be used with {@link TopLinkTemplate}'s - * execution methods, often as anonymous classes within a method implementation. - * A typical implementation will call TopLink Session CRUD to perform some - * operations on persistent objects. - * - *

The Session that gets passed into the doInTopLink method - * is usually a thread-safe ClientSession. Since this provides access to the - * TopLink shared cache, it is possible for implementations of this interface to return - * references to read-only objects from the shared cache. These objects - * must not be modified by application code outside of the DAO layer. - * If persistent objects need to be edited, they should be loaded from (or registered with) - * a TopLink UnitOfWork, or they should be explicitly copied and merged back into a - * UnitOfWork at a later point of time. - * - *

Users can access a UnitOfWork by using the getActiveUnitOfWork - * method on the Session. Normally, this will only be done when there is an - * active non-read-only transaction being managed by Spring's {@link TopLinkTransactionManager} - * or by an external transaction controller (usually a J2EE server's JTA provider, - * configured in TopLink). The getActiveUnitOfWork method will return - * null outside of a managed transaction. - * - * @author Juergen Hoeller - * @author James Clark - * @see TopLinkTemplate - * @see TopLinkTransactionManager - */ -public interface TopLinkCallback { - - /** - * Gets called by TopLinkTemplate.execute with an active - * Session. Does not need to care about activating or closing - * the TopLink Session, or handling transactions. - * - *

Note that write operations should usually be performed on the active - * UnitOfWork within an externally controlled transaction, through - * calling getActiveUnitOfWork. However, an implementation can also - * choose to use acquireUnitOfWork to create an independent - * UnitOfWork, which it needs to commit at the end of the operation. - * - *

Allows for returning a result object created within the callback, - * i.e. a domain object or a collection of domain objects. - * A thrown custom RuntimeException is treated as an application exception: - * It gets propagated to the caller of the template. - * - * @param session active TopLink Session - * @return a result object, or null if none - * @throws TopLinkException if thrown by the TopLink API - * @see oracle.toplink.sessions.Session#getActiveUnitOfWork() - * @see oracle.toplink.sessions.Session#acquireUnitOfWork() - * @see TopLinkTemplate#execute - * @see TopLinkTemplate#executeFind - */ - Object doInTopLink(Session session) throws TopLinkException; - -} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkInterceptor.java b/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkInterceptor.java deleted file mode 100644 index c49eb2e60c..0000000000 --- a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkInterceptor.java +++ /dev/null @@ -1,117 +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.toplink; - -import oracle.toplink.exceptions.TopLinkException; -import oracle.toplink.sessions.Session; -import org.aopalliance.intercept.MethodInterceptor; -import org.aopalliance.intercept.MethodInvocation; - -import org.springframework.transaction.support.TransactionSynchronizationManager; - -/** - * This interceptor binds a new TopLink Session to the thread before a method - * call, closing and removing it afterwards in case of any method outcome. - * If there already is a pre-bound Session (e.g. from TopLinkTransactionManager, - * or from a surrounding TopLink-intercepted method), the interceptor simply - * takes part in it. - * - *

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

- * public void doSomeDataAccessAction() {
- *   Session session = this.serverSession.getActiveSession();
- *   ...
- * }
- * - * Note that this interceptor automatically translates TopLinkExceptions, - * via delegating to the SessionFactoryUtils.convertTopLikAccessException - * method that converts them to exceptions that are compatible with the - * org.springframework.dao exception hierarchy (like TopLinkTemplate does). - * This can be turned off if the raw exceptions are preferred. - * - *

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

- * - *

The drawback is the dependency on interceptor configuration. However, note - * that this interceptor is usually not necessary in scenarios where the - * data access code always executes within transactions. A transaction will always - * have a thread-bound Session in the first place, so adding this interceptor to the - * configuration just adds value when potentially executing outside of transactions - * and/or when relying on exception translation. - * - * @author Juergen Hoeller - * @since 1.2 - */ -public class TopLinkInterceptor extends TopLinkAccessor implements MethodInterceptor { - - private boolean exceptionConversionEnabled = true; - - - /** - * Set whether to convert any TopLinkException raised to a Spring DataAccessException, - * compatible with the org.springframework.dao exception hierarchy. - *

Default is "true". Turn this flag off to let the caller receive raw exceptions - * as-is, without any wrapping. - * @see org.springframework.dao.DataAccessException - */ - public void setExceptionConversionEnabled(boolean exceptionConversionEnabled) { - this.exceptionConversionEnabled = exceptionConversionEnabled; - } - - - public Object invoke(MethodInvocation methodInvocation) throws Throwable { - boolean existingTransaction = false; - Session session = SessionFactoryUtils.getSession(getSessionFactory(), true); - if (TransactionSynchronizationManager.hasResource(getSessionFactory())) { - logger.debug("Found thread-bound Session for TopLink interceptor"); - existingTransaction = true; - } - else { - logger.debug("Using new Session for TopLink interceptor"); - TransactionSynchronizationManager.bindResource(getSessionFactory(), new SessionHolder(session)); - } - try { - return methodInvocation.proceed(); - } - catch (TopLinkException ex) { - if (this.exceptionConversionEnabled) { - throw convertTopLinkAccessException(ex); - } - else { - throw ex; - } - } - finally { - if (existingTransaction) { - logger.debug("Not closing pre-bound TopLink Session after interceptor"); - } - else { - TransactionSynchronizationManager.unbindResource(getSessionFactory()); - SessionFactoryUtils.releaseSession(session, getSessionFactory()); - } - } - } - -} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkJdbcException.java b/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkJdbcException.java deleted file mode 100644 index 75e84330df..0000000000 --- a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkJdbcException.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2002-2005 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.toplink; - -import oracle.toplink.exceptions.DatabaseException; - -import org.springframework.dao.UncategorizedDataAccessException; - -/** - * TopLink-specific subclass of DataAccessException, for JDBC exceptions - * that TopLink rethrew. - * - * @author Juergen Hoeller - * @see SessionFactoryUtils#convertTopLinkAccessException - * @since 1.2 - */ -public class TopLinkJdbcException extends UncategorizedDataAccessException { - - public TopLinkJdbcException(DatabaseException ex) { - super("JDBC exception on TopLink data access: " + ex.getMessage(), ex.getInternalException()); - } - -} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkOperations.java b/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkOperations.java deleted file mode 100644 index 42cd7a4902..0000000000 --- a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkOperations.java +++ /dev/null @@ -1,703 +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.toplink; - -import java.util.Collection; -import java.util.List; - -import oracle.toplink.expressions.Expression; -import oracle.toplink.queryframework.Call; -import oracle.toplink.queryframework.DatabaseQuery; -import oracle.toplink.sessions.ObjectCopyingPolicy; - -import org.springframework.dao.DataAccessException; - -/** - * Interface that specifies a basic set of TopLink operations, - * implemented by {@link TopLinkTemplate}. Not often used, but a useful - * option to enhance testability, as it can easily be mocked or stubbed. - * - *

Defines TopLinkTemplate's data access methods that - * mirror various TopLink {@link oracle.toplink.sessions.Session} / - * {@link oracle.toplink.sessions.UnitOfWork} methods. Users are - * strongly encouraged to read the TopLink javadocs for details - * on the semantics of those methods. - * - * @author Juergen Hoeller - * @since 1.2 - */ -public interface TopLinkOperations { - - /** - * Execute the action specified by the given action object within a - * TopLink Session. Application exceptions thrown by the action object - * get propagated to the caller (can only be unchecked). TopLink exceptions - * are transformed into appropriate DAO ones. Allows for returning a - * result object, i.e. a domain object or a collection of domain objects. - *

Note: Callback code is not supposed to handle transactions itself! - * Use an appropriate transaction manager like TopLinkTransactionManager. - * @param action callback object that specifies the TopLink action - * @return a result object returned by the action, or null - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see TopLinkTransactionManager - * @see org.springframework.dao - * @see org.springframework.transaction - * @see oracle.toplink.sessions.Session - */ - Object execute(TopLinkCallback action) throws DataAccessException; - - /** - * Execute the specified action assuming that the result object is a - * Collection. This is a convenience method for executing TopLink queries - * within an action. - * @param action callback object that specifies the TopLink action - * @return a Collection result returned by the action, or null - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - */ - List executeFind(TopLinkCallback action) throws DataAccessException; - - - //------------------------------------------------------------------------- - // Convenience methods for executing generic queries - //------------------------------------------------------------------------- - - /** - * Execute a given named query with the given arguments. - *

Retrieves read-write objects from the TopLink UnitOfWork in case of a - * non-read-only transaction, and read-only objects else. - * @param entityClass the entity class that has the named query descriptor - * @param queryName the name of the query - * @return the result object or list of result objects for the query - * (can be cast to the entity class or Collection/List, respectively) - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.Session#executeQuery(String, Class) - */ - Object executeNamedQuery(Class entityClass, String queryName) throws DataAccessException; - - /** - * Execute a given named query with the given arguments. - * @param entityClass the entity class that has the named query descriptor - * @param queryName the name of the query - * @param enforceReadOnly whether to always retrieve read-only objects from - * the plain TopLink Session (else, read-write objects will be retrieved - * from the TopLink UnitOfWork in case of a non-read-only transaction) - * @return the result object or list of result objects for the query - * (can be cast to the entity class or Collection/List, respectively) - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.Session#executeQuery(String, Class) - */ - Object executeNamedQuery(Class entityClass, String queryName, boolean enforceReadOnly) - throws DataAccessException; - - /** - * Execute a given named query with the given arguments. - *

Retrieves read-write objects from the TopLink UnitOfWork in case of a - * non-read-only transaction, and read-only objects else. - * @param entityClass the entity class that has the named query descriptor - * @param queryName the name of the query - * @param args the arguments for the query (can be null) - * @return the result object or list of result objects for the query - * (can be cast to the entity class or Collection/List, respectively) - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.Session#executeQuery(String, Class, java.util.Vector) - */ - Object executeNamedQuery(Class entityClass, String queryName, Object[] args) throws DataAccessException; - - /** - * Execute a given named query with the given arguments. - * @param entityClass the entity class that has the named query descriptor - * @param queryName the name of the query - * @param args the arguments for the query (can be null) - * @param enforceReadOnly whether to always retrieve read-only objects from - * the plain TopLink Session (else, read-write objects will be retrieved - * from the TopLink UnitOfWork in case of a non-read-only transaction) - * @return the result object or list of result objects for the query - * (can be cast to the entity class or Collection/List, respectively) - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.Session#executeQuery(String, Class, java.util.Vector) - */ - Object executeNamedQuery(Class entityClass, String queryName, Object[] args, boolean enforceReadOnly) - throws DataAccessException; - - /** - * Execute the given query object with the given arguments. - *

Retrieves read-write objects from the TopLink UnitOfWork in case of a - * non-read-only transaction, and read-only objects else. - * @param query the query object to execute (for example, - * a ReadObjectQuery or ReadAllQuery instance) - * @return the result object or list of result objects for the query - * (can be cast to the entity class or Collection/List, respectively) - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.Session#executeQuery(oracle.toplink.queryframework.DatabaseQuery) - */ - Object executeQuery(DatabaseQuery query) throws DataAccessException; - - /** - * Execute the given query object with the given arguments. - * @param query the query object to execute (for example, - * a ReadObjectQuery or ReadAllQuery instance) - * @param enforceReadOnly whether to always retrieve read-only objects from - * the plain TopLink Session (else, read-write objects will be retrieved - * from the TopLink UnitOfWork in case of a non-read-only transaction) - * @return the result object or list of result objects for the query - * (can be cast to the entity class or Collection/List, respectively) - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.Session#executeQuery(oracle.toplink.queryframework.DatabaseQuery) - */ - Object executeQuery(DatabaseQuery query, boolean enforceReadOnly) throws DataAccessException; - - /** - * Execute the given query object with the given arguments. - *

Retrieves read-write objects from the TopLink UnitOfWork in case of a - * non-read-only transaction, and read-only objects else. - * @param query the query object to execute (for example, - * a ReadObjectQuery or ReadAllQuery instance) - * @param args the arguments for the query (can be null) - * @return the result object or list of result objects for the query - * (can be cast to the entity class or Collection/List, respectively) - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.Session#executeQuery(oracle.toplink.queryframework.DatabaseQuery, java.util.Vector) - */ - Object executeQuery(DatabaseQuery query, Object[] args) throws DataAccessException; - - /** - * Execute the given query object with the given arguments. - * @param query the query object to execute (for example, - * a ReadObjectQuery or ReadAllQuery instance) - * @param args the arguments for the query (can be null) - * @param enforceReadOnly whether to always retrieve read-only objects from - * the plain TopLink Session (else, read-write objects will be retrieved - * from the TopLink UnitOfWork in case of a non-read-only transaction) - * @return the result object or list of result objects for the query - * (can be cast to the entity class or Collection/List, respectively) - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.Session#executeQuery(oracle.toplink.queryframework.DatabaseQuery, java.util.Vector) - */ - Object executeQuery(DatabaseQuery query, Object[] args, boolean enforceReadOnly) - throws DataAccessException; - - - //------------------------------------------------------------------------- - // Convenience methods for reading a specific set of objects - //------------------------------------------------------------------------- - - /** - * Read all entity instances of the given class. - *

Retrieves read-write objects from the TopLink UnitOfWork in case of a - * non-read-only transaction, and read-only objects else. - * @param entityClass the entity class - * @return the list of entity instances - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.Session#readAllObjects(Class) - */ - List readAll(Class entityClass) throws DataAccessException; - - /** - * Read all entity instances of the given class. - * @param entityClass the entity class - * @param enforceReadOnly whether to always retrieve read-only objects from - * the plain TopLink Session (else, read-write objects will be retrieved - * from the TopLink UnitOfWork in case of a non-read-only transaction) - * @return the list of entity instances - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.Session#readAllObjects(Class) - */ - List readAll(Class entityClass, boolean enforceReadOnly) throws DataAccessException; - - /** - * Read all entity instances of the given class that match the given expression. - *

Retrieves read-write objects from the TopLink UnitOfWork in case of a - * non-read-only transaction, and read-only objects else. - * @param entityClass the entity class - * @param expression the TopLink expression to match, - * usually built through the TopLink ExpressionBuilder - * @return the list of matching entity instances - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.Session#readAllObjects(Class, oracle.toplink.expressions.Expression) - * @see oracle.toplink.expressions.ExpressionBuilder - */ - List readAll(Class entityClass, Expression expression) throws DataAccessException; - - /** - * Read all entity instances of the given class that match the given expression. - * @param entityClass the entity class - * @param expression the TopLink expression to match, - * usually built through the TopLink ExpressionBuilder - * @param enforceReadOnly whether to always retrieve read-only objects from - * the plain TopLink Session (else, read-write objects will be retrieved - * from the TopLink UnitOfWork in case of a non-read-only transaction) - * @return the list of matching entity instances - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.Session#readAllObjects(Class, oracle.toplink.expressions.Expression) - * @see oracle.toplink.expressions.ExpressionBuilder - */ - List readAll(Class entityClass, Expression expression, boolean enforceReadOnly) - throws DataAccessException; - - /** - * Read all entity instances of the given class, as returned by the given call. - *

Retrieves read-write objects from the TopLink UnitOfWork in case of a - * non-read-only transaction, and read-only objects else. - * @param entityClass the entity class - * @param call the TopLink Call object to apply (either a SQLCall or an EJBQLCall) - * @return the list of matching entity instances - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.Session#readAllObjects(Class, oracle.toplink.queryframework.Call) - * @see oracle.toplink.queryframework.SQLCall - * @see oracle.toplink.queryframework.EJBQLCall - */ - List readAll(Class entityClass, Call call) throws DataAccessException; - - /** - * Read all entity instances of the given class, as returned by the given call. - * @param entityClass the entity class - * @param call the TopLink Call object to apply (either a SQLCall or an EJBQLCall) - * @param enforceReadOnly whether to always retrieve read-only objects from - * the plain TopLink Session (else, read-write objects will be retrieved - * from the TopLink UnitOfWork in case of a non-read-only transaction) - * @return the list of matching entity instances - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.Session#readAllObjects(Class, oracle.toplink.expressions.Expression) - * @see oracle.toplink.queryframework.SQLCall - * @see oracle.toplink.queryframework.EJBQLCall - */ - List readAll(Class entityClass, Call call, boolean enforceReadOnly) throws DataAccessException; - - /** - * Read an entity instance of the given class that matches the given expression. - *

Retrieves read-write objects from the TopLink UnitOfWork in case of a - * non-read-only transaction, and read-only objects else. - * @param entityClass the entity class - * @param expression the TopLink expression to match, - * usually built through the TopLink ExpressionBuilder - * @return the matching entity instance, or null if none found - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.Session#readAllObjects(Class, oracle.toplink.expressions.Expression) - * @see oracle.toplink.expressions.ExpressionBuilder - */ - Object read(Class entityClass, Expression expression) throws DataAccessException; - - /** - * Read an entity instance of the given class that matches the given expression. - * @param entityClass the entity class - * @param expression the TopLink expression to match, - * usually built through the TopLink ExpressionBuilder - * @param enforceReadOnly whether to always retrieve read-only objects from - * the plain TopLink Session (else, read-write objects will be retrieved - * from the TopLink UnitOfWork in case of a non-read-only transaction) - * @return a matching entity instance, or null if none found - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.Session#readAllObjects(Class, oracle.toplink.expressions.Expression) - * @see oracle.toplink.expressions.ExpressionBuilder - */ - Object read(Class entityClass, Expression expression, boolean enforceReadOnly) - throws DataAccessException; - - /** - * Read an entity instance of the given class, as returned by the given call. - *

Retrieves read-write objects from the TopLink UnitOfWork in case of a - * non-read-only transaction, and read-only objects else. - * @param entityClass the entity class - * @param call the TopLink Call object to apply (either a SQLCall or an EJBQLCall) - * @return a matching entity instance, or null if none found - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.Session#readAllObjects(Class, oracle.toplink.queryframework.Call) - * @see oracle.toplink.queryframework.SQLCall - * @see oracle.toplink.queryframework.EJBQLCall - */ - Object read(Class entityClass, Call call) throws DataAccessException; - - /** - * Read an entity instance of the given class, as returned by the given call. - * @param entityClass the entity class - * @param call the TopLink Call object to apply (either a SQLCall or an EJBQLCall) - * @param enforceReadOnly whether to always retrieve read-only objects from - * the plain TopLink Session (else, read-write objects will be retrieved - * from the TopLink UnitOfWork in case of a non-read-only transaction) - * @return a matching entity instance, or null if none found - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.Session#readAllObjects(Class, oracle.toplink.expressions.Expression) - * @see oracle.toplink.queryframework.SQLCall - * @see oracle.toplink.queryframework.EJBQLCall - */ - Object read(Class entityClass, Call call, boolean enforceReadOnly) - throws DataAccessException; - - - //------------------------------------------------------------------------- - // Convenience methods for reading an individual object by id - //------------------------------------------------------------------------- - - /** - * Read the entity instance of the given class with the given id, - * throwing an exception if not found. - *

Retrieves read-write objects from the TopLink UnitOfWork in case of a - * non-read-only transaction, and read-only objects else. - * @param entityClass the entity class - * @param id the id of the desired object - * @return the entity instance - * @throws org.springframework.orm.ObjectRetrievalFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.queryframework.ReadObjectQuery#setSelectionKey(java.util.Vector) - */ - Object readById(Class entityClass, Object id) throws DataAccessException; - - /** - * Read the entity instance of the given class with the given id, - * throwing an exception if not found. - * @param entityClass the entity class - * @param id the id of the desired object - * @return the entity instance - * @param enforceReadOnly whether to always retrieve read-only objects from - * the plain TopLink Session (else, read-write objects will be retrieved - * from the TopLink UnitOfWork in case of a non-read-only transaction) - * @throws org.springframework.orm.ObjectRetrievalFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.queryframework.ReadObjectQuery#setSelectionKey(java.util.Vector) - */ - Object readById(Class entityClass, Object id, boolean enforceReadOnly) throws DataAccessException; - - /** - * Read the entity instance of the given class with the given composite id, - * throwing an exception if not found. - *

Retrieves read-write objects from the TopLink UnitOfWork in case of a - * non-read-only transaction, and read-only objects else. - * @param entityClass the entity class - * @param keys the composite id elements of the desired object - * @return the entity instance - * @throws org.springframework.orm.ObjectRetrievalFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.queryframework.ReadObjectQuery#setSelectionKey(java.util.Vector) - */ - Object readById(Class entityClass, Object[] keys) throws DataAccessException; - - /** - * Read the entity instance of the given class with the given composite id, - * throwing an exception if not found. - * @param entityClass the entity class - * @param keys the composite id elements of the desired object - * @param enforceReadOnly whether to always retrieve read-only objects from - * the plain TopLink Session (else, read-write objects will be retrieved - * from the TopLink UnitOfWork in case of a non-read-only transaction) - * @return the entity instance - * @throws org.springframework.orm.ObjectRetrievalFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.queryframework.ReadObjectQuery#setSelectionKey(java.util.Vector) - */ - Object readById(Class entityClass, Object[] keys, boolean enforceReadOnly) throws DataAccessException; - - /** - * Read the entity instance of the given class with the given id, - * throwing an exception if not found. A detached copy of the entity object - * will be returned, allowing for modifications outside the current transaction, - * with the changes to be merged into a later transaction. - *

Retrieves read-write objects from the TopLink UnitOfWork in case of a - * non-read-only transaction, and read-only objects else. - * @param entityClass the entity class - * @param id the id of the desired object - * @return a copy of the entity instance - * @throws org.springframework.orm.ObjectRetrievalFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.queryframework.ReadObjectQuery#setSelectionKey(java.util.Vector) - * @see oracle.toplink.sessions.Session#copyObject(Object) - */ - Object readAndCopy(Class entityClass, Object id) throws DataAccessException; - - /** - * Read the entity instance of the given class with the given id, - * throwing an exception if not found. A detached copy of the entity object - * will be returned, allowing for modifications outside the current transaction, - * with the changes to be merged into a later transaction. - * @param entityClass the entity class - * @param id the id of the desired object - * @param enforceReadOnly whether to always retrieve read-only objects from - * the plain TopLink Session (else, read-write objects will be retrieved - * from the TopLink UnitOfWork in case of a non-read-only transaction) - * @return a copy of the entity instance - * @throws org.springframework.orm.ObjectRetrievalFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.queryframework.ReadObjectQuery#setSelectionKey(java.util.Vector) - * @see oracle.toplink.sessions.Session#copyObject(Object) - */ - Object readAndCopy(Class entityClass, Object id, boolean enforceReadOnly) throws DataAccessException; - - /** - * Read the entity instance of the given class with the given composite id, - * throwing an exception if not found. A detached copy of the entity object - * will be returned, allowing for modifications outside the current transaction, - * with the changes to be merged into a later transaction. - *

Retrieves read-write objects from the TopLink UnitOfWork in case of a - * non-read-only transaction, and read-only objects else. - * @param entityClass the entity class - * @param keys the composite id elements of the desired object - * @return a copy of the entity instance - * @throws org.springframework.orm.ObjectRetrievalFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.queryframework.ReadObjectQuery#setSelectionKey(java.util.Vector) - * @see oracle.toplink.sessions.Session#copyObject(Object) - */ - Object readAndCopy(Class entityClass, Object[] keys) throws DataAccessException; - - /** - * Read the entity instance of the given class with the given composite id, - * throwing an exception if not found. A detached copy of the entity object - * will be returned, allowing for modifications outside the current transaction, - * with the changes to be merged into a later transaction. - * @param entityClass the entity class - * @param keys the composite id elements of the desired object - * @param enforceReadOnly whether to always retrieve read-only objects from - * the plain TopLink Session (else, read-write objects will be retrieved - * from the TopLink UnitOfWork in case of a non-read-only transaction) - * @return a copy of the entity instance - * @throws org.springframework.orm.ObjectRetrievalFailureException if not found - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.queryframework.ReadObjectQuery#setSelectionKey(java.util.Vector) - * @see oracle.toplink.sessions.Session#copyObject(Object) - */ - Object readAndCopy(Class entityClass, Object[] keys, boolean enforceReadOnly) throws DataAccessException; - - - //------------------------------------------------------------------------- - // Convenience methods for copying and refreshing objects - //------------------------------------------------------------------------- - - /** - * Create a detached copy of the given entity object, - * using TopLink's default ObjectCopyingPolicy. - * @param entity the entity object to copy - * @return the copy of the entity object - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.Session#copyObject(Object) - */ - Object copy(Object entity) throws DataAccessException; - - /** - * Create a detached copy of the given entity object. - * @param entity the entity object to copy - * @param copyingPolicy the TopLink ObjectCopyingPolicy to apply - * @return the copy of the entity object - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.Session#copyObject(Object, oracle.toplink.sessions.ObjectCopyingPolicy) - */ - Object copy(Object entity, ObjectCopyingPolicy copyingPolicy) throws DataAccessException; - - /** - * Create detached copies of all given entity objects, - * using TopLink's default ObjectCopyingPolicy. - * @param entities the entity objects to copy - * @return the copies of the entity objects - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.Session#copyObject(Object) - */ - List copyAll(Collection entities) throws DataAccessException; - - /** - * Create detached copies of all given entity objects. - * @param entities the entity objects to copy - * @param copyingPolicy the TopLink ObjectCopyingPolicy to apply - * @return the copies of the entity objects - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.Session#copyObject(Object) - */ - List copyAll(Collection entities, ObjectCopyingPolicy copyingPolicy) throws DataAccessException; - - /** - * Refresh the given entity object, returning the refreshed object. - *

The returned object will only be different from the passed-in object - * if the passed-in object is not the currently registered version of - * the corresponding entity. - *

Retrieves read-write objects from the TopLink UnitOfWork in case of a - * non-read-only transaction, and read-only objects else. - * @param entity the entity object to refresh - * @return the refreshed version of the entity object - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.Session#refreshObject(Object) - */ - Object refresh(Object entity) throws DataAccessException; - - /** - * Refresh the given entity object, returning the refreshed object. - *

The returned object will only be different from the passed-in object - * if the passed-in object is not the currently registered version of - * the corresponding entity. - *

Retrieves read-write objects from the TopLink UnitOfWork in case of a - * non-read-only transaction, and read-only objects else. - * @param entity the entity object to refresh - * @param enforceReadOnly whether to always retrieve read-only objects from - * the plain TopLink Session (else, read-write objects will be retrieved - * from the TopLink UnitOfWork in case of a non-read-only transaction) - * @return the refreshed version of the entity object - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.Session#refreshObject(Object) - */ - Object refresh(Object entity, boolean enforceReadOnly) throws DataAccessException; - - /** - * Refresh the given entity objects, returning the corresponding refreshed objects. - *

A returned object will only be different from the corresponding passed-in - * object if the passed-in object is not the currently registered version of - * the corresponding entity. - *

Retrieves read-write objects from the TopLink UnitOfWork in case of a - * non-read-only transaction, and read-only objects else. - * @param entities the entity objects to refresh - * @return the refreshed versions of the entity objects - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.Session#refreshObject(Object) - */ - List refreshAll(Collection entities) throws DataAccessException; - - /** - * Refresh the given entity objects, returning the corresponding refreshed objects. - *

A returned object will only be different from the corresponding passed-in - * object if the passed-in object is not the currently registered version of - * the corresponding entity. - * @param entities the entity objects to refresh - * @param enforceReadOnly whether to always retrieve read-only objects from - * the plain TopLink Session (else, read-write objects will be retrieved - * from the TopLink UnitOfWork in case of a non-read-only transaction) - * @return the refreshed versions of the entity objects - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.Session#refreshObject(Object) - */ - List refreshAll(Collection entities, boolean enforceReadOnly) throws DataAccessException; - - - //------------------------------------------------------------------------- - // Convenience methods for persisting and deleting objects - //------------------------------------------------------------------------- - - /** - * Register the given (new or existing) entity with the current UnitOfWork. - *

The entity will be checked for existence, according to TopLink's - * configured existence checking policy. To avoid the (potentially costly) - * existence check, consider using the specific registerNew - * or registerExisting method. - * Do not edit the passed-in object any further afterwards. - * @param entity the entity to register - * @return the registered clone of the original object, - * which needs to be used for further editing - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.UnitOfWork#registerObject(Object) - * @see #registerNew(Object) - * @see #registerExisting(Object) - */ - Object register(Object entity); - - /** - * Register all given entities with the current UnitOfWork. - * Do not edit the passed-in objects any further afterwards. - * @param entities the entities to register - * @return the registered clones of the original objects, - * which need to be used for further editing - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.UnitOfWork#registerAllObjects(java.util.Collection) - */ - List registerAll(Collection entities); - - /** - * Register the given new entity with the current UnitOfWork. - * The passed-in object can be edited further afterwards. - * @param entity the new entity to register - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.UnitOfWork#registerNewObject(Object) - */ - void registerNew(Object entity); - - /** - * Register the given existing entity with the current UnitOfWork. - * Do not edit the passed-in object any further afterwards. - * @param entity the existing entity to register - * @return the registered clone of the original object, - * which needs to be used for further editing - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.UnitOfWork#registerExistingObject(Object) - */ - Object registerExisting(Object entity); - - /** - * Reassociate the given entity copy with the current UnitOfWork, - * using simple merging. - *

The given object will not be reassociated itself: instead, the state - * will be copied onto the persistent object with the same identifier. - * In case of a new entity, merge will copy to a registered object as well, - * but will also update the identifier of the passed-in object. - * @param entity the updated copy to merge - * @return the updated, registered persistent instance - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.UnitOfWork#mergeClone(Object) - */ - Object merge(Object entity) throws DataAccessException; - - /** - * Reassociate the given entity copy with the current UnitOfWork, - * using deep merging of all contained entities. - *

The given object will not be reassociated itself: instead, the state - * will be copied onto the persistent object with the same identifier. - * In case of a new entity, merge will register a copy as well, - * but will also update the identifier of the passed-in object. - * @param entity the updated copy to merge - * @return the updated, registered persistent instance - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.UnitOfWork#deepMergeClone(Object) - */ - Object deepMerge(Object entity) throws DataAccessException; - - /** - * Reassociate the given entity copy with the current UnitOfWork, - * using shallow merging of the entity instance. - *

The given object will not be reassociated itself: instead, the state - * will be copied onto the persistent object with the same identifier. - * In case of a new entity, merge will register a copy as well, - * but will also update the identifier of the passed-in object. - * @param entity the updated copy to merge - * @return the updated, registered persistent instance - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.UnitOfWork#shallowMergeClone(Object) - */ - Object shallowMerge(Object entity) throws DataAccessException; - - /** - * Reassociate the given entity copy with the current UnitOfWork, - * using merging with all references from this clone. - *

The given object will not be reassociated itself: instead, the state - * will be copied onto the persistent object with the same identifier. - * In case of a new entity, merge will register a copy as well, - * but will also update the identifier of the passed-in object. - * @param entity the updated copy to merge - * @return the updated, registered persistent instance - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.UnitOfWork#mergeCloneWithReferences(Object) - */ - Object mergeWithReferences(Object entity) throws DataAccessException; - - /** - * Delete the given entity. - * @param entity the entity to delete - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.UnitOfWork#deleteObject(Object) - */ - void delete(Object entity) throws DataAccessException; - - /** - * Delete all given entities. - * @param entities the entities to delete - * @throws org.springframework.dao.DataAccessException in case of TopLink errors - * @see oracle.toplink.sessions.UnitOfWork#deleteAllObjects(java.util.Collection) - */ - void deleteAll(Collection entities) throws DataAccessException; - -} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkOptimisticLockingFailureException.java b/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkOptimisticLockingFailureException.java deleted file mode 100644 index 84f1e2eac2..0000000000 --- a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkOptimisticLockingFailureException.java +++ /dev/null @@ -1,36 +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.toplink; - -import oracle.toplink.exceptions.OptimisticLockException; - -import org.springframework.orm.ObjectOptimisticLockingFailureException; - -/** - * TopLink-specific subclass of ObjectOptimisticLockingFailureException. - * Converts TopLink's OptimisticLockException. - * - * @author Juergen Hoeller - * @since 1.2 - */ -public class TopLinkOptimisticLockingFailureException extends ObjectOptimisticLockingFailureException { - - public TopLinkOptimisticLockingFailureException(OptimisticLockException ex) { - super(ex.getObject() != null ? ex.getObject().getClass() : null, null, ex.getMessage(), ex); - } - -} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkQueryException.java b/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkQueryException.java deleted file mode 100644 index 90f264d2c2..0000000000 --- a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkQueryException.java +++ /dev/null @@ -1,36 +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.toplink; - -import oracle.toplink.exceptions.QueryException; - -import org.springframework.dao.InvalidDataAccessResourceUsageException; - -/** - * TopLink-specific subclass of InvalidDataAccessResourceUsageException, - * thrown on invalid TopLink query syntax or behavior. - * - * @author Juergen Hoeller - * @since 1.2 - */ -public class TopLinkQueryException extends InvalidDataAccessResourceUsageException { - - public TopLinkQueryException(QueryException ex) { - super(ex.getMessage(), ex); - } - -} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkSystemException.java b/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkSystemException.java deleted file mode 100644 index 6a9846ba6b..0000000000 --- a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkSystemException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2002-2005 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.toplink; - -import oracle.toplink.exceptions.TopLinkException; - -import org.springframework.dao.UncategorizedDataAccessException; - -/** - * TopLink-specific subclass of UncategorizedDataAccessException, - * for TopLink system errors that do not match any concrete - * org.springframework.dao exceptions. - * - * @author Juergen Hoeller - * @since 1.2 - * @see SessionFactoryUtils#convertTopLinkAccessException - */ -public class TopLinkSystemException extends UncategorizedDataAccessException { - - public TopLinkSystemException(TopLinkException ex) { - super(ex.getMessage(), ex); - } - -} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkTemplate.java b/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkTemplate.java deleted file mode 100644 index f1b34dc4e5..0000000000 --- a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkTemplate.java +++ /dev/null @@ -1,534 +0,0 @@ -/* - * Copyright 2002-2007 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.toplink; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Vector; - -import oracle.toplink.exceptions.TopLinkException; -import oracle.toplink.expressions.Expression; -import oracle.toplink.queryframework.Call; -import oracle.toplink.queryframework.DatabaseQuery; -import oracle.toplink.queryframework.ReadObjectQuery; -import oracle.toplink.sessions.ObjectCopyingPolicy; -import oracle.toplink.sessions.Session; -import oracle.toplink.sessions.UnitOfWork; - -import org.springframework.dao.DataAccessException; -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.orm.ObjectRetrievalFailureException; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * Helper class that simplifies TopLink data access code, and converts - * TopLinkExceptions into unchecked DataAccessExceptions, following the - * org.springframework.dao exception hierarchy. - * - *

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

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

This class can be considered as direct alternative to working with the raw - * TopLink Session API (through SessionFactoryUtils.getSession()). - * The major advantage is its automatic conversion to DataAccessExceptions, the - * major disadvantage that no checked application exceptions can get thrown from - * within data access code. Corresponding checks and the actual throwing of such - * exceptions can often be deferred to after callback execution, though. - * - *

{@link LocalSessionFactoryBean} is the preferred way of obtaining a reference - * to a specific TopLink SessionFactory. It will usually be configured to - * create ClientSessions for a ServerSession held by it, allowing for seamless - * multi-threaded execution. The Spring application context will manage its lifecycle, - * initializing and shutting down the factory as part of the application. - * - *

Thanks to Slavik Markovich for implementing the initial TopLink support prototype! - * - * @author Juergen Hoeller - * @author James Clark - * @since 1.2 - * @see #setSessionFactory - * @see TopLinkCallback - * @see oracle.toplink.sessions.Session - * @see TopLinkInterceptor - * @see LocalSessionFactoryBean - * @see TopLinkTransactionManager - * @see org.springframework.transaction.jta.JtaTransactionManager - */ -public class TopLinkTemplate extends TopLinkAccessor implements TopLinkOperations { - - private boolean allowCreate = true; - - - /** - * Create a new TopLinkTemplate instance. - */ - public TopLinkTemplate() { - } - - /** - * Create a new TopLinkTemplate instance. - */ - public TopLinkTemplate(SessionFactory sessionFactory) { - setSessionFactory(sessionFactory); - afterPropertiesSet(); - } - - /** - * Create a new TopLinkTemplate instance. - * @param allowCreate if a new Session should be created if no thread-bound found - */ - public TopLinkTemplate(SessionFactory sessionFactory, boolean allowCreate) { - setSessionFactory(sessionFactory); - setAllowCreate(allowCreate); - afterPropertiesSet(); - } - - /** - * Set if a new Session should be created when no transactional Session - * can be found for the current thread. - *

TopLinkTemplate is aware of a corresponding Session bound to the - * current thread, for example when using TopLinkTransactionManager. - * If allowCreate is true, a new non-transactional Session will be created - * if none found, which needs to be closed at the end of the operation. - * If false, an IllegalStateException will get thrown in this case. - * @see SessionFactoryUtils#getSession(SessionFactory, boolean) - */ - public void setAllowCreate(boolean allowCreate) { - this.allowCreate = allowCreate; - } - - /** - * Return if a new Session should be created if no thread-bound found. - */ - public boolean isAllowCreate() { - return this.allowCreate; - } - - - public Object execute(TopLinkCallback action) throws DataAccessException { - Assert.notNull(action, "Callback object must not be null"); - - Session session = SessionFactoryUtils.getSession(getSessionFactory(), this.allowCreate); - try { - return action.doInTopLink(session); - } - catch (TopLinkException ex) { - throw convertTopLinkAccessException(ex); - } - catch (RuntimeException ex) { - // callback code threw application exception - throw ex; - } - finally { - SessionFactoryUtils.releaseSession(session, getSessionFactory()); - } - } - - public List executeFind(TopLinkCallback action) throws DataAccessException { - Object result = execute(action); - if (result != null && !(result instanceof List)) { - throw new InvalidDataAccessApiUsageException( - "Result object returned from TopLinkCallback isn't a List: [" + result + "]"); - } - return (List) result; - } - - - //------------------------------------------------------------------------- - // Convenience methods for executing generic queries - //------------------------------------------------------------------------- - - public Object executeNamedQuery(Class entityClass, String queryName) throws DataAccessException { - return executeNamedQuery(entityClass, queryName, null, false); - } - - public Object executeNamedQuery(Class entityClass, String queryName, boolean enforceReadOnly) - throws DataAccessException { - - return executeNamedQuery(entityClass, queryName, null, enforceReadOnly); - } - - public Object executeNamedQuery(Class entityClass, String queryName, Object[] args) - throws DataAccessException { - - return executeNamedQuery(entityClass, queryName, args, false); - } - - public Object executeNamedQuery( - final Class entityClass, final String queryName, final Object[] args, final boolean enforceReadOnly) - throws DataAccessException { - - return execute(new SessionReadCallback(enforceReadOnly) { - @Override - protected Object readFromSession(Session session) throws TopLinkException { - if (args != null) { - return session.executeQuery(queryName, entityClass, new Vector(Arrays.asList(args))); - } - else { - return session.executeQuery(queryName, entityClass, new Vector()); - } - } - }); - } - - public Object executeQuery(DatabaseQuery query) throws DataAccessException { - return executeQuery(query, null, false); - } - - public Object executeQuery(DatabaseQuery query, boolean enforceReadOnly) throws DataAccessException { - return executeQuery(query, null, enforceReadOnly); - } - - public Object executeQuery(DatabaseQuery query, Object[] args) throws DataAccessException { - return executeQuery(query, args, false); - } - - public Object executeQuery(final DatabaseQuery query, final Object[] args, final boolean enforceReadOnly) - throws DataAccessException { - - return execute(new SessionReadCallback(enforceReadOnly) { - @Override - protected Object readFromSession(Session session) throws TopLinkException { - if (args != null) { - return session.executeQuery(query, new Vector(Arrays.asList(args))); - } - else { - return session.executeQuery(query); - } - } - }); - } - - - //------------------------------------------------------------------------- - // Convenience methods for reading a specific set of objects - //------------------------------------------------------------------------- - - public List readAll(Class entityClass) throws DataAccessException { - return readAll(entityClass, false); - } - - public List readAll(final Class entityClass, final boolean enforceReadOnly) throws DataAccessException { - return executeFind(new SessionReadCallback(enforceReadOnly) { - @Override - protected Object readFromSession(Session session) throws TopLinkException { - return session.readAllObjects(entityClass); - } - }); - } - - public List readAll(Class entityClass, Expression expression) throws DataAccessException { - return readAll(entityClass, expression, false); - } - - public List readAll(final Class entityClass, final Expression expression, final boolean enforceReadOnly) - throws DataAccessException { - - return executeFind(new SessionReadCallback(enforceReadOnly) { - @Override - protected Object readFromSession(Session session) throws TopLinkException { - return session.readAllObjects(entityClass, expression); - } - }); - } - - public List readAll(Class entityClass, Call call) throws DataAccessException { - return readAll(entityClass, call, false); - } - - public List readAll(final Class entityClass, final Call call, final boolean enforceReadOnly) - throws DataAccessException { - - return executeFind(new SessionReadCallback(enforceReadOnly) { - @Override - protected Object readFromSession(Session session) throws TopLinkException { - return session.readAllObjects(entityClass, call); - } - }); - } - - public Object read(Class entityClass, Expression expression) throws DataAccessException { - return read(entityClass, expression, false); - } - - public Object read(final Class entityClass, final Expression expression, final boolean enforceReadOnly) - throws DataAccessException { - - return execute(new SessionReadCallback(enforceReadOnly) { - @Override - protected Object readFromSession(Session session) throws TopLinkException { - return session.readObject(entityClass, expression); - } - }); - } - - public Object read(Class entityClass, Call call) throws DataAccessException { - return read(entityClass, call, false); - } - - public Object read(final Class entityClass, final Call call, final boolean enforceReadOnly) - throws DataAccessException { - - return execute(new SessionReadCallback(enforceReadOnly) { - @Override - protected Object readFromSession(Session session) throws TopLinkException { - return session.readObject(entityClass, call); - } - }); - } - - - //------------------------------------------------------------------------- - // Convenience methods for reading an individual object by id - //------------------------------------------------------------------------- - - public Object readById(Class entityClass, Object id) throws DataAccessException { - return readById(entityClass, id, false); - } - - public Object readById(Class entityClass, Object id, boolean enforceReadOnly) throws DataAccessException { - return readById(entityClass, new Object[] {id}, enforceReadOnly); - } - - public Object readById(Class entityClass, Object[] keys) throws DataAccessException { - return readById(entityClass, keys, false); - } - - public Object readById(final Class entityClass, final Object[] keys, final boolean enforceReadOnly) - throws DataAccessException { - - Assert.isTrue(keys != null && keys.length > 0, "Non-empty keys or id is required"); - - ReadObjectQuery query = new ReadObjectQuery(entityClass); - query.setSelectionKey(new Vector(Arrays.asList(keys))); - Object result = executeQuery(query, enforceReadOnly); - - if (result == null) { - Object identifier = (keys.length == 1 ? keys[0] : StringUtils.arrayToCommaDelimitedString(keys)); - throw new ObjectRetrievalFailureException(entityClass, identifier); - } - return result; - } - - public Object readAndCopy(Class entityClass, Object id) throws DataAccessException { - return readAndCopy(entityClass, id, false); - } - - public Object readAndCopy(Class entityClass, Object id, boolean enforceReadOnly) - throws DataAccessException { - - Object entity = readById(entityClass, id, enforceReadOnly); - return copy(entity); - } - - public Object readAndCopy(Class entityClass, Object[] keys) throws DataAccessException { - return readAndCopy(entityClass, keys, false); - } - - public Object readAndCopy(Class entityClass, Object[] keys, boolean enforceReadOnly) - throws DataAccessException { - - Object entity = readById(entityClass, keys, enforceReadOnly); - return copy(entity); - } - - - //------------------------------------------------------------------------- - // Convenience methods for copying and refreshing objects - //------------------------------------------------------------------------- - - public Object copy(Object entity) throws DataAccessException { - ObjectCopyingPolicy copyingPolicy = new ObjectCopyingPolicy(); - copyingPolicy.cascadeAllParts(); - copyingPolicy.setShouldResetPrimaryKey(false); - return copy(entity, copyingPolicy); - } - - public Object copy(final Object entity, final ObjectCopyingPolicy copyingPolicy) - throws DataAccessException { - - return execute(new TopLinkCallback() { - public Object doInTopLink(Session session) throws TopLinkException { - return session.copyObject(entity, copyingPolicy); - } - }); - } - - public List copyAll(Collection entities) throws DataAccessException { - ObjectCopyingPolicy copyingPolicy = new ObjectCopyingPolicy(); - copyingPolicy.cascadeAllParts(); - copyingPolicy.setShouldResetPrimaryKey(false); - return copyAll(entities, copyingPolicy); - } - - public List copyAll(final Collection entities, final ObjectCopyingPolicy copyingPolicy) - throws DataAccessException { - - return (List) execute(new TopLinkCallback() { - public Object doInTopLink(Session session) throws TopLinkException { - List result = new ArrayList(entities.size()); - for (Iterator it = entities.iterator(); it.hasNext();) { - Object entity = it.next(); - result.add(session.copyObject(entity, copyingPolicy)); - } - return result; - } - }); - } - - public Object refresh(Object entity) throws DataAccessException { - return refresh(entity, false); - } - - public Object refresh(final Object entity, final boolean enforceReadOnly) throws DataAccessException { - return execute(new SessionReadCallback(enforceReadOnly) { - @Override - protected Object readFromSession(Session session) throws TopLinkException { - return session.refreshObject(entity); - } - }); - } - - public List refreshAll(Collection entities) throws DataAccessException { - return refreshAll(entities, false); - } - - public List refreshAll(final Collection entities, final boolean enforceReadOnly) throws DataAccessException { - return (List) execute(new SessionReadCallback(enforceReadOnly) { - @Override - protected Object readFromSession(Session session) throws TopLinkException { - List result = new ArrayList(entities.size()); - for (Iterator it = entities.iterator(); it.hasNext();) { - Object entity = it.next(); - result.add(session.refreshObject(entity)); - } - return result; - } - }); - } - - - //------------------------------------------------------------------------- - // Convenience methods for persisting and deleting objects - //------------------------------------------------------------------------- - - public Object register(final Object entity) { - return execute(new UnitOfWorkCallback() { - @Override - protected Object doInUnitOfWork(UnitOfWork unitOfWork) throws TopLinkException { - return unitOfWork.registerObject(entity); - } - }); - } - - public List registerAll(final Collection entities) { - return (List) execute(new UnitOfWorkCallback() { - @Override - protected Object doInUnitOfWork(UnitOfWork unitOfWork) throws TopLinkException { - return unitOfWork.registerAllObjects(entities); - } - }); - } - - public void registerNew(final Object entity) { - execute(new UnitOfWorkCallback() { - @Override - protected Object doInUnitOfWork(UnitOfWork unitOfWork) throws TopLinkException { - return unitOfWork.registerNewObject(entity); - } - }); - } - - public Object registerExisting(final Object entity) { - return execute(new UnitOfWorkCallback() { - @Override - protected Object doInUnitOfWork(UnitOfWork unitOfWork) throws TopLinkException { - return unitOfWork.registerExistingObject(entity); - } - }); - } - - public Object merge(final Object entity) throws DataAccessException { - return execute(new UnitOfWorkCallback() { - @Override - protected Object doInUnitOfWork(UnitOfWork unitOfWork) throws TopLinkException { - return unitOfWork.mergeClone(entity); - } - }); - } - - public Object deepMerge(final Object entity) throws DataAccessException { - return execute(new UnitOfWorkCallback() { - @Override - protected Object doInUnitOfWork(UnitOfWork unitOfWork) throws TopLinkException { - return unitOfWork.deepMergeClone(entity); - } - }); - } - - public Object shallowMerge(final Object entity) throws DataAccessException { - return execute(new UnitOfWorkCallback() { - @Override - protected Object doInUnitOfWork(UnitOfWork unitOfWork) throws TopLinkException { - return unitOfWork.shallowMergeClone(entity); - } - }); - } - - public Object mergeWithReferences(final Object entity) throws DataAccessException { - return execute(new UnitOfWorkCallback() { - @Override - protected Object doInUnitOfWork(UnitOfWork unitOfWork) throws TopLinkException { - return unitOfWork.mergeCloneWithReferences(entity); - } - }); - } - - public void delete(final Object entity) throws DataAccessException { - execute(new UnitOfWorkCallback() { - @Override - protected Object doInUnitOfWork(UnitOfWork unitOfWork) throws TopLinkException { - return unitOfWork.deleteObject(entity); - } - }); - } - - public void deleteAll(final Collection entities) throws DataAccessException { - execute(new UnitOfWorkCallback() { - @Override - protected Object doInUnitOfWork(UnitOfWork unitOfWork) throws TopLinkException { - unitOfWork.deleteAllObjects(entities); - return null; - } - }); - } - -} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkTransactionManager.java b/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkTransactionManager.java deleted file mode 100644 index 8fc663bcc9..0000000000 --- a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/TopLinkTransactionManager.java +++ /dev/null @@ -1,489 +0,0 @@ -/* - * Copyright 2002-2008 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.toplink; - -import java.sql.Connection; -import java.sql.SQLException; - -import javax.sql.DataSource; - -import oracle.toplink.exceptions.DatabaseException; -import oracle.toplink.exceptions.TopLinkException; -import oracle.toplink.internal.databaseaccess.Accessor; -import oracle.toplink.internal.databaseaccess.DatabaseAccessor; -import oracle.toplink.sessions.Session; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.dao.DataAccessException; -import org.springframework.jdbc.datasource.ConnectionHolder; -import org.springframework.jdbc.datasource.JdbcTransactionObjectSupport; -import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy; -import org.springframework.jdbc.support.SQLExceptionTranslator; -import org.springframework.transaction.CannotCreateTransactionException; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.support.AbstractPlatformTransactionManager; -import org.springframework.transaction.support.DefaultTransactionStatus; -import org.springframework.transaction.support.ResourceTransactionManager; -import org.springframework.transaction.support.TransactionSynchronizationManager; - -/** - * {@link org.springframework.transaction.PlatformTransactionManager} implementation - * for a single TopLink {@link SessionFactory}. Binds a TopLink Session from the - * specified factory to the thread, potentially allowing for one thread-bound Session - * per factory. {@link SessionFactoryUtils} and {@link TopLinkTemplate} are aware - * of thread-bound Sessions and participate in such transactions automatically. - * Using either of those or going through Session.getActiveUnitOfWork() is - * required for TopLink access code supporting this transaction handling mechanism. - * - *

This transaction manager is appropriate for applications that use a single - * TopLink SessionFactory for transactional data access. JTA (usually through - * {@link org.springframework.transaction.jta.JtaTransactionManager}) is necessary - * for accessing multiple transactional resources within the same transaction. - * Note that you need to configure TopLink with an appropriate external transaction - * controller in order to make it participate in JTA transactions. - * - *

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

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

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

Thanks to Slavik Markovich for implementing the initial TopLink support prototype! - * - * @author Juergen Hoeller - * @author James Clark - * @since 1.2 - * @see #setSessionFactory - * @see #setDataSource - * @see LocalSessionFactoryBean - * @see SessionFactoryUtils#getSession - * @see SessionFactoryUtils#releaseSession - * @see TopLinkTemplate - * @see oracle.toplink.sessions.Session#getActiveUnitOfWork() - * @see org.springframework.jdbc.datasource.DataSourceUtils#getConnection - * @see org.springframework.jdbc.datasource.DataSourceUtils#applyTransactionTimeout - * @see org.springframework.jdbc.datasource.DataSourceUtils#releaseConnection - * @see org.springframework.jdbc.core.JdbcTemplate - * @see org.springframework.jdbc.datasource.DataSourceTransactionManager - * @see org.springframework.transaction.jta.JtaTransactionManager - */ -public class TopLinkTransactionManager extends AbstractPlatformTransactionManager - implements ResourceTransactionManager, InitializingBean { - - private SessionFactory sessionFactory; - - private DataSource dataSource; - - private boolean lazyDatabaseTransaction = false; - - private SQLExceptionTranslator jdbcExceptionTranslator; - - - /** - * Create a new TopLinkTransactionManager instance. - * A SessionFactory has to be specified to be able to use it. - * @see #setSessionFactory - */ - public TopLinkTransactionManager() { - } - - /** - * Create a new TopLinkTransactionManager instance. - * @param sessionFactory the TopLink SessionFactory to manage transactions for - */ - public TopLinkTransactionManager(SessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; - afterPropertiesSet(); - } - - /** - * Set the the TopLink SessionFactory to manage transactions for. - * This will usually be a ServerSessionFactory. - *

The passed-in SessionFactory will be asked for a plain Session - * in case of a read-only transaction (where no active UnitOfWork is - * supposed to be available), and for a managed Session else (with an - * active UnitOfWork that will be committed by this transaction manager). - * @see ServerSessionFactory - * @see SessionFactory#createSession() - * @see SessionFactory#createManagedClientSession() - */ - public void setSessionFactory(SessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; - } - - /** - * Return the SessionFactory that this instance should manage transactions for. - */ - public SessionFactory getSessionFactory() { - return this.sessionFactory; - } - - /** - * Set the JDBC DataSource that this instance should manage transactions for. - * The DataSource should match the one used by the TopLink SessionFactory: - * for example, you could specify the same JNDI DataSource for both. - *

A transactional JDBC Connection for this DataSource will be provided to - * application code accessing this DataSource directly via DataSourceUtils - * or JdbcTemplate. The Connection will be taken from the TopLink Session. - * This will only happen for transactions that are not marked - * as read-only. TopLink does not support database transactions for pure - * read-only operations on a Session (that is, without a UnitOfWork). - *

Note that you need to use a TopLink Session with a DatabaseAccessor - * to allow for exposing TopLink transactions as JDBC transactions. This is - * the case of all standard TopLink configurations. - *

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

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). - *

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 #setDataSource(javax.sql.DataSource) - * @see oracle.toplink.sessions.UnitOfWork#beginEarlyTransaction() - */ - public void setLazyDatabaseTransaction(boolean lazyDatabaseTransaction) { - this.lazyDatabaseTransaction = lazyDatabaseTransaction; - } - - /** - * Return whether to lazily start a database transaction within a TopLink - * transaction. - */ - public boolean isLazyDatabaseTransaction() { - return this.lazyDatabaseTransaction; - } - - /** - * Set the JDBC exception translator for this transaction manager. - *

Applied to any SQLException root cause of a TopLink DatabaseException - * that is thrown on commit. The default is to rely on TopLink's native - * exception translation. - * @param jdbcExceptionTranslator the exception translator - * @see oracle.toplink.exceptions.DatabaseException - * @see org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator - * @see org.springframework.jdbc.support.SQLStateSQLExceptionTranslator - * @see #setDataSource(javax.sql.DataSource) - */ - public void setJdbcExceptionTranslator(SQLExceptionTranslator jdbcExceptionTranslator) { - this.jdbcExceptionTranslator = jdbcExceptionTranslator; - } - - /** - * Return the JDBC exception translator for this transaction manager, if any. - */ - public SQLExceptionTranslator getJdbcExceptionTranslator() { - return this.jdbcExceptionTranslator; - } - - public void afterPropertiesSet() { - if (getSessionFactory() == null) { - throw new IllegalArgumentException("Property 'sessionFactory' is required"); - } - } - - - public Object getResourceFactory() { - return getSessionFactory(); - } - - @Override - protected Object doGetTransaction() { - TopLinkTransactionObject txObject = new TopLinkTransactionObject(); - SessionHolder sessionHolder = (SessionHolder) - TransactionSynchronizationManager.getResource(this.sessionFactory); - txObject.setSessionHolder(sessionHolder); - return txObject; - } - - @Override - protected boolean isExistingTransaction(Object transaction) { - TopLinkTransactionObject txObject = (TopLinkTransactionObject) transaction; - return (txObject.getSessionHolder() != null); - } - - @Override - protected void doBegin(Object transaction, TransactionDefinition definition) { - Session session = null; - - try { - if (!definition.isReadOnly()) { - logger.debug("Creating managed TopLink Session with active UnitOfWork for read-write transaction"); - session = getSessionFactory().createManagedClientSession(); - } - else { - logger.debug("Creating plain TopLink Session without active UnitOfWork for read-only transaction"); - session = getSessionFactory().createSession(); - } - - if (logger.isDebugEnabled()) { - logger.debug("Opened new session [" + session + "] for TopLink transaction"); - } - - TopLinkTransactionObject txObject = (TopLinkTransactionObject) transaction; - txObject.setSessionHolder(new SessionHolder(session)); - txObject.getSessionHolder().setSynchronizedWithTransaction(true); - - // Register transaction timeout. - int timeout = determineTimeout(definition); - if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) { - txObject.getSessionHolder().setTimeoutInSeconds(timeout); - } - - // Enforce early database transaction for TopLink read-write transaction, - // unless we are explicitly told to use lazy transactions. - if (!definition.isReadOnly() && !isLazyDatabaseTransaction()) { - session.getActiveUnitOfWork().beginEarlyTransaction(); - } - - // Register the TopLink Session's JDBC Connection for the DataSource, if set. - if (getDataSource() != null) { - Session mostSpecificSession = (!definition.isReadOnly() ? session.getActiveUnitOfWork() : session); - Connection con = getJdbcConnection(mostSpecificSession); - if (con != null) { - ConnectionHolder conHolder = new ConnectionHolder(con); - if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) { - conHolder.setTimeoutInSeconds(timeout); - } - if (logger.isDebugEnabled()) { - logger.debug("Exposing TopLink transaction as JDBC transaction [" + con + "]"); - } - TransactionSynchronizationManager.bindResource(getDataSource(), conHolder); - txObject.setConnectionHolder(conHolder); - } - else { - if (logger.isDebugEnabled()) { - logger.debug("Not exposing TopLink transaction [" + session + - "] as JDBC transaction because no JDBC Connection could be retrieved from it"); - } - } - } - - // Bind the session holder to the thread. - TransactionSynchronizationManager.bindResource(getSessionFactory(), txObject.getSessionHolder()); - } - - catch (Exception ex) { - SessionFactoryUtils.releaseSession(session, getSessionFactory()); - throw new CannotCreateTransactionException("Could not open TopLink Session for transaction", ex); - } - } - - /** - * Extract the underlying JDBC Connection from the given TopLink Session. - *

Default implementation casts to oracle.toplink.publicinterface.Session - * and fetches the Connection from the DatabaseAccessor exposed there. - * @param session the current TopLink Session - * @return the underlying JDBC Connection, or null if none found - * @see oracle.toplink.publicinterface.Session#getAccessor() - * @see oracle.toplink.internal.databaseaccess.DatabaseAccessor#getConnection() - */ - protected Connection getJdbcConnection(Session session) { - if (!(session instanceof oracle.toplink.publicinterface.Session)) { - if (logger.isDebugEnabled()) { - logger.debug("TopLink Session [" + session + - "] does not derive from [oracle.toplink.publicinterface.Session]"); - } - return null; - } - Accessor accessor = ((oracle.toplink.publicinterface.Session) session).getAccessor(); - if (!(accessor instanceof DatabaseAccessor)) { - if (logger.isDebugEnabled()) { - logger.debug("TopLink Accessor [" + accessor + - "] does not derive from [oracle.toplink.internal.databaseaccess.DatabaseAccessor]"); - } - return null; - } - return ((DatabaseAccessor) accessor).getConnection(); - } - - @Override - protected Object doSuspend(Object transaction) { - TopLinkTransactionObject txObject = (TopLinkTransactionObject) transaction; - txObject.setSessionHolder(null); - return TransactionSynchronizationManager.unbindResource(getSessionFactory()); - } - - @Override - protected void doResume(Object transaction, Object suspendedResources) { - SessionHolder sessionHolder = (SessionHolder) suspendedResources; - if (TransactionSynchronizationManager.hasResource(getSessionFactory())) { - // From non-transactional code running in active transaction synchronization - // -> can be safely removed, will be closed on transaction completion. - TransactionSynchronizationManager.unbindResource(getSessionFactory()); - } - TransactionSynchronizationManager.bindResource(getSessionFactory(), sessionHolder); - } - - @Override - protected void doCommit(DefaultTransactionStatus status) { - TopLinkTransactionObject txObject = (TopLinkTransactionObject) status.getTransaction(); - if (status.isDebug()) { - logger.debug("Committing TopLink transaction on session [" + - txObject.getSessionHolder().getSession() + "]"); - } - try { - if (!status.isReadOnly()) { - txObject.getSessionHolder().getSession().getActiveUnitOfWork().commit(); - } - txObject.getSessionHolder().clear(); - } - catch (TopLinkException ex) { - throw convertTopLinkAccessException(ex); - } - } - - @Override - protected void doRollback(DefaultTransactionStatus status) { - TopLinkTransactionObject txObject = (TopLinkTransactionObject) status.getTransaction(); - if (status.isDebug()) { - logger.debug("Not committing TopLink transaction on session [" + - txObject.getSessionHolder().getSession() + "]"); - } - txObject.getSessionHolder().clear(); - } - - @Override - protected void doSetRollbackOnly(DefaultTransactionStatus status) { - TopLinkTransactionObject txObject = (TopLinkTransactionObject) status.getTransaction(); - if (status.isDebug()) { - logger.debug("Setting TopLink transaction on session [" + - txObject.getSessionHolder().getSession() + "] rollback-only"); - } - txObject.getSessionHolder().setRollbackOnly(); - } - - @Override - protected void doCleanupAfterCompletion(Object transaction) { - TopLinkTransactionObject txObject = (TopLinkTransactionObject) transaction; - - // Remove the session holder from the thread. - TransactionSynchronizationManager.unbindResource(getSessionFactory()); - - // Remove the JDBC connection holder from the thread, if exposed. - if (txObject.hasConnectionHolder()) { - TransactionSynchronizationManager.unbindResource(getDataSource()); - } - - Session session = txObject.getSessionHolder().getSession(); - if (logger.isDebugEnabled()) { - logger.debug("Releasing TopLink Session [" + session + "] after transaction"); - } - try { - session.release(); - } - catch (Throwable ex) { - // just log it, to keep a transaction-related exception - logger.debug("Could not release TopLink Session after transaction", ex); - } - } - - /** - * Convert the given TopLinkException to an appropriate exception from the - * org.springframework.dao hierarchy. - *

Will automatically apply a specified SQLExceptionTranslator to a - * TopLink DatabaseException, else rely on TopLink's default translation. - * @param ex TopLinkException that occured - * @return a corresponding DataAccessException - * @see SessionFactoryUtils#convertTopLinkAccessException - * @see #setJdbcExceptionTranslator - */ - protected DataAccessException convertTopLinkAccessException(TopLinkException ex) { - if (getJdbcExceptionTranslator() != null && ex instanceof DatabaseException) { - Throwable internalEx = ex.getInternalException(); - // Should always be a SQLException inside a DatabaseException. - if (internalEx instanceof SQLException) { - return getJdbcExceptionTranslator().translate( - "TopLink commit: " + ex.getMessage(), null, (SQLException) internalEx); - } - } - return SessionFactoryUtils.convertTopLinkAccessException(ex); - } - - - /** - * TopLink transaction object, representing a SessionHolder. - * Used as transaction object by TopLinkTransactionManager. - */ - private static class TopLinkTransactionObject extends JdbcTransactionObjectSupport { - - private SessionHolder sessionHolder; - - public void setSessionHolder(SessionHolder sessionHolder) { - this.sessionHolder = sessionHolder; - } - - public SessionHolder getSessionHolder() { - return this.sessionHolder; - } - - public boolean isRollbackOnly() { - return getSessionHolder().isRollbackOnly(); - } - } - -} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/UnitOfWorkCallback.java b/org.springframework.orm/src/main/java/org/springframework/orm/toplink/UnitOfWorkCallback.java deleted file mode 100644 index 7505f2d03a..0000000000 --- a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/UnitOfWorkCallback.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2002-2005 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.toplink; - -import oracle.toplink.exceptions.TopLinkException; -import oracle.toplink.sessions.Session; -import oracle.toplink.sessions.UnitOfWork; - -/** - * Convenient abstract implementation of the TopLinkCallback interface, - * exposing a UnitOfWork to perform write operations on. - * - *

The exposed UnitOfWork will either be be the active UnitOfWork of - * the current transaction, if any, or a temporarily acquired UnitOfWork - * that will be committed at the end of the operation. - * - * @author Juergen Hoeller - * @since 1.2 - * @see #doInUnitOfWork(oracle.toplink.sessions.UnitOfWork) - * @see oracle.toplink.sessions.Session#getActiveUnitOfWork() - */ -public abstract class UnitOfWorkCallback implements TopLinkCallback { - - /** - * Determines the UnitOfWork to work on (either the active UnitOfWork or a - * temporarily acquired UnitOfWork) and delegates to doInUnitOfWork. - * @see #doInUnitOfWork(oracle.toplink.sessions.UnitOfWork) - */ - public final Object doInTopLink(Session session) throws TopLinkException { - // Fetch active UnitOfWork or acquire temporary UnitOfWork. - UnitOfWork unitOfWork = session.getActiveUnitOfWork(); - boolean newUnitOfWork = false; - if (unitOfWork == null) { - unitOfWork = session.acquireUnitOfWork(); - newUnitOfWork = true; - } - - // Perform callback operation, committing the UnitOfWork unless - // it is the active UnitOfWork of an externally managed transaction. - try { - Object result = doInUnitOfWork(unitOfWork); - if (newUnitOfWork) { - unitOfWork.commit(); - } - return result; - } - finally { - if (newUnitOfWork) { - unitOfWork.release(); - } - } - } - - /** - * Called with a UnitOfWork to work on, either the active UnitOfWork or a - * temporarily acquired UnitOfWork (as determined by the transaction status). - * @param unitOfWork the TopLink UnitOfWork to perform write operations on - * @return a result object, or null if none - * @throws TopLinkException in case of TopLink errors - */ - protected abstract Object doInUnitOfWork(UnitOfWork unitOfWork) throws TopLinkException; - -} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/package.html b/org.springframework.orm/src/main/java/org/springframework/orm/toplink/package.html deleted file mode 100644 index dfb35de0d8..0000000000 --- a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/package.html +++ /dev/null @@ -1,13 +0,0 @@ - - - -Package providing integration of -Oracle TopLink -with Spring concepts. - -

Contains SessionFactory helper classes, a template plus callback -for TopLink access, and an implementation of Spring's transaction SPI -for local TopLink transactions. - - - diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/support/CommonsLoggingSessionLog.java b/org.springframework.orm/src/main/java/org/springframework/orm/toplink/support/CommonsLoggingSessionLog.java deleted file mode 100644 index ec23aefa76..0000000000 --- a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/support/CommonsLoggingSessionLog.java +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright 2002-2007 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.toplink.support; - -import java.lang.reflect.Method; - -import oracle.toplink.internal.databaseaccess.Accessor; -import oracle.toplink.logging.AbstractSessionLog; -import oracle.toplink.logging.SessionLogEntry; -import oracle.toplink.publicinterface.Session; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.util.ReflectionUtils; - -/** - * TopLink 10.1.3+ SessionLog implementation that logs through Commons Logging. - * - *

The namespace used is "oracle.toplink.xxx", with the latter part being - * the TopLink log category ("sql"/"transaction"/etc). In case of no category - * given, "session" will be used as default. This allows for fine-grained - * filtering of log messages, for example through Log4J configuration. - * - *

Maps TopLink's SEVERE level to CL ERROR, TopLink's WARNING to CL WARN, - * TopLink's INFO to CL INFO, TopLink's CONFIG/FINE/FINER to CL DEBUG, - * and TopLink's FINEST to CL TRACE. This results in common CL log behavior: - * INFO logging only at startup; operation logging at DEBUG level. Debug logging - * can be further filtered according to categories: for example, activate Log4J - * DEBUG logging for category "oracle.toplink.sql" to see the generated SQL. - * - *

Note: This implementation will only work on TopLink 10.1.3 or higher, - * as it is built against TopLink's new SessionLog facilities in the - * oracle.toplink.logging package, supporting log categories. - * - * @author Juergen Hoeller - * @since 1.2 - * @see CommonsLoggingSessionLog904 - * @see oracle.toplink.logging.JavaLog - * @see org.springframework.orm.toplink.LocalSessionFactoryBean#setSessionLog - */ -public class CommonsLoggingSessionLog extends AbstractSessionLog { - - public static final String NAMESPACE_PREFIX = "oracle.toplink."; - - public static final String DEFAULT_NAMESPACE = "session"; - - public static final String DEFAULT_SEPARATOR = "--"; - - - private static Method getSessionMethod; - - private static Method getExceptionMethod; - - static { - try { - getSessionMethod = SessionLogEntry.class.getMethod("getSession", new Class[0]); - } - catch (NoSuchMethodException ex) { - throw new IllegalStateException("Could not find method SessionLogEntry.getSession()"); - } - try { - getExceptionMethod = SessionLogEntry.class.getMethod("getException", new Class[0]); - } - catch (NoSuchMethodException ex) { - throw new IllegalStateException("Could not find method SessionLogEntry.getException()"); - } - } - - - private String separator = DEFAULT_SEPARATOR; - - - /** - * Specify the separator between TopLink's supplemental details - * (session, connection) and the log message itself. Default is "--". - */ - public void setSeparator(String separator) { - this.separator = separator; - } - - /** - * Return the separator between TopLink's supplemental details - * (session, connection) and the log message itself. Default is "--". - */ - public String getSeparator() { - return this.separator; - } - - - @Override - public void log(SessionLogEntry entry) { - Log logger = LogFactory.getLog(getCategory(entry)); - switch (entry.getLevel()) { - case SEVERE: - if (logger.isErrorEnabled()) { - if (entry.hasException()) { - logger.error(getMessageString(entry), getException(entry)); - } - else { - logger.error(getMessageString(entry)); - } - } - break; - case WARNING: - if (logger.isWarnEnabled()) { - if (entry.hasException()) { - logger.warn(getMessageString(entry), getException(entry)); - } - else { - logger.warn(getMessageString(entry)); - } - } - break; - case INFO: - if (logger.isInfoEnabled()) { - if (entry.hasException()) { - logger.info(getMessageString(entry), getException(entry)); - } - else { - logger.info(getMessageString(entry)); - } - } - break; - case CONFIG: - case FINE: - case FINER: - if (logger.isDebugEnabled()) { - if (entry.hasException()) { - logger.debug(getMessageString(entry), getException(entry)); - } - else { - logger.debug(getMessageString(entry)); - } - } - break; - case FINEST: - if (logger.isTraceEnabled()) { - if (entry.hasException()) { - logger.trace(getMessageString(entry), getException(entry)); - } - else { - logger.trace(getMessageString(entry)); - } - } - break; - } - } - - /** - * Determine the log category for the given log entry. - *

If the entry carries a name space value, it will be appended - * to the "oracle.toplink." prefix; else, "oracle.toplink.session" - * will be used. - */ - protected String getCategory(SessionLogEntry entry) { - String namespace = entry.getNameSpace(); - return NAMESPACE_PREFIX + (namespace != null ? namespace : DEFAULT_NAMESPACE); - } - - /** - * Build the message String for the given log entry, including the - * supplemental details (session, connection) and the formatted message. - * @see #getSessionString(oracle.toplink.sessions.Session) - * @see #getConnectionString(oracle.toplink.internal.databaseaccess.Accessor) - * @see #formatMessage(oracle.toplink.logging.SessionLogEntry) - * @see #getSeparator() - */ - protected String getMessageString(SessionLogEntry entry) { - StringBuffer buf = new StringBuffer(); - Session session = getSession(entry); - if (session != null) { - buf.append(getSessionString(session)); - buf.append(getSeparator()); - } - Accessor connection = entry.getConnection(); - if (connection != null) { - buf.append(getConnectionString(connection)); - buf.append(getSeparator()); - } - buf.append(formatMessage(entry)); - return buf.toString(); - } - - /** - * Extract the exception from the given log entry. - *

The default implementation calls SessionLogEntry.getSession - * via reflection: The return type varies between TopLink 10.1.3 and 11 - * (Session vs AbstractSession, respectively). - */ - protected Session getSession(SessionLogEntry entry) { - return (Session) ReflectionUtils.invokeMethod(getSessionMethod, entry); - } - - /** - * Extract the exception from the given log entry. - *

The default implementation calls SessionLogEntry.getException - * via reflection: The return type varies between TopLink 9.0.4 and 10.1.3 - * (Exception vs Throwable, respectively). - */ - protected Throwable getException(SessionLogEntry entry) { - return (Throwable) ReflectionUtils.invokeMethod(getExceptionMethod, entry); - } - -} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/support/CommonsLoggingSessionLog904.java b/org.springframework.orm/src/main/java/org/springframework/orm/toplink/support/CommonsLoggingSessionLog904.java deleted file mode 100644 index 1b672114af..0000000000 --- a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/support/CommonsLoggingSessionLog904.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright 2002-2005 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.toplink.support; - -import oracle.toplink.sessions.DefaultSessionLog; -import oracle.toplink.sessions.Session; -import oracle.toplink.sessions.SessionLogEntry; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * TopLink 9.0.4 SessionLog implementation that logs through Commons Logging. - * - *

The namespace used is "oracle.toplink.session". Fine-grained filtering - * of log messages, for example through Log4J configuration, is not - * available on TopLink 9.0.4: Consider upgrading to TopLink 10.1.3 and - * using the CommonsLoggingSessionLog class instead. - * - *

TopLink log entries with exceptions are logged at CL WARN level, - * TopLink debug log entries at CL TRACE level, and any other log entry - * at CL DEBUG level. Finer-grained mapping to log levels is unfortunately - * not possible on TopLink 9.0.4. - * - *

Note: This implementation will only actually work on TopLink 9.0.4, - * as it is built against TopLink's old SessionLog facilities in the - * oracle.toplink.sessions package, which are effectively - * obsolete (deprecated and bypassed) as of TopLink 10.1.3. - * - * @author Juergen Hoeller - * @since 1.2 - * @see CommonsLoggingSessionLog - * @see oracle.toplink.sessions.DefaultSessionLog - * @see org.springframework.orm.toplink.LocalSessionFactoryBean#setSessionLog - */ -public class CommonsLoggingSessionLog904 extends DefaultSessionLog { - - public static final String NAMESPACE = "oracle.toplink.session"; - - public static final String DEFAULT_SEPARATOR = "--"; - - - private final Log logger = LogFactory.getLog(NAMESPACE); - - private String separator = DEFAULT_SEPARATOR; - - - /** - * Specify the separator between TopLink's supplemental details - * (session, connection) and the log message itself. Default is "--". - */ - public void setSeparator(String separator) { - this.separator = separator; - } - - /** - * Return the separator between TopLink's supplemental details - * (session, connection) and the log message itself. Default is "--". - */ - public String getSeparator() { - return separator; - } - - - @Override - public void log(SessionLogEntry entry) { - if (entry.hasException()) { - if (shouldLogExceptions() && logger.isWarnEnabled()) { - this.logger.warn(getMessageString(entry), entry.getException()); - } - } - else if (entry.isDebug()) { - if (shouldLogDebug() && logger.isTraceEnabled()) { - this.logger.trace(getMessageString(entry)); - } - } - else { - if (logger.isDebugEnabled()) { - this.logger.debug(getMessageString(entry)); - } - } - } - - /** - * Build the message String for the given log entry, including the - * supplemental details (session, connection) and the message text. - * @see #getSeparator() - */ - protected String getMessageString(SessionLogEntry entry) { - StringBuffer buf = new StringBuffer(); - if (shouldPrintSession()) { - buf.append(getSessionName(entry.getSession())); - buf.append("("); - buf.append(String.valueOf(System.identityHashCode(entry.getSession()))); - buf.append(")"); - buf.append(getSeparator()); - } - if (shouldPrintConnection() && entry.getConnection() != null) { - buf.append("Connection"); - buf.append("("); - buf.append(String.valueOf(System.identityHashCode(entry.getConnection()))); - buf.append(")"); - buf.append(getSeparator()); - } - buf.append(entry.getMessage()); - return buf.toString(); - } - - /** - * Return the name to be used for the given Session - * ("UnitOfWork"/"ServerSession"/"ClientSession"/etc). - */ - protected String getSessionName(Session session) { - if (session.isUnitOfWork()) { - return "UnitOfWork"; - } - if (session.isServerSession()) { - return "ServerSession"; - } - if (session.isClientSession()) { - return "ClientSession"; - } - if (session.isSessionBroker()) { - return "SessionBroker"; - } - if (session.isRemoteSession()) { - return "RemoteSession"; - } - if (session.isDatabaseSession()) { - return "DatabaseSession"; - } - return "Session"; - } - -} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/support/TopLinkDaoSupport.java b/org.springframework.orm/src/main/java/org/springframework/orm/toplink/support/TopLinkDaoSupport.java deleted file mode 100644 index 1c917f5c2b..0000000000 --- a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/support/TopLinkDaoSupport.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright 2002-2008 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.toplink.support; - -import oracle.toplink.exceptions.TopLinkException; -import oracle.toplink.sessions.Session; - -import org.springframework.dao.DataAccessException; -import org.springframework.dao.DataAccessResourceFailureException; -import org.springframework.dao.support.DaoSupport; -import org.springframework.orm.toplink.SessionFactory; -import org.springframework.orm.toplink.SessionFactoryUtils; -import org.springframework.orm.toplink.TopLinkTemplate; - -/** - * Convenient super class for TopLink data access objects. - * - *

Requires a SessionFactory to be set, providing a TopLinkTemplate - * based on it to subclasses. Can alternatively be initialized directly with - * a TopLinkTemplate, to reuse the latter's settings such as the SessionFactory, - * exception translator, etc. - * - *

This base class is mainly intended for TopLinkTemplate usage - * but can also be used when working with SessionFactoryUtils directly, - * for example in combination with TopLinkInterceptor-managed Sessions. - * Convenience getSession and releaseSession - * methods are provided for that usage style. - * - * @author Juergen Hoeller - * @since 1.2 - * @see #setSessionFactory - * @see #setTopLinkTemplate - * @see #getSession - * @see #releaseSession - * @see org.springframework.orm.toplink.TopLinkTemplate - * @see org.springframework.orm.toplink.TopLinkInterceptor - */ -public abstract class TopLinkDaoSupport extends DaoSupport { - - private TopLinkTemplate topLinkTemplate; - - - /** - * Set the TopLink SessionFactory to be used by this DAO. - * Will automatically create a TopLinkTemplate for the given SessionFactory. - * @see #createTopLinkTemplate - * @see #setTopLinkTemplate - */ - public final void setSessionFactory(SessionFactory sessionFactory) { - if (this.topLinkTemplate == null || sessionFactory != this.topLinkTemplate.getSessionFactory()) { - this.topLinkTemplate = createTopLinkTemplate(sessionFactory); - } - } - - /** - * Create a TopLinkTemplate for the given SessionFactory. - * Only invoked if populating the DAO with a SessionFactory reference! - *

Can be overridden in subclasses to provide a TopLinkTemplate instance - * with different configuration, or a custom TopLinkTemplate subclass. - * @param sessionFactory the TopLink SessionFactory to create a TopLinkTemplate for - * @return the new TopLinkTemplate instance - * @see #setSessionFactory - */ - protected TopLinkTemplate createTopLinkTemplate(SessionFactory sessionFactory) { - return new TopLinkTemplate(sessionFactory); - } - - /** - * Return the TopLink SessionFactory used by this DAO. - */ - public final SessionFactory getSessionFactory() { - return (this.topLinkTemplate != null ? this.topLinkTemplate.getSessionFactory() : null); - } - - /** - * Set the TopLinkTemplate for this DAO explicitly, - * as an alternative to specifying a SessionFactory. - * @see #setSessionFactory - */ - public final void setTopLinkTemplate(TopLinkTemplate topLinkTemplate) { - this.topLinkTemplate = topLinkTemplate; - } - - /** - * Return the TopLinkTemplate for this DAO, - * pre-initialized with the SessionFactory or set explicitly. - */ - public final TopLinkTemplate getTopLinkTemplate() { - return topLinkTemplate; - } - - @Override - protected final void checkDaoConfig() { - if (this.topLinkTemplate == null) { - throw new IllegalArgumentException("sessionFactory or topLinkTemplate is required"); - } - } - - - /** - * Get a TopLink Session, either from the current transaction or a new one. - * The latter is only allowed if the "allowCreate" setting of this bean's - * TopLinkTemplate is true. - *

Note that this is not meant to be invoked from TopLinkTemplate code - * but rather just in plain TopLink code. Either rely on a thread-bound - * Session (via TopLinkInterceptor), or use it in combination with - * releaseSession. - *

In general, it is recommended to use TopLinkTemplate, either with - * the provided convenience operations or with a custom TopLinkCallback - * that provides you with a Session to work on. TopLinkTemplate will care - * for all resource management and for proper exception conversion. - * @return the TopLink Session - * @throws DataAccessResourceFailureException if the Session couldn't be created - * @throws IllegalStateException if no thread-bound Session found and allowCreate false - * @see TopLinkTemplate - * @see org.springframework.orm.toplink.SessionFactoryUtils#getSession(SessionFactory, boolean) - * @see org.springframework.orm.toplink.TopLinkInterceptor - * @see org.springframework.orm.toplink.TopLinkTemplate - * @see org.springframework.orm.toplink.TopLinkCallback - */ - protected final Session getSession() - throws DataAccessResourceFailureException, IllegalStateException { - - return getSession(this.topLinkTemplate.isAllowCreate()); - } - - /** - * Get a TopLink Session, either from the current transaction or a new one. - * The latter is only allowed if "allowCreate" is true. - *

Note that this is not meant to be invoked from TopLinkTemplate code - * but rather just in plain TopLink code. Either rely on a thread-bound - * Session (via TopLinkInterceptor), or use it in combination with - * releaseSession. - *

In general, it is recommended to use TopLinkTemplate, either with - * the provided convenience operations or with a custom TopLinkCallback - * that provides you with a Session to work on. TopLinkTemplate will care - * for all resource management and for proper exception conversion. - * @param allowCreate if a new Session should be created if no thread-bound found - * @return the TopLink Session - * @throws DataAccessResourceFailureException if the Session couldn't be created - * @throws IllegalStateException if no thread-bound Session found and allowCreate false - * @see org.springframework.orm.toplink.SessionFactoryUtils#getSession(SessionFactory, boolean) - * @see org.springframework.orm.toplink.TopLinkInterceptor - * @see org.springframework.orm.toplink.TopLinkTemplate - * @see org.springframework.orm.toplink.TopLinkCallback - */ - protected final Session getSession(boolean allowCreate) - throws DataAccessResourceFailureException, IllegalStateException { - - return SessionFactoryUtils.getSession(this.getSessionFactory(), allowCreate); - } - - /** - * Convert the given TopLinkException to an appropriate exception from the - * org.springframework.dao hierarchy. Will automatically detect - * wrapped SQLExceptions and convert them accordingly. - *

Delegates to the convertTopLinkAccessException method of this - * DAO's TopLinkTemplate. - * @param ex TopLinkException that occured - * @return the corresponding DataAccessException instance - * @see #setTopLinkTemplate - * @see org.springframework.orm.toplink.TopLinkTemplate#convertTopLinkAccessException - */ - protected final DataAccessException convertTopLinkAccessException(TopLinkException ex) { - return this.topLinkTemplate.convertTopLinkAccessException(ex); - } - - /** - * Close the given TopLink Session, created via this DAO's SessionFactory, - * if it isn't bound to the thread. - * @param session the TopLink Session to close - * @see org.springframework.orm.toplink.SessionFactoryUtils#releaseSession - */ - protected final void releaseSession(Session session) { - SessionFactoryUtils.releaseSession(session, getSessionFactory()); - } - -} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/support/TransactionAwareSessionAdapter.java b/org.springframework.orm/src/main/java/org/springframework/orm/toplink/support/TransactionAwareSessionAdapter.java deleted file mode 100644 index e12f65cd70..0000000000 --- a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/support/TransactionAwareSessionAdapter.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2002-2005 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.toplink.support; - -import oracle.toplink.sessions.Session; - -import org.springframework.beans.factory.FactoryBean; -import org.springframework.orm.toplink.SessionFactory; - -/** - * This adapter FactoryBean takes a TopLink SessionFactory and exposes a - * corresponding transaction-aware TopLink Session as bean reference. - * - *

This adapter bean will usually be defined in front of a Spring - * LocalSessionFactoryBean, to allow for passing Session references to DAOs - * that expect to work on a raw TopLink Session. Your DAOs can then, - * for example, access the currently active Session and UnitOfWork via - * Session.getActiveSession() and - * Session.getActiveUnitOfWork(), respectively. - * - *

The main advantage of this proxy is that it allows DAOs to work with a - * plain TopLink Session reference, while still participating in Spring's - * (or a J2EE server's) resource and transaction management. DAOs will only - * rely on the TopLink API in such a scenario, without any Spring dependencies. - * - *

It is usually preferable to write your TopLink-based DAOs with Spring's - * TopLinkTemplate, offering benefits such as consistent data access exceptions - * instead of TopLinkExceptions at the DAO layer. However, Spring's resource - * and transaction management (and Dependency Injection) will work for DAOs - * written against the plain TopLink API too. - * - *

Of course, you can still access the target TopLink SessionFactory - * even when your DAOs go through this adapter, by defining a bean reference - * that points directly at your target SessionFactory bean. - * - *

Note that the actual creation of a transaction-aware TopLink Session - * is available on the TopLink SessionFactory itself. This adapter FactoryBean - * is just a convenient way to expose such a Session in a declarative fashion. - * - * @author Juergen Hoeller - * @since 1.2 - * @see org.springframework.orm.toplink.LocalSessionFactoryBean - * @see org.springframework.orm.toplink.SessionFactory#createTransactionAwareSession() - * @see oracle.toplink.sessions.Session#getActiveSession() - * @see oracle.toplink.sessions.Session#getActiveUnitOfWork() - */ -public class TransactionAwareSessionAdapter implements FactoryBean { - - private Session session; - - - /** - * Set the SessionFactory that this adapter is supposed to expose a - * transaction-aware TopLink Session for. This should be the raw - * SessionFactory, as accessed by TopLinkTransactionManager. - * @see org.springframework.orm.toplink.TopLinkTransactionManager - */ - public void setSessionFactory(SessionFactory sessionFactory) { - this.session = sessionFactory.createTransactionAwareSession(); - } - - - public Object getObject() { - return this.session; - } - - public Class getObjectType() { - return Session.class; - } - - public boolean isSingleton() { - return true; - } - -} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/support/package.html b/org.springframework.orm/src/main/java/org/springframework/orm/toplink/support/package.html deleted file mode 100644 index cee7e65060..0000000000 --- a/org.springframework.orm/src/main/java/org/springframework/orm/toplink/support/package.html +++ /dev/null @@ -1,8 +0,0 @@ - - - -Classes supporting the org.springframework.orm.toplink package. -Contains a DAO base class for TopLinkTemplate usage. - - -