org.eclipse.persistence.sessions.factories.SessionFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.eclipse.persistence.core Show documentation
Show all versions of org.eclipse.persistence.core Show documentation
EclipseLink build based upon Git transaction ecdf3c32c4
/*
* Copyright (c) 1998, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.sessions.factories;
import java.util.Collection;
import org.eclipse.persistence.sessions.broker.SessionBroker;
import org.eclipse.persistence.sessions.*;
import org.eclipse.persistence.sessions.server.Server;
import org.eclipse.persistence.sessions.factories.SessionManager;
/**
* Helper class to simplify the development and generation of code that accesses
* TopLink through the SessionManager (sessions config XML).
* Responsibilities:
* - Lookup of a session by name using default or provided sessions config location
*
- Support lookup of active UnitOfWork and Session in JTA environments
*
- Hot/Re-deployment handling of applications
*
- Detachment helpers to simplify usage within a local session bean
*
*
* Basic usage example:
*
* SessionFactory = sessionFactory = new SessionFactory("session-name");
*
* ...
*
* public List read(Vector args) {
* Session session = sessionFactory.acquireSession();
*
* List results = (List) session.executeQuery("query-name", MyClass.class, args);
*
* session.release();
* return results;
* }
*
* public void write(MyClass detachedInstance) {
* UnitOfWork uow = sessionFactory.acquireUnitOfWork();
*
* MyClass workingCopy = (MyClass) uow.readObject(detachedInstance);
*
* if (workingCopy == null) {
* throw new MyException("Cannot write changes. Object does not exist");
* }
*
* uow.deepMergeClone(detachedInstance);
*
* uow.commit();
* }
*
*
* Detachment: The detach helper methods are provided to assist with the
* construction of applications. This helper class was designed for use within
* session beans (SB) and in the case of local SBs the objects returned are not
* serialized. Since EclipseLink's default behavior is to return the shared instance
* from the cache and rely on developers to only modify instances within a
* UnitOfWork this may be an issue. The client to the local session bean may
* try to modify the instance and thus corrupt the cache. By detaching the object
* the client to the session bean gets its own isolated copy that it can freely
* modify. This provides the same functionality as with a remote session bean
* and allows the developer the choice in how/when objects are detached.
* Note: The above code example shows how a detached instance can have
* changes made to it persisted through use of the UnitOfWork merge API.
*
* @author Doug Clarke {@literal &} John Braken
* @version 10.1.3
* @since Dec 10, 2006
*/
public class SessionFactory {
/**
* Location for the sessions.xml file. The default here is the most common.
* If none is provided then EclipseLink's default locations of 'sessions.xml'
* and 'META-INF/sessions.xml' will be tried.
*/
private String sessionXMLPath;
private String sessionName;
/**
* Constructor for creating a new EclipseLinkSessionHelper instance.
*
* @param sessionsXMLPath - resource path of the sessions configuration xml.
* @param sessionName - name of the session to use.
*/
public SessionFactory(String sessionsXMLPath, String sessionName) {
this.sessionXMLPath = sessionsXMLPath;
this.sessionName = sessionName;
}
public SessionFactory(String sessionName) {
this.sessionName = sessionName;
}
public String getSessionName() {
return sessionName;
}
public String getSessionXMLPath() {
return this.sessionXMLPath;
}
/**
* The class-loader returned form this call will be used when loading the
* EclipseLink configuration. By default this is the current thread's loader.
* If this is not the case users can subclass this session factory and
* override this method to provide a different loader.
*/
protected ClassLoader getClassLoader() {
return Thread.currentThread().getContextClassLoader();
}
/**
* Helper method that looks up the singleton session and ensure that
* if the application has been hot-deployed it gets a fresh version of the
* server.
*/
public DatabaseSession getSharedSession() {
return getSharedSession(true, false);
}
/**
* Used in place of getSharedSession() when the calling application needs
* access to the session prior to login or it wishes to force the session
* configuration to be re-loaded an applied. This also makes use of the
* current class-loader return from getClassLoader() and a SessionManager
* class-loader check to see if the application was loaded by another
* class-loader and is should this be refreshed as the application has been
* hot deployed.
*/
public DatabaseSession getSharedSession(boolean login, boolean refresh) {
XMLSessionConfigLoader xmlLoader;
if (getSessionXMLPath() != null) {
xmlLoader = new XMLSessionConfigLoader(getSessionXMLPath());
} else {
xmlLoader = new XMLSessionConfigLoader();
}
return (DatabaseSession)SessionManager.getManager().getSession(xmlLoader,
getSessionName(),
getClassLoader(),
login,
refresh,
true);
}
/**
* Returns the Session active for this specified helper. If the EclipseLink
* session does not have an external transaction controller or there is
* not an active JTA transaction then a newly acquire client session is
* returned on each call.
*
* This method also properly handles acquire a client session from a broker
* as well as returning the shared session in the case it is a database
* session.
*/
public Session acquireSession() {
Session sharedSession = getSharedSession();
if (sharedSession.hasExternalTransactionController()) {
UnitOfWork uow = sharedSession.getActiveUnitOfWork();
if (uow != null) {
return uow.getParent();
}
}
if (sharedSession.isServerSession()) {
return ((Server)sharedSession).acquireClientSession();
}
if (sharedSession.isSessionBroker()) {
SessionBroker broker = (SessionBroker)sharedSession;
if (broker.isServerSessionBroker()) {
return broker.acquireClientSessionBroker();
}
return broker;
}
// Assume we have a database session and return it.
return sharedSession;
}
/**
* Looks up the active UnitOfWork using either the global JTA TX or acquires
* a new one from the active session.
*/
public UnitOfWork acquireUnitOfWork() {
return acquireUnitOfWork(getSharedSession());
}
/**
* Looks up the active UnitOfWork using either the global JTA TX or acquires
* a new one from the active session. THis method should be used if a session
* has already been acquired.
*/
public UnitOfWork acquireUnitOfWork(Session session) {
if (session.hasExternalTransactionController()) {
return session.getActiveUnitOfWork();
}
return session.acquireUnitOfWork();
}
/**
* Build a detached copy using a one-off UnitOfWork.
* This simulates creation of a copy through serialization when using a
* remote session bean if this copy process is not done the user of this
* helper would return the shared copy from the cache that should not be
* modified. These detachment methods *MUST* be used for local session
* beans where the returned objects can be modified by the client.
*
* @param entity an existing persistent entity
* @return a copy of the entity for use in a local client that may make changes to it
*/
public Object detach(Object entity) {
UnitOfWork uow =
((org.eclipse.persistence.internal.sessions.AbstractSession)getSharedSession()).acquireNonSynchronizedUnitOfWork(null);
Object copy = uow.registerObject(entity);
uow.release();
return copy;
}
public Collection detach(Collection entities) {
UnitOfWork uow =
((org.eclipse.persistence.internal.sessions.AbstractSession)getSharedSession()).acquireNonSynchronizedUnitOfWork(null);
Collection copies = uow.registerAllObjects(entities);
uow.release();
return copies;
}
}