📄 hibernatetemplate.java
字号:
/*
* Copyright 2002-2004 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.hibernate;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import net.sf.hibernate.Criteria;
import net.sf.hibernate.FlushMode;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.LockMode;
import net.sf.hibernate.Query;
import net.sf.hibernate.Session;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.type.Type;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.transaction.support.TransactionSynchronizationManager;
/**
* Helper class that simplifies Hibernate data access code, and converts
* checked HibernateExceptions into unchecked DataAccessExceptions,
* compatible to the org.springframework.dao exception hierarchy.
* Uses the same SQLExceptionTranslator mechanism as JdbcTemplate.
*
* <p>Typically used to implement data access or business logic services that
* use Hibernate within their implementation but are Hibernate-agnostic in
* their interface. The latter resp. code calling the latter only have to deal
* with domain objects, query objects, and org.springframework.dao exceptions.
*
* <p>The central method is "execute", supporting Hibernate code implementing
* the HibernateCallback interface. It provides Hibernate Session handling
* such that neither the HibernateCallback implementation nor the calling
* code needs to explicitly care about retrieving/closing Hibernate Sessions,
* or handling Session lifecycle exceptions. For typical single step actions,
* there are various convenience methods (find, load, saveOrUpdate, delete).
*
* <p>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.
*
* <p>This class can be considered a programmatic alternative to
* HibernateInterceptor. The major advantage is its straightforwardness, the
* major disadvantage that no checked application exceptions can get thrown
* from within data access code. Such checks and the actual throwing of such
* exceptions can often be deferred to after callback execution, though.
*
* <p>Note that even if HibernateTransactionManager is used for transaction
* demarcation in higher-level services, all those services above the data
* access layer don't need need to be Hibernate-aware. Setting such a special
* PlatformTransactionManager is a configuration issue: For example,
* switching to JTA is just a matter of Spring configuration (use
* JtaTransactionManager instead) that does not affect application code.
*
* <p>LocalSessionFactoryBean is the preferred way of obtaining a reference
* to a specific Hibernate SessionFactory, at least in a non-EJB environment.
* Alternatively, use a JndiObjectFactoryBean to fetch a SessionFactory
* from JNDI (possibly set up via a JCA Connector).
*
* <p>Note: Spring's Hibernate support requires Hibernate 2.1 (as of Spring 1.0).
*
* @author Juergen Hoeller
* @since 02.05.2003
* @see #setSessionFactory
* @see #setJdbcExceptionTranslator
* @see HibernateCallback
* @see HibernateInterceptor
* @see HibernateTransactionManager
* @see LocalSessionFactoryBean
* @see org.springframework.jndi.JndiObjectFactoryBean
* @see org.springframework.jdbc.support.SQLExceptionTranslator
* @see net.sf.hibernate.Session
*/
public class HibernateTemplate extends HibernateAccessor implements HibernateOperations {
private boolean allowCreate = true;
private boolean cacheQueries = false;
private boolean checkWriteOperations = true;
/**
* Create a new HibernateTemplate instance.
*/
public HibernateTemplate() {
}
/**
* Create a new HibernateTemplate instance.
* @param sessionFactory SessionFactory to create Sessions
*/
public HibernateTemplate(SessionFactory sessionFactory) {
setSessionFactory(sessionFactory);
afterPropertiesSet();
}
/**
* Create a new HibernateTemplate instance.
* @param sessionFactory SessionFactory to create Sessions
* @param allowCreate if a new Session should be created
* if no thread-bound found
*/
public HibernateTemplate(SessionFactory sessionFactory, boolean allowCreate) {
setSessionFactory(sessionFactory);
setAllowCreate(allowCreate);
afterPropertiesSet();
}
/**
* Set if a new Session should be created if no thread-bound found.
* <p>HibernateTemplate is aware of a respective Session bound to the
* current thread, for example when using HibernateTransactionManager.
* If allowCreate is true, a new Session will be created if none found.
* 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 allowCreate;
}
/**
* Set whether to cache all queries executed by this template.
* If this is true, all Query and Criteria objects created by
* this template will be marked as cacheable.
* @see net.sf.hibernate.Query#setCacheable
* @see net.sf.hibernate.Criteria#setCacheable
*/
public void setCacheQueries(boolean cacheQueries) {
this.cacheQueries = cacheQueries;
}
/**
* Return whether to cache all queries executed by this template.
*/
public boolean isCacheQueries() {
return cacheQueries;
}
/**
* Set whether to check that the Hibernate Session is not in read-only mode
* in case of write operations (save/update/delete).
* <p>Default is true, for fail-fast behavior when attempting write operations
* within a read-only transaction. Turn this off to allow save/update/delete
* on a Session with flush mode NEVER.
* @see #setFlushMode
* @see #checkWriteOperationAllowed
* @see org.springframework.transaction.TransactionDefinition#isReadOnly
*/
public void setCheckWriteOperations(boolean checkWriteOperations) {
this.checkWriteOperations = checkWriteOperations;
}
/**
* Return whether to check that the Hibernate Session is not in read-only
* mode in case of write operations (save/update/delete).
*/
public boolean isCheckWriteOperations() {
return checkWriteOperations;
}
public Object execute(HibernateCallback action) throws DataAccessException {
Session session = (!isAllowCreate() ?
SessionFactoryUtils.getSession(getSessionFactory(), false) :
SessionFactoryUtils.getSession(
getSessionFactory(), getEntityInterceptor(), getJdbcExceptionTranslator()));
boolean existingTransaction = TransactionSynchronizationManager.hasResource(getSessionFactory());
if (!existingTransaction && getFlushMode() == FLUSH_NEVER) {
session.setFlushMode(FlushMode.NEVER);
}
try {
Object result = action.doInHibernate(session);
flushIfNecessary(session, existingTransaction);
return result;
}
catch (HibernateException ex) {
throw convertHibernateAccessException(ex);
}
catch (SQLException ex) {
throw convertJdbcAccessException(ex);
}
catch (RuntimeException ex) {
// callback code threw application exception
throw ex;
}
finally {
SessionFactoryUtils.closeSessionIfNecessary(session, getSessionFactory());
}
}
public List executeFind(HibernateCallback action) throws DataAccessException {
return (List) execute(action);
}
//-------------------------------------------------------------------------
// Convenience methods for loading individual objects
//-------------------------------------------------------------------------
public Object get(final Class entityClass, final Serializable id) throws DataAccessException {
return execute(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
return session.get(entityClass, id);
}
});
}
public Object get(final Class entityClass, final Serializable id, final LockMode lockMode)
throws DataAccessException {
return execute(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
return session.get(entityClass, id, lockMode);
}
});
}
public Object load(final Class entityClass, final Serializable id) throws DataAccessException {
return execute(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
return session.load(entityClass, id);
}
});
}
public Object load(final Class entityClass, final Serializable id, final LockMode lockMode)
throws DataAccessException {
return execute(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
return session.load(entityClass, id, lockMode);
}
});
}
public List loadAll(final Class entityClass) throws DataAccessException {
return executeFind(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
Criteria criteria = createCriteria(session, entityClass);
return criteria.list();
}
});
}
public void refresh(final Object entity) throws DataAccessException {
execute(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
session.refresh(entity);
return null;
}
});
}
public void refresh(final Object entity, final LockMode lockMode) throws DataAccessException {
execute(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
session.refresh(entity, lockMode);
return null;
}
});
}
public boolean contains(final Object entity) throws DataAccessException {
Boolean result = (Boolean) execute(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
return new Boolean(session.contains(entity));
}
});
return result.booleanValue();
}
public void evict(final Object entity) throws DataAccessException {
execute(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
session.evict(entity);
return null;
}
});
}
//-------------------------------------------------------------------------
// Convenience methods for storing individual objects
//-------------------------------------------------------------------------
public void lock(final Object entity, final LockMode lockMode) throws DataAccessException {
execute(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
session.lock(entity, lockMode);
return null;
}
});
}
public Serializable save(final Object entity) throws DataAccessException {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -