generified operations interfaces; update to JDO 2.1; preparation for JPA 2.0

This commit is contained in:
Juergen Hoeller 2009-01-25 23:20:41 +00:00
parent 612ed8c660
commit e7465dcb99
34 changed files with 708 additions and 383 deletions

View File

@ -47,7 +47,7 @@
<dependency org="org.hibernate" name="com.springsource.org.hibernate" rev="3.2.6.ga" conf="optional, hibernate->compile"/> <dependency org="org.hibernate" name="com.springsource.org.hibernate" rev="3.2.6.ga" conf="optional, hibernate->compile"/>
<dependency org="org.hibernate" name="com.springsource.org.hibernate.annotations" rev="3.3.0.ga" conf="optional, hibernate-jpa->compile"/> <dependency org="org.hibernate" name="com.springsource.org.hibernate.annotations" rev="3.3.0.ga" conf="optional, hibernate-jpa->compile"/>
<dependency org="org.hibernate" name="com.springsource.org.hibernate.ejb" rev="3.3.1.ga" conf="optional, hibernate-jpa->compile"/> <dependency org="org.hibernate" name="com.springsource.org.hibernate.ejb" rev="3.3.1.ga" conf="optional, hibernate-jpa->compile"/>
<dependency org="javax.jdo" name="com.springsource.javax.jdo" rev="2.0.0" conf="provided, jdo->compile"/> <dependency org="javax.jdo" name="com.springsource.javax.jdo" rev="2.1.0" conf="provided, jdo->compile"/>
<dependency org="javax.persistence" name="com.springsource.javax.persistence" rev="1.0.0" conf="provided, jpa->compile"/> <dependency org="javax.persistence" name="com.springsource.javax.persistence" rev="1.0.0" conf="provided, jpa->compile"/>
<dependency org="javax.servlet" name="com.springsource.javax.servlet" rev="2.5.0" conf="provided, web->compile"/> <dependency org="javax.servlet" name="com.springsource.javax.servlet" rev="2.5.0" conf="provided, web->compile"/>
<dependency org="javax.transaction" name="com.springsource.javax.transaction" rev="1.1.0" conf="provided->runtime"/> <dependency org="javax.transaction" name="com.springsource.javax.transaction" rev="1.1.0" conf="provided->runtime"/>

View File

@ -162,11 +162,11 @@
<orderEntry type="module-library"> <orderEntry type="module-library">
<library> <library>
<CLASSES> <CLASSES>
<root url="jar://$IVY_CACHE$/javax.jdo/com.springsource.javax.jdo/2.0.0/com.springsource.javax.jdo-2.0.0.jar!/" /> <root url="jar://$IVY_CACHE$/javax.jdo/com.springsource.javax.jdo/2.1.0/com.springsource.javax.jdo-2.1.0.jar!/" />
</CLASSES> </CLASSES>
<JAVADOC /> <JAVADOC />
<SOURCES> <SOURCES>
<root url="jar://$IVY_CACHE$/javax.jdo/com.springsource.javax.jdo/2.0.0/com.springsource.javax.jdo-sources-2.0.0.jar!/" /> <root url="jar://$IVY_CACHE$/javax.jdo/com.springsource.javax.jdo/2.1.0/com.springsource.javax.jdo-sources-2.1.0.jar!/" />
</SOURCES> </SOURCES>
</library> </library>
</orderEntry> </orderEntry>

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2008 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -55,7 +55,7 @@ import org.springframework.jdbc.support.SQLExceptionTranslator;
* @see org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor * @see org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor
*/ */
public abstract class AbstractSessionFactoryBean public abstract class AbstractSessionFactoryBean
implements FactoryBean, InitializingBean, DisposableBean, PersistenceExceptionTranslator { implements FactoryBean<SessionFactory>, InitializingBean, DisposableBean, PersistenceExceptionTranslator {
/** Logger available to subclasses */ /** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass()); protected final Log logger = LogFactory.getLog(getClass());
@ -256,11 +256,11 @@ public abstract class AbstractSessionFactoryBean
/** /**
* Return the singleton SessionFactory. * Return the singleton SessionFactory.
*/ */
public Object getObject() { public SessionFactory getObject() {
return this.sessionFactory; return this.sessionFactory;
} }
public Class getObjectType() { public Class<? extends SessionFactory> getObjectType() {
return (this.sessionFactory != null) ? this.sessionFactory.getClass() : SessionFactory.class; return (this.sessionFactory != null) ? this.sessionFactory.getClass() : SessionFactory.class;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2006 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -41,7 +41,7 @@ import org.hibernate.Session;
* @see HibernateTemplate * @see HibernateTemplate
* @see HibernateTransactionManager * @see HibernateTransactionManager
*/ */
public interface HibernateCallback { public interface HibernateCallback<T> {
/** /**
* Gets called by <code>HibernateTemplate.execute</code> with an active * Gets called by <code>HibernateTemplate.execute</code> with an active
@ -66,6 +66,6 @@ public interface HibernateCallback {
* @see HibernateTemplate#execute * @see HibernateTemplate#execute
* @see HibernateTemplate#executeFind * @see HibernateTemplate#executeFind
*/ */
Object doInHibernate(Session session) throws HibernateException, SQLException; T doInHibernate(Session session) throws HibernateException, SQLException;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2008 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -85,7 +85,7 @@ public interface HibernateOperations {
* @see org.springframework.transaction * @see org.springframework.transaction
* @see org.hibernate.Session * @see org.hibernate.Session
*/ */
Object execute(HibernateCallback action) throws DataAccessException; <T> T execute(HibernateCallback<T> action) throws DataAccessException;
/** /**
* Execute the specified action assuming that the result object is a * Execute the specified action assuming that the result object is a
@ -96,7 +96,7 @@ public interface HibernateOperations {
* @return a List result returned by the action, or <code>null</code> * @return a List result returned by the action, or <code>null</code>
* @throws org.springframework.dao.DataAccessException in case of Hibernate errors * @throws org.springframework.dao.DataAccessException in case of Hibernate errors
*/ */
List executeFind(HibernateCallback action) throws DataAccessException; List executeFind(HibernateCallback<?> action) throws DataAccessException;
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -530,7 +530,7 @@ public interface HibernateOperations {
* @see org.hibernate.Session#merge(String, Object) * @see org.hibernate.Session#merge(String, Object)
* @see #saveOrUpdate * @see #saveOrUpdate
*/ */
Object merge(String entityName, Object entity) throws DataAccessException; <T> T merge(String entityName, T entity) throws DataAccessException;
/** /**
* Delete the given persistent instance. * Delete the given persistent instance.

View File

@ -335,11 +335,11 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
} }
public Object execute(HibernateCallback action) throws DataAccessException { public <T> T execute(HibernateCallback<T> action) throws DataAccessException {
return doExecute(action, false, false); return doExecute(action, false, false);
} }
public List executeFind(HibernateCallback action) throws DataAccessException { public List executeFind(HibernateCallback<?> action) throws DataAccessException {
Object result = doExecute(action, false, false); Object result = doExecute(action, false, false);
if (result != null && !(result instanceof List)) { if (result != null && !(result instanceof List)) {
throw new InvalidDataAccessApiUsageException( throw new InvalidDataAccessApiUsageException(
@ -357,7 +357,7 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
* @return a result object returned by the action, or <code>null</code> * @return a result object returned by the action, or <code>null</code>
* @throws org.springframework.dao.DataAccessException in case of Hibernate errors * @throws org.springframework.dao.DataAccessException in case of Hibernate errors
*/ */
public Object executeWithNewSession(HibernateCallback action) { public <T> T executeWithNewSession(HibernateCallback<T> action) {
return doExecute(action, true, false); return doExecute(action, true, false);
} }
@ -370,24 +370,10 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
* @return a result object returned by the action, or <code>null</code> * @return a result object returned by the action, or <code>null</code>
* @throws org.springframework.dao.DataAccessException in case of Hibernate errors * @throws org.springframework.dao.DataAccessException in case of Hibernate errors
*/ */
public Object executeWithNativeSession(HibernateCallback action) { public <T> T executeWithNativeSession(HibernateCallback<T> action) {
return doExecute(action, false, true); return doExecute(action, false, true);
} }
/**
* Execute the action specified by the given action object within a Session.
* @param action callback object that specifies the Hibernate action
* @param enforceNativeSession whether to enforce exposure of the native
* Hibernate Session to callback code
* @return a result object returned by the action, or <code>null</code>
* @throws org.springframework.dao.DataAccessException in case of Hibernate errors
* @deprecated as of Spring 2.5, in favor of {@link #executeWithNativeSession}
*/
@Deprecated
public Object execute(HibernateCallback action, boolean enforceNativeSession) throws DataAccessException {
return doExecute(action, false, enforceNativeSession);
}
/** /**
* Execute the action specified by the given action object within a Session. * Execute the action specified by the given action object within a Session.
* @param action callback object that specifies the Hibernate action * @param action callback object that specifies the Hibernate action
@ -398,7 +384,7 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
* @return a result object returned by the action, or <code>null</code> * @return a result object returned by the action, or <code>null</code>
* @throws org.springframework.dao.DataAccessException in case of Hibernate errors * @throws org.springframework.dao.DataAccessException in case of Hibernate errors
*/ */
protected Object doExecute(HibernateCallback action, boolean enforceNewSession, boolean enforceNativeSession) protected <T> T doExecute(HibernateCallback<T> action, boolean enforceNewSession, boolean enforceNativeSession)
throws DataAccessException { throws DataAccessException {
Assert.notNull(action, "Callback object must not be null"); Assert.notNull(action, "Callback object must not be null");
@ -417,7 +403,7 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
enableFilters(session); enableFilters(session);
Session sessionToExpose = Session sessionToExpose =
(enforceNativeSession || isExposeNativeSession() ? session : createSessionProxy(session)); (enforceNativeSession || isExposeNativeSession() ? session : createSessionProxy(session));
Object result = action.doInHibernate(sessionToExpose); T result = action.doInHibernate(sessionToExpose);
flushIfNecessary(session, existingTransaction); flushIfNecessary(session, existingTransaction);
return result; return result;
} }
@ -520,17 +506,17 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
return get(entityClass, id, null); return get(entityClass, id, null);
} }
@SuppressWarnings("unchecked")
public <T> T get(final Class<T> entityClass, final Serializable id, final LockMode lockMode) public <T> T get(final Class<T> entityClass, final Serializable id, final LockMode lockMode)
throws DataAccessException { throws DataAccessException {
return (T) executeWithNativeSession(new HibernateCallback() { return executeWithNativeSession(new HibernateCallback<T>() {
public Object doInHibernate(Session session) throws HibernateException { @SuppressWarnings("unchecked")
public T doInHibernate(Session session) throws HibernateException {
if (lockMode != null) { if (lockMode != null) {
return session.get(entityClass, id, lockMode); return (T) session.get(entityClass, id, lockMode);
} }
else { else {
return session.get(entityClass, id); return (T) session.get(entityClass, id);
} }
} }
}); });
@ -543,7 +529,7 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
public Object get(final String entityName, final Serializable id, final LockMode lockMode) public Object get(final String entityName, final Serializable id, final LockMode lockMode)
throws DataAccessException { throws DataAccessException {
return executeWithNativeSession(new HibernateCallback() { return executeWithNativeSession(new HibernateCallback<Object>() {
public Object doInHibernate(Session session) throws HibernateException { public Object doInHibernate(Session session) throws HibernateException {
if (lockMode != null) { if (lockMode != null) {
return session.get(entityName, id, lockMode); return session.get(entityName, id, lockMode);
@ -559,17 +545,17 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
return load(entityClass, id, null); return load(entityClass, id, null);
} }
@SuppressWarnings("unchecked")
public <T> T load(final Class<T> entityClass, final Serializable id, final LockMode lockMode) public <T> T load(final Class<T> entityClass, final Serializable id, final LockMode lockMode)
throws DataAccessException { throws DataAccessException {
return (T) executeWithNativeSession(new HibernateCallback() { return executeWithNativeSession(new HibernateCallback<T>() {
public Object doInHibernate(Session session) throws HibernateException { @SuppressWarnings("unchecked")
public T doInHibernate(Session session) throws HibernateException {
if (lockMode != null) { if (lockMode != null) {
return session.load(entityClass, id, lockMode); return (T) session.load(entityClass, id, lockMode);
} }
else { else {
return session.load(entityClass, id); return (T) session.load(entityClass, id);
} }
} }
}); });
@ -582,7 +568,7 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
public Object load(final String entityName, final Serializable id, final LockMode lockMode) public Object load(final String entityName, final Serializable id, final LockMode lockMode)
throws DataAccessException { throws DataAccessException {
return executeWithNativeSession(new HibernateCallback() { return executeWithNativeSession(new HibernateCallback<Object>() {
public Object doInHibernate(Session session) throws HibernateException { public Object doInHibernate(Session session) throws HibernateException {
if (lockMode != null) { if (lockMode != null) {
return session.load(entityName, id, lockMode); return session.load(entityName, id, lockMode);
@ -594,10 +580,10 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
}); });
} }
@SuppressWarnings("unchecked")
public <T> List<T> loadAll(final Class<T> entityClass) throws DataAccessException { public <T> List<T> loadAll(final Class<T> entityClass) throws DataAccessException {
return (List<T>) executeWithNativeSession(new HibernateCallback() { return executeWithNativeSession(new HibernateCallback<List<T>>() {
public Object doInHibernate(Session session) throws HibernateException { @SuppressWarnings("unchecked")
public List<T> doInHibernate(Session session) throws HibernateException {
Criteria criteria = session.createCriteria(entityClass); Criteria criteria = session.createCriteria(entityClass);
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
prepareCriteria(criteria); prepareCriteria(criteria);
@ -607,7 +593,7 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
} }
public void load(final Object entity, final Serializable id) throws DataAccessException { public void load(final Object entity, final Serializable id) throws DataAccessException {
executeWithNativeSession(new HibernateCallback() { executeWithNativeSession(new HibernateCallback<Object>() {
public Object doInHibernate(Session session) throws HibernateException { public Object doInHibernate(Session session) throws HibernateException {
session.load(entity, id); session.load(entity, id);
return null; return null;
@ -620,7 +606,7 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
} }
public void refresh(final Object entity, final LockMode lockMode) throws DataAccessException { public void refresh(final Object entity, final LockMode lockMode) throws DataAccessException {
executeWithNativeSession(new HibernateCallback() { executeWithNativeSession(new HibernateCallback<Object>() {
public Object doInHibernate(Session session) throws HibernateException { public Object doInHibernate(Session session) throws HibernateException {
if (lockMode != null) { if (lockMode != null) {
session.refresh(entity, lockMode); session.refresh(entity, lockMode);
@ -634,15 +620,15 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
} }
public boolean contains(final Object entity) throws DataAccessException { public boolean contains(final Object entity) throws DataAccessException {
return (Boolean) executeWithNativeSession(new HibernateCallback() { return executeWithNativeSession(new HibernateCallback<Boolean>() {
public Object doInHibernate(Session session) { public Boolean doInHibernate(Session session) {
return session.contains(entity); return session.contains(entity);
} }
}); });
} }
public void evict(final Object entity) throws DataAccessException { public void evict(final Object entity) throws DataAccessException {
executeWithNativeSession(new HibernateCallback() { executeWithNativeSession(new HibernateCallback<Object>() {
public Object doInHibernate(Session session) throws HibernateException { public Object doInHibernate(Session session) throws HibernateException {
session.evict(entity); session.evict(entity);
return null; return null;
@ -674,7 +660,7 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
public void lock(final Object entity, final LockMode lockMode) throws DataAccessException { public void lock(final Object entity, final LockMode lockMode) throws DataAccessException {
executeWithNativeSession(new HibernateCallback() { executeWithNativeSession(new HibernateCallback<Object>() {
public Object doInHibernate(Session session) throws HibernateException { public Object doInHibernate(Session session) throws HibernateException {
session.lock(entity, lockMode); session.lock(entity, lockMode);
return null; return null;
@ -685,7 +671,7 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
public void lock(final String entityName, final Object entity, final LockMode lockMode) public void lock(final String entityName, final Object entity, final LockMode lockMode)
throws DataAccessException { throws DataAccessException {
executeWithNativeSession(new HibernateCallback() { executeWithNativeSession(new HibernateCallback<Object>() {
public Object doInHibernate(Session session) throws HibernateException { public Object doInHibernate(Session session) throws HibernateException {
session.lock(entityName, entity, lockMode); session.lock(entityName, entity, lockMode);
return null; return null;
@ -694,8 +680,8 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
} }
public Serializable save(final Object entity) throws DataAccessException { public Serializable save(final Object entity) throws DataAccessException {
return (Serializable) executeWithNativeSession(new HibernateCallback() { return executeWithNativeSession(new HibernateCallback<Serializable>() {
public Object doInHibernate(Session session) throws HibernateException { public Serializable doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session); checkWriteOperationAllowed(session);
return session.save(entity); return session.save(entity);
} }
@ -703,8 +689,8 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
} }
public Serializable save(final String entityName, final Object entity) throws DataAccessException { public Serializable save(final String entityName, final Object entity) throws DataAccessException {
return (Serializable) executeWithNativeSession(new HibernateCallback() { return executeWithNativeSession(new HibernateCallback<Serializable>() {
public Object doInHibernate(Session session) throws HibernateException { public Serializable doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session); checkWriteOperationAllowed(session);
return session.save(entityName, entity); return session.save(entityName, entity);
} }
@ -716,7 +702,7 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
} }
public void update(final Object entity, final LockMode lockMode) throws DataAccessException { public void update(final Object entity, final LockMode lockMode) throws DataAccessException {
executeWithNativeSession(new HibernateCallback() { executeWithNativeSession(new HibernateCallback<Object>() {
public Object doInHibernate(Session session) throws HibernateException { public Object doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session); checkWriteOperationAllowed(session);
session.update(entity); session.update(entity);
@ -735,7 +721,7 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
public void update(final String entityName, final Object entity, final LockMode lockMode) public void update(final String entityName, final Object entity, final LockMode lockMode)
throws DataAccessException { throws DataAccessException {
executeWithNativeSession(new HibernateCallback() { executeWithNativeSession(new HibernateCallback<Object>() {
public Object doInHibernate(Session session) throws HibernateException { public Object doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session); checkWriteOperationAllowed(session);
session.update(entityName, entity); session.update(entityName, entity);
@ -748,7 +734,7 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
} }
public void saveOrUpdate(final Object entity) throws DataAccessException { public void saveOrUpdate(final Object entity) throws DataAccessException {
executeWithNativeSession(new HibernateCallback() { executeWithNativeSession(new HibernateCallback<Object>() {
public Object doInHibernate(Session session) throws HibernateException { public Object doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session); checkWriteOperationAllowed(session);
session.saveOrUpdate(entity); session.saveOrUpdate(entity);
@ -758,7 +744,7 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
} }
public void saveOrUpdate(final String entityName, final Object entity) throws DataAccessException { public void saveOrUpdate(final String entityName, final Object entity) throws DataAccessException {
executeWithNativeSession(new HibernateCallback() { executeWithNativeSession(new HibernateCallback<Object>() {
public Object doInHibernate(Session session) throws HibernateException { public Object doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session); checkWriteOperationAllowed(session);
session.saveOrUpdate(entityName, entity); session.saveOrUpdate(entityName, entity);
@ -768,7 +754,7 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
} }
public void saveOrUpdateAll(final Collection entities) throws DataAccessException { public void saveOrUpdateAll(final Collection entities) throws DataAccessException {
executeWithNativeSession(new HibernateCallback() { executeWithNativeSession(new HibernateCallback<Object>() {
public Object doInHibernate(Session session) throws HibernateException { public Object doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session); checkWriteOperationAllowed(session);
for (Object entity : entities) { for (Object entity : entities) {
@ -782,7 +768,7 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
public void replicate(final Object entity, final ReplicationMode replicationMode) public void replicate(final Object entity, final ReplicationMode replicationMode)
throws DataAccessException { throws DataAccessException {
executeWithNativeSession(new HibernateCallback() { executeWithNativeSession(new HibernateCallback<Object>() {
public Object doInHibernate(Session session) throws HibernateException { public Object doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session); checkWriteOperationAllowed(session);
session.replicate(entity, replicationMode); session.replicate(entity, replicationMode);
@ -794,7 +780,7 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
public void replicate(final String entityName, final Object entity, final ReplicationMode replicationMode) public void replicate(final String entityName, final Object entity, final ReplicationMode replicationMode)
throws DataAccessException { throws DataAccessException {
executeWithNativeSession(new HibernateCallback() { executeWithNativeSession(new HibernateCallback<Object>() {
public Object doInHibernate(Session session) throws HibernateException { public Object doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session); checkWriteOperationAllowed(session);
session.replicate(entityName, entity, replicationMode); session.replicate(entityName, entity, replicationMode);
@ -804,7 +790,7 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
} }
public void persist(final Object entity) throws DataAccessException { public void persist(final Object entity) throws DataAccessException {
executeWithNativeSession(new HibernateCallback() { executeWithNativeSession(new HibernateCallback<Object>() {
public Object doInHibernate(Session session) throws HibernateException { public Object doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session); checkWriteOperationAllowed(session);
session.persist(entity); session.persist(entity);
@ -814,7 +800,7 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
} }
public void persist(final String entityName, final Object entity) throws DataAccessException { public void persist(final String entityName, final Object entity) throws DataAccessException {
executeWithNativeSession(new HibernateCallback() { executeWithNativeSession(new HibernateCallback<Object>() {
public Object doInHibernate(Session session) throws HibernateException { public Object doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session); checkWriteOperationAllowed(session);
session.persist(entityName, entity); session.persist(entityName, entity);
@ -823,20 +809,22 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
}); });
} }
public Object merge(final Object entity) throws DataAccessException { public <T> T merge(final T entity) throws DataAccessException {
return executeWithNativeSession(new HibernateCallback() { return executeWithNativeSession(new HibernateCallback<T>() {
public Object doInHibernate(Session session) throws HibernateException { @SuppressWarnings("unchecked")
public T doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session); checkWriteOperationAllowed(session);
return session.merge(entity); return (T) session.merge(entity);
} }
}); });
} }
public Object merge(final String entityName, final Object entity) throws DataAccessException { public <T> T merge(final String entityName, final T entity) throws DataAccessException {
return executeWithNativeSession(new HibernateCallback() { return executeWithNativeSession(new HibernateCallback<T>() {
public Object doInHibernate(Session session) throws HibernateException { @SuppressWarnings("unchecked")
public T doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session); checkWriteOperationAllowed(session);
return session.merge(entityName, entity); return (T) session.merge(entityName, entity);
} }
}); });
} }
@ -846,7 +834,7 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
} }
public void delete(final Object entity, final LockMode lockMode) throws DataAccessException { public void delete(final Object entity, final LockMode lockMode) throws DataAccessException {
executeWithNativeSession(new HibernateCallback() { executeWithNativeSession(new HibernateCallback<Object>() {
public Object doInHibernate(Session session) throws HibernateException { public Object doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session); checkWriteOperationAllowed(session);
if (lockMode != null) { if (lockMode != null) {
@ -865,7 +853,7 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
public void delete(final String entityName, final Object entity, final LockMode lockMode) public void delete(final String entityName, final Object entity, final LockMode lockMode)
throws DataAccessException { throws DataAccessException {
executeWithNativeSession(new HibernateCallback() { executeWithNativeSession(new HibernateCallback<Object>() {
public Object doInHibernate(Session session) throws HibernateException { public Object doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session); checkWriteOperationAllowed(session);
if (lockMode != null) { if (lockMode != null) {
@ -878,7 +866,7 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
} }
public void deleteAll(final Collection entities) throws DataAccessException { public void deleteAll(final Collection entities) throws DataAccessException {
executeWithNativeSession(new HibernateCallback() { executeWithNativeSession(new HibernateCallback<Object>() {
public Object doInHibernate(Session session) throws HibernateException { public Object doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session); checkWriteOperationAllowed(session);
for (Object entity : entities) { for (Object entity : entities) {
@ -890,7 +878,7 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
} }
public void flush() throws DataAccessException { public void flush() throws DataAccessException {
executeWithNativeSession(new HibernateCallback() { executeWithNativeSession(new HibernateCallback<Object>() {
public Object doInHibernate(Session session) throws HibernateException { public Object doInHibernate(Session session) throws HibernateException {
session.flush(); session.flush();
return null; return null;
@ -899,7 +887,7 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
} }
public void clear() throws DataAccessException { public void clear() throws DataAccessException {
executeWithNativeSession(new HibernateCallback() { executeWithNativeSession(new HibernateCallback<Object>() {
public Object doInHibernate(Session session) { public Object doInHibernate(Session session) {
session.clear(); session.clear();
return null; return null;
@ -921,8 +909,8 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
} }
public List find(final String queryString, final Object... values) throws DataAccessException { public List find(final String queryString, final Object... values) throws DataAccessException {
return (List) executeWithNativeSession(new HibernateCallback() { return executeWithNativeSession(new HibernateCallback<List>() {
public Object doInHibernate(Session session) throws HibernateException { public List doInHibernate(Session session) throws HibernateException {
Query queryObject = session.createQuery(queryString); Query queryObject = session.createQuery(queryString);
prepareQuery(queryObject); prepareQuery(queryObject);
if (values != null) { if (values != null) {
@ -947,8 +935,8 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
if (paramNames.length != values.length) { if (paramNames.length != values.length) {
throw new IllegalArgumentException("Length of paramNames array must match length of values array"); throw new IllegalArgumentException("Length of paramNames array must match length of values array");
} }
return (List) executeWithNativeSession(new HibernateCallback() { return executeWithNativeSession(new HibernateCallback<List>() {
public Object doInHibernate(Session session) throws HibernateException { public List doInHibernate(Session session) throws HibernateException {
Query queryObject = session.createQuery(queryString); Query queryObject = session.createQuery(queryString);
prepareQuery(queryObject); prepareQuery(queryObject);
if (values != null) { if (values != null) {
@ -964,8 +952,8 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
public List findByValueBean(final String queryString, final Object valueBean) public List findByValueBean(final String queryString, final Object valueBean)
throws DataAccessException { throws DataAccessException {
return (List) executeWithNativeSession(new HibernateCallback() { return executeWithNativeSession(new HibernateCallback<List>() {
public Object doInHibernate(Session session) throws HibernateException { public List doInHibernate(Session session) throws HibernateException {
Query queryObject = session.createQuery(queryString); Query queryObject = session.createQuery(queryString);
prepareQuery(queryObject); prepareQuery(queryObject);
queryObject.setProperties(valueBean); queryObject.setProperties(valueBean);
@ -988,8 +976,8 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
} }
public List findByNamedQuery(final String queryName, final Object... values) throws DataAccessException { public List findByNamedQuery(final String queryName, final Object... values) throws DataAccessException {
return (List) executeWithNativeSession(new HibernateCallback() { return executeWithNativeSession(new HibernateCallback<List>() {
public Object doInHibernate(Session session) throws HibernateException { public List doInHibernate(Session session) throws HibernateException {
Query queryObject = session.getNamedQuery(queryName); Query queryObject = session.getNamedQuery(queryName);
prepareQuery(queryObject); prepareQuery(queryObject);
if (values != null) { if (values != null) {
@ -1015,8 +1003,8 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
if (paramNames != null && values != null && paramNames.length != values.length) { if (paramNames != null && values != null && paramNames.length != values.length) {
throw new IllegalArgumentException("Length of paramNames array must match length of values array"); throw new IllegalArgumentException("Length of paramNames array must match length of values array");
} }
return (List) executeWithNativeSession(new HibernateCallback() { return executeWithNativeSession(new HibernateCallback<List>() {
public Object doInHibernate(Session session) throws HibernateException { public List doInHibernate(Session session) throws HibernateException {
Query queryObject = session.getNamedQuery(queryName); Query queryObject = session.getNamedQuery(queryName);
prepareQuery(queryObject); prepareQuery(queryObject);
if (values != null) { if (values != null) {
@ -1032,8 +1020,8 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
public List findByNamedQueryAndValueBean(final String queryName, final Object valueBean) public List findByNamedQueryAndValueBean(final String queryName, final Object valueBean)
throws DataAccessException { throws DataAccessException {
return (List) executeWithNativeSession(new HibernateCallback() { return executeWithNativeSession(new HibernateCallback<List>() {
public Object doInHibernate(Session session) throws HibernateException { public List doInHibernate(Session session) throws HibernateException {
Query queryObject = session.getNamedQuery(queryName); Query queryObject = session.getNamedQuery(queryName);
prepareQuery(queryObject); prepareQuery(queryObject);
queryObject.setProperties(valueBean); queryObject.setProperties(valueBean);
@ -1055,8 +1043,8 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
throws DataAccessException { throws DataAccessException {
Assert.notNull(criteria, "DetachedCriteria must not be null"); Assert.notNull(criteria, "DetachedCriteria must not be null");
return (List) executeWithNativeSession(new HibernateCallback() { return executeWithNativeSession(new HibernateCallback<List>() {
public Object doInHibernate(Session session) throws HibernateException { public List doInHibernate(Session session) throws HibernateException {
Criteria executableCriteria = criteria.getExecutableCriteria(session); Criteria executableCriteria = criteria.getExecutableCriteria(session);
prepareCriteria(executableCriteria); prepareCriteria(executableCriteria);
if (firstResult >= 0) { if (firstResult >= 0) {
@ -1087,8 +1075,8 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
throws DataAccessException { throws DataAccessException {
Assert.notNull(exampleEntity, "Example entity must not be null"); Assert.notNull(exampleEntity, "Example entity must not be null");
return (List) executeWithNativeSession(new HibernateCallback() { return executeWithNativeSession(new HibernateCallback<List>() {
public Object doInHibernate(Session session) throws HibernateException { public List doInHibernate(Session session) throws HibernateException {
Criteria executableCriteria = (entityName != null ? Criteria executableCriteria = (entityName != null ?
session.createCriteria(entityName) : session.createCriteria(exampleEntity.getClass())); session.createCriteria(entityName) : session.createCriteria(exampleEntity.getClass()));
executableCriteria.add(Example.create(exampleEntity)); executableCriteria.add(Example.create(exampleEntity));
@ -1118,8 +1106,8 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
} }
public Iterator iterate(final String queryString, final Object... values) throws DataAccessException { public Iterator iterate(final String queryString, final Object... values) throws DataAccessException {
return (Iterator) executeWithNativeSession(new HibernateCallback() { return executeWithNativeSession(new HibernateCallback<Iterator>() {
public Object doInHibernate(Session session) throws HibernateException { public Iterator doInHibernate(Session session) throws HibernateException {
Query queryObject = session.createQuery(queryString); Query queryObject = session.createQuery(queryString);
prepareQuery(queryObject); prepareQuery(queryObject);
if (values != null) { if (values != null) {
@ -1150,8 +1138,8 @@ public class HibernateTemplate extends HibernateAccessor implements HibernateOpe
} }
public int bulkUpdate(final String queryString, final Object... values) throws DataAccessException { public int bulkUpdate(final String queryString, final Object... values) throws DataAccessException {
return (Integer) executeWithNativeSession(new HibernateCallback() { return executeWithNativeSession(new HibernateCallback<Integer>() {
public Object doInHibernate(Session session) throws HibernateException { public Integer doInHibernate(Session session) throws HibernateException {
Query queryObject = session.createQuery(queryString); Query queryObject = session.createQuery(queryString);
prepareQuery(queryObject); prepareQuery(queryObject);
if (values != null) { if (values != null) {

View File

@ -360,7 +360,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
throw new IllegalStateException("Cannot get entity interceptor via bean name if no bean factory set"); throw new IllegalStateException("Cannot get entity interceptor via bean name if no bean factory set");
} }
String beanName = (String) this.entityInterceptor; String beanName = (String) this.entityInterceptor;
return (Interceptor) this.beanFactory.getBean(beanName, Interceptor.class); return this.beanFactory.getBean(beanName, Interceptor.class);
} }
else { else {
return null; return null;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2008 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,7 +17,6 @@
package org.springframework.orm.hibernate3.support; package org.springframework.orm.hibernate3.support;
import java.io.IOException; import java.io.IOException;
import javax.servlet.FilterChain; import javax.servlet.FilterChain;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -239,9 +238,8 @@ public class OpenSessionInViewFilter extends OncePerRequestFilter {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Using SessionFactory '" + getSessionFactoryBeanName() + "' for OpenSessionInViewFilter"); logger.debug("Using SessionFactory '" + getSessionFactoryBeanName() + "' for OpenSessionInViewFilter");
} }
WebApplicationContext wac = WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()); return wac.getBean(getSessionFactoryBeanName(), SessionFactory.class);
return (SessionFactory) wac.getBean(getSessionFactoryBeanName(), SessionFactory.class);
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2008 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -20,7 +20,6 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.Properties; import java.util.Properties;
import javax.sql.DataSource; import javax.sql.DataSource;
import com.ibatis.common.xml.NodeletException; import com.ibatis.common.xml.NodeletException;
@ -68,7 +67,7 @@ import org.springframework.util.ObjectUtils;
* @see SqlMapClientTemplate#setSqlMapClient * @see SqlMapClientTemplate#setSqlMapClient
* @see SqlMapClientTemplate#setDataSource * @see SqlMapClientTemplate#setDataSource
*/ */
public class SqlMapClientFactoryBean implements FactoryBean, InitializingBean { public class SqlMapClientFactoryBean implements FactoryBean<SqlMapClient>, InitializingBean {
private static final ThreadLocal configTimeLobHandlerHolder = new ThreadLocal(); private static final ThreadLocal configTimeLobHandlerHolder = new ThreadLocal();
@ -333,24 +332,24 @@ public class SqlMapClientFactoryBean implements FactoryBean, InitializingBean {
SqlMapClient client = null; SqlMapClient client = null;
SqlMapConfigParser configParser = new SqlMapConfigParser(); SqlMapConfigParser configParser = new SqlMapConfigParser();
for (int i = 0; i < configLocations.length; i++) { for (Resource configLocation : configLocations) {
InputStream is = configLocations[i].getInputStream(); InputStream is = configLocation.getInputStream();
try { try {
client = configParser.parse(is, properties); client = configParser.parse(is, properties);
} }
catch (RuntimeException ex) { catch (RuntimeException ex) {
throw new NestedIOException("Failed to parse config resource: " + configLocations[i], ex.getCause()); throw new NestedIOException("Failed to parse config resource: " + configLocation, ex.getCause());
} }
} }
if (mappingLocations != null) { if (mappingLocations != null) {
SqlMapParser mapParser = SqlMapParserFactory.createSqlMapParser(configParser); SqlMapParser mapParser = SqlMapParserFactory.createSqlMapParser(configParser);
for (int i = 0; i < mappingLocations.length; i++) { for (Resource mappingLocation : mappingLocations) {
try { try {
mapParser.parse(mappingLocations[i].getInputStream()); mapParser.parse(mappingLocation.getInputStream());
} }
catch (NodeletException ex) { catch (NodeletException ex) {
throw new NestedIOException("Failed to parse mapping resource: " + mappingLocations[i], ex); throw new NestedIOException("Failed to parse mapping resource: " + mappingLocation, ex);
} }
} }
} }
@ -381,11 +380,11 @@ public class SqlMapClientFactoryBean implements FactoryBean, InitializingBean {
} }
public Object getObject() { public SqlMapClient getObject() {
return this.sqlMapClient; return this.sqlMapClient;
} }
public Class getObjectType() { public Class<? extends SqlMapClient> getObjectType() {
return (this.sqlMapClient != null ? this.sqlMapClient.getClass() : SqlMapClient.class); return (this.sqlMapClient != null ? this.sqlMapClient.getClass() : SqlMapClient.class);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2007 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -18,7 +18,6 @@ package org.springframework.orm.jdo;
import java.sql.Connection; import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
import javax.jdo.JDOException; import javax.jdo.JDOException;
import javax.jdo.PersistenceManager; import javax.jdo.PersistenceManager;
import javax.jdo.Query; import javax.jdo.Query;
@ -182,20 +181,13 @@ public class DefaultJdoDialect implements JdoDialect, PersistenceExceptionTransl
} }
/** /**
* This implementation delegates to JDO 2.0's <code>flush</code> method. * This implementation sets the JPA 2.0 query hints "javax.persistence.lock.timeout"
* <p>To be overridden for pre-JDO2 implementations, using the corresponding * and "javax.persistence.query.timeout", assuming that JDO 2.1 providers are often
* vendor-specific mechanism there. * JPA providers as well.
* @see javax.jdo.PersistenceManager#flush()
*/
public void flush(PersistenceManager pm) throws JDOException {
pm.flush();
}
/**
* This implementation logs a warning that it cannot apply a query timeout.
*/ */
public void applyQueryTimeout(Query query, int remainingTimeInSeconds) throws JDOException { public void applyQueryTimeout(Query query, int remainingTimeInSeconds) throws JDOException {
logger.info("DefaultJdoDialect does not support query timeouts: ignoring remaining transaction time"); query.addExtension("javax.persistence.lock.timeout", remainingTimeInSeconds);
query.addExtension("javax.persistence.query.timeout", remainingTimeInSeconds);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2006 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -73,7 +73,7 @@ public abstract class JdoAccessor implements InitializingBean {
* PersistenceManagers. * PersistenceManagers.
*/ */
public PersistenceManagerFactory getPersistenceManagerFactory() { public PersistenceManagerFactory getPersistenceManagerFactory() {
return persistenceManagerFactory; return this.persistenceManagerFactory;
} }
/** /**
@ -120,7 +120,7 @@ public abstract class JdoAccessor implements InitializingBean {
* Return if this accessor should flush changes to the database eagerly. * Return if this accessor should flush changes to the database eagerly.
*/ */
public boolean isFlushEager() { public boolean isFlushEager() {
return flushEager; return this.flushEager;
} }
/** /**
@ -129,7 +129,7 @@ public abstract class JdoAccessor implements InitializingBean {
*/ */
public void afterPropertiesSet() { public void afterPropertiesSet() {
if (getPersistenceManagerFactory() == null) { if (getPersistenceManagerFactory() == null) {
throw new IllegalArgumentException("persistenceManagerFactory is required"); throw new IllegalArgumentException("Property 'persistenceManagerFactory' is required");
} }
// Build default JdoDialect if none explicitly specified. // Build default JdoDialect if none explicitly specified.
if (this.jdoDialect == null) { if (this.jdoDialect == null) {
@ -148,7 +148,7 @@ public abstract class JdoAccessor implements InitializingBean {
protected void flushIfNecessary(PersistenceManager pm, boolean existingTransaction) throws JDOException { protected void flushIfNecessary(PersistenceManager pm, boolean existingTransaction) throws JDOException {
if (isFlushEager()) { if (isFlushEager()) {
logger.debug("Eagerly flushing JDO persistence manager"); logger.debug("Eagerly flushing JDO persistence manager");
getJdoDialect().flush(pm); pm.flush();
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2006 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -41,7 +41,7 @@ import javax.jdo.PersistenceManager;
* @see JdoTemplate * @see JdoTemplate
* @see JdoTransactionManager * @see JdoTransactionManager
*/ */
public interface JdoCallback { public interface JdoCallback<T> {
/** /**
* Gets called by <code>JdoTemplate.execute</code> with an active JDO * Gets called by <code>JdoTemplate.execute</code> with an active JDO
@ -64,6 +64,6 @@ public interface JdoCallback {
* @see JdoTemplate#execute * @see JdoTemplate#execute
* @see JdoTemplate#executeFind * @see JdoTemplate#executeFind
*/ */
Object doInJdo(PersistenceManager pm) throws JDOException; T doInJdo(PersistenceManager pm) throws JDOException;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2007 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,7 +17,6 @@
package org.springframework.orm.jdo; package org.springframework.orm.jdo;
import java.sql.SQLException; import java.sql.SQLException;
import javax.jdo.JDOException; import javax.jdo.JDOException;
import javax.jdo.PersistenceManager; import javax.jdo.PersistenceManager;
import javax.jdo.Query; import javax.jdo.Query;
@ -145,22 +144,11 @@ public interface JdoDialect {
void releaseJdbcConnection(ConnectionHandle conHandle, PersistenceManager pm) void releaseJdbcConnection(ConnectionHandle conHandle, PersistenceManager pm)
throws JDOException, SQLException; throws JDOException, SQLException;
/**
* Flush the given PersistenceManager, i.e. flush all changes (that have been
* applied to persistent objects) to the underlying database. This method will
* just get invoked when eager flushing is actually necessary, for example when
* JDBC access code needs to see changes within the same transaction.
* @param pm the current JDO PersistenceManager
* @throws JDOException in case of errors
* @see JdoAccessor#setFlushEager
*/
void flush(PersistenceManager pm) throws JDOException;
/** /**
* Apply the given timeout to the given JDO query object. * Apply the given timeout to the given JDO query object.
* <p>Invoked with the remaining time of a specified transaction timeout, if any. * <p>Invoked with the remaining time of a specified transaction timeout, if any.
* @param query the JDO query object to apply the timeout to * @param query the JDO query object to apply the timeout to
* @param timeout the timeout value to apply * @param timeout the timeout value (seconds) to apply
* @throws JDOException if thrown by JDO methods * @throws JDOException if thrown by JDO methods
* @see JdoTemplate#prepareQuery * @see JdoTemplate#prepareQuery
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2008 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -67,7 +67,7 @@ public interface JdoOperations {
* @see org.springframework.transaction * @see org.springframework.transaction
* @see javax.jdo.PersistenceManager * @see javax.jdo.PersistenceManager
*/ */
Object execute(JdoCallback action) throws DataAccessException; <T> T execute(JdoCallback<T> action) throws DataAccessException;
/** /**
* Execute the specified action assuming that the result object is a * Execute the specified action assuming that the result object is a
@ -77,7 +77,7 @@ public interface JdoOperations {
* @return a Collection result returned by the action, or <code>null</code> * @return a Collection result returned by the action, or <code>null</code>
* @throws org.springframework.dao.DataAccessException in case of JDO errors * @throws org.springframework.dao.DataAccessException in case of JDO errors
*/ */
Collection executeFind(JdoCallback action) throws DataAccessException; Collection executeFind(JdoCallback<?> action) throws DataAccessException;
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -113,7 +113,7 @@ public interface JdoOperations {
* @see javax.jdo.PersistenceManager#getObjectById(Object, boolean) * @see javax.jdo.PersistenceManager#getObjectById(Object, boolean)
* @see javax.jdo.PersistenceManager#getObjectById(Class, Object) * @see javax.jdo.PersistenceManager#getObjectById(Class, Object)
*/ */
Object getObjectById(Class entityClass, Object idValue) throws DataAccessException; <T> T getObjectById(Class<T> entityClass, Object idValue) throws DataAccessException;
/** /**
* Remove the given object from the PersistenceManager cache. * Remove the given object from the PersistenceManager cache.
@ -169,7 +169,7 @@ public interface JdoOperations {
* @throws org.springframework.dao.DataAccessException in case of JDO errors * @throws org.springframework.dao.DataAccessException in case of JDO errors
* @see javax.jdo.PersistenceManager#makePersistent(Object) * @see javax.jdo.PersistenceManager#makePersistent(Object)
*/ */
Object makePersistent(Object entity) throws DataAccessException; <T> T makePersistent(T entity) throws DataAccessException;
/** /**
* Make the given transient instances persistent. * Make the given transient instances persistent.
@ -179,7 +179,7 @@ public interface JdoOperations {
* @throws org.springframework.dao.DataAccessException in case of JDO errors * @throws org.springframework.dao.DataAccessException in case of JDO errors
* @see javax.jdo.PersistenceManager#makePersistentAll(java.util.Collection) * @see javax.jdo.PersistenceManager#makePersistentAll(java.util.Collection)
*/ */
Collection makePersistentAll(Collection entities) throws DataAccessException; <T> Collection<T> makePersistentAll(Collection<T> entities) throws DataAccessException;
/** /**
* Delete the given persistent instance. * Delete the given persistent instance.
@ -206,7 +206,7 @@ public interface JdoOperations {
* @return the corresponding detached instance * @return the corresponding detached instance
* @see javax.jdo.PersistenceManager#detachCopy(Object) * @see javax.jdo.PersistenceManager#detachCopy(Object)
*/ */
Object detachCopy(Object entity); <T> T detachCopy(T entity);
/** /**
* Detach copies of the given persistent instances from the current JDO transaction, * Detach copies of the given persistent instances from the current JDO transaction,
@ -215,7 +215,7 @@ public interface JdoOperations {
* @return the corresponding detached instances * @return the corresponding detached instances
* @see javax.jdo.PersistenceManager#detachCopyAll(Collection) * @see javax.jdo.PersistenceManager#detachCopyAll(Collection)
*/ */
Collection detachCopyAll(Collection entities); <T> Collection<T> detachCopyAll(Collection<T> entities);
/** /**
* Flush all transactional modifications to the database. * Flush all transactional modifications to the database.
@ -240,7 +240,7 @@ public interface JdoOperations {
* @throws org.springframework.dao.DataAccessException in case of JDO errors * @throws org.springframework.dao.DataAccessException in case of JDO errors
* @see javax.jdo.PersistenceManager#newQuery(Class) * @see javax.jdo.PersistenceManager#newQuery(Class)
*/ */
Collection find(Class entityClass) throws DataAccessException; <T> Collection<T> find(Class<T> entityClass) throws DataAccessException;
/** /**
* Find all persistent instances of the given class that match the given * Find all persistent instances of the given class that match the given
@ -251,7 +251,7 @@ public interface JdoOperations {
* @throws org.springframework.dao.DataAccessException in case of JDO errors * @throws org.springframework.dao.DataAccessException in case of JDO errors
* @see javax.jdo.PersistenceManager#newQuery(Class, String) * @see javax.jdo.PersistenceManager#newQuery(Class, String)
*/ */
Collection find(Class entityClass, String filter) throws DataAccessException; <T> Collection<T> find(Class<T> entityClass, String filter) throws DataAccessException;
/** /**
* Find all persistent instances of the given class that match the given * Find all persistent instances of the given class that match the given
@ -264,7 +264,7 @@ public interface JdoOperations {
* @see javax.jdo.PersistenceManager#newQuery(Class, String) * @see javax.jdo.PersistenceManager#newQuery(Class, String)
* @see javax.jdo.Query#setOrdering * @see javax.jdo.Query#setOrdering
*/ */
Collection find(Class entityClass, String filter, String ordering) throws DataAccessException; <T> Collection<T> find(Class<T> entityClass, String filter, String ordering) throws DataAccessException;
/** /**
* Find all persistent instances of the given class that match the given * Find all persistent instances of the given class that match the given
@ -279,7 +279,7 @@ public interface JdoOperations {
* @see javax.jdo.Query#declareParameters * @see javax.jdo.Query#declareParameters
* @see javax.jdo.Query#executeWithArray * @see javax.jdo.Query#executeWithArray
*/ */
Collection find(Class entityClass, String filter, String parameters, Object[] values) <T> Collection<T> find(Class<T> entityClass, String filter, String parameters, Object[] values)
throws DataAccessException; throws DataAccessException;
/** /**
@ -298,7 +298,7 @@ public interface JdoOperations {
* @see javax.jdo.Query#executeWithArray * @see javax.jdo.Query#executeWithArray
* @see javax.jdo.Query#setOrdering * @see javax.jdo.Query#setOrdering
*/ */
Collection find(Class entityClass, String filter, String parameters, Object[] values, String ordering) <T> Collection<T> find(Class<T> entityClass, String filter, String parameters, Object[] values, String ordering)
throws DataAccessException; throws DataAccessException;
/** /**
@ -314,7 +314,7 @@ public interface JdoOperations {
* @see javax.jdo.Query#declareParameters * @see javax.jdo.Query#declareParameters
* @see javax.jdo.Query#executeWithMap * @see javax.jdo.Query#executeWithMap
*/ */
Collection find(Class entityClass, String filter, String parameters, Map values) <T> Collection<T> find(Class<T> entityClass, String filter, String parameters, Map values)
throws DataAccessException; throws DataAccessException;
/** /**
@ -333,7 +333,7 @@ public interface JdoOperations {
* @see javax.jdo.Query#executeWithMap * @see javax.jdo.Query#executeWithMap
* @see javax.jdo.Query#setOrdering * @see javax.jdo.Query#setOrdering
*/ */
Collection find(Class entityClass, String filter, String parameters, Map values, String ordering) <T> Collection<T> find(Class<T> entityClass, String filter, String parameters, Map values, String ordering)
throws DataAccessException; throws DataAccessException;
/** /**
@ -387,7 +387,8 @@ public interface JdoOperations {
* @throws org.springframework.dao.DataAccessException in case of JDO errors * @throws org.springframework.dao.DataAccessException in case of JDO errors
* @see javax.jdo.PersistenceManager#newNamedQuery(Class, String) * @see javax.jdo.PersistenceManager#newNamedQuery(Class, String)
*/ */
Collection findByNamedQuery(Class entityClass, String queryName) throws DataAccessException; <T> Collection<T> findByNamedQuery(Class<T> entityClass, String queryName)
throws DataAccessException;
/** /**
* Find persistent instances through the given named query. * Find persistent instances through the given named query.
@ -398,7 +399,8 @@ public interface JdoOperations {
* @throws org.springframework.dao.DataAccessException in case of JDO errors * @throws org.springframework.dao.DataAccessException in case of JDO errors
* @see javax.jdo.PersistenceManager#newNamedQuery(Class, String) * @see javax.jdo.PersistenceManager#newNamedQuery(Class, String)
*/ */
Collection findByNamedQuery(Class entityClass, String queryName, Object[] values) throws DataAccessException; <T> Collection<T> findByNamedQuery(Class<T> entityClass, String queryName, Object[] values)
throws DataAccessException;
/** /**
* Find persistent instances through the given named query. * Find persistent instances through the given named query.
@ -409,6 +411,7 @@ public interface JdoOperations {
* @throws org.springframework.dao.DataAccessException in case of JDO errors * @throws org.springframework.dao.DataAccessException in case of JDO errors
* @see javax.jdo.PersistenceManager#newNamedQuery(Class, String) * @see javax.jdo.PersistenceManager#newNamedQuery(Class, String)
*/ */
Collection findByNamedQuery(Class entityClass, String queryName, Map values) throws DataAccessException; <T> Collection<T> findByNamedQuery(Class<T> entityClass, String queryName, Map values)
throws DataAccessException;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2008 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -22,7 +22,6 @@ import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
import javax.jdo.JDOException; import javax.jdo.JDOException;
import javax.jdo.PersistenceManager; import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory; import javax.jdo.PersistenceManagerFactory;
@ -77,6 +76,8 @@ import org.springframework.util.ClassUtils;
* for example: <code>evict</code>, <code>evictAll</code>, <code>flush</code>. * for example: <code>evict</code>, <code>evictAll</code>, <code>flush</code>.
* *
* <p><b>NOTE: This class requires JDO 2.0 or higher, as of Spring 2.5.</b> * <p><b>NOTE: This class requires JDO 2.0 or higher, as of Spring 2.5.</b>
* As of Spring 3.0, it follows JDO 2.1 conventions in terms of generic
* parameter and return types, which still remaining compatible with JDO 2.0.
* *
* @author Juergen Hoeller * @author Juergen Hoeller
* @since 03.06.2003 * @since 03.06.2003
@ -170,11 +171,11 @@ public class JdoTemplate extends JdoAccessor implements JdoOperations {
} }
public Object execute(JdoCallback action) throws DataAccessException { public <T> T execute(JdoCallback<T> action) throws DataAccessException {
return execute(action, isExposeNativePersistenceManager()); return execute(action, isExposeNativePersistenceManager());
} }
public Collection executeFind(JdoCallback action) throws DataAccessException { public Collection executeFind(JdoCallback<?> action) throws DataAccessException {
Object result = execute(action, isExposeNativePersistenceManager()); Object result = execute(action, isExposeNativePersistenceManager());
if (result != null && !(result instanceof Collection)) { if (result != null && !(result instanceof Collection)) {
throw new InvalidDataAccessApiUsageException( throw new InvalidDataAccessApiUsageException(
@ -192,7 +193,7 @@ public class JdoTemplate extends JdoAccessor implements JdoOperations {
* @return a result object returned by the action, or <code>null</code> * @return a result object returned by the action, or <code>null</code>
* @throws org.springframework.dao.DataAccessException in case of JDO errors * @throws org.springframework.dao.DataAccessException in case of JDO errors
*/ */
public Object execute(JdoCallback action, boolean exposeNativePersistenceManager) throws DataAccessException { public <T> T execute(JdoCallback<T> action, boolean exposeNativePersistenceManager) throws DataAccessException {
Assert.notNull(action, "Callback object must not be null"); Assert.notNull(action, "Callback object must not be null");
PersistenceManager pm = PersistenceManagerFactoryUtils.getPersistenceManager( PersistenceManager pm = PersistenceManagerFactoryUtils.getPersistenceManager(
@ -201,7 +202,7 @@ public class JdoTemplate extends JdoAccessor implements JdoOperations {
TransactionSynchronizationManager.hasResource(getPersistenceManagerFactory()); TransactionSynchronizationManager.hasResource(getPersistenceManagerFactory());
try { try {
PersistenceManager pmToExpose = (exposeNativePersistenceManager ? pm : createPersistenceManagerProxy(pm)); PersistenceManager pmToExpose = (exposeNativePersistenceManager ? pm : createPersistenceManagerProxy(pm));
Object result = action.doInJdo(pmToExpose); T result = action.doInJdo(pmToExpose);
flushIfNecessary(pm, existingTransaction); flushIfNecessary(pm, existingTransaction);
return postProcessResult(result, pm, existingTransaction); return postProcessResult(result, pm, existingTransaction);
} }
@ -248,7 +249,7 @@ public class JdoTemplate extends JdoAccessor implements JdoOperations {
* @return the post-processed result object (can be simply be the passed-in object) * @return the post-processed result object (can be simply be the passed-in object)
* @see #execute(JdoCallback, boolean) * @see #execute(JdoCallback, boolean)
*/ */
protected Object postProcessResult(Object result, PersistenceManager pm, boolean existingTransaction) { protected <T> T postProcessResult(T result, PersistenceManager pm, boolean existingTransaction) {
return result; return result;
} }
@ -258,23 +259,23 @@ public class JdoTemplate extends JdoAccessor implements JdoOperations {
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
public Object getObjectById(final Object objectId) throws DataAccessException { public Object getObjectById(final Object objectId) throws DataAccessException {
return execute(new JdoCallback() { return execute(new JdoCallback<Object>() {
public Object doInJdo(PersistenceManager pm) throws JDOException { public Object doInJdo(PersistenceManager pm) throws JDOException {
return pm.getObjectById(objectId, true); return pm.getObjectById(objectId, true);
} }
}, true); }, true);
} }
public Object getObjectById(final Class entityClass, final Object idValue) throws DataAccessException { public <T> T getObjectById(final Class<T> entityClass, final Object idValue) throws DataAccessException {
return execute(new JdoCallback() { return execute(new JdoCallback<T>() {
public Object doInJdo(PersistenceManager pm) throws JDOException { public T doInJdo(PersistenceManager pm) throws JDOException {
return pm.getObjectById(entityClass, idValue); return pm.getObjectById(entityClass, idValue);
} }
}, true); }, true);
} }
public void evict(final Object entity) throws DataAccessException { public void evict(final Object entity) throws DataAccessException {
execute(new JdoCallback() { execute(new JdoCallback<Object>() {
public Object doInJdo(PersistenceManager pm) throws JDOException { public Object doInJdo(PersistenceManager pm) throws JDOException {
pm.evict(entity); pm.evict(entity);
return null; return null;
@ -283,7 +284,7 @@ public class JdoTemplate extends JdoAccessor implements JdoOperations {
} }
public void evictAll(final Collection entities) throws DataAccessException { public void evictAll(final Collection entities) throws DataAccessException {
execute(new JdoCallback() { execute(new JdoCallback<Object>() {
public Object doInJdo(PersistenceManager pm) throws JDOException { public Object doInJdo(PersistenceManager pm) throws JDOException {
pm.evictAll(entities); pm.evictAll(entities);
return null; return null;
@ -292,7 +293,7 @@ public class JdoTemplate extends JdoAccessor implements JdoOperations {
} }
public void evictAll() throws DataAccessException { public void evictAll() throws DataAccessException {
execute(new JdoCallback() { execute(new JdoCallback<Object>() {
public Object doInJdo(PersistenceManager pm) throws JDOException { public Object doInJdo(PersistenceManager pm) throws JDOException {
pm.evictAll(); pm.evictAll();
return null; return null;
@ -301,7 +302,7 @@ public class JdoTemplate extends JdoAccessor implements JdoOperations {
} }
public void refresh(final Object entity) throws DataAccessException { public void refresh(final Object entity) throws DataAccessException {
execute(new JdoCallback() { execute(new JdoCallback<Object>() {
public Object doInJdo(PersistenceManager pm) throws JDOException { public Object doInJdo(PersistenceManager pm) throws JDOException {
pm.refresh(entity); pm.refresh(entity);
return null; return null;
@ -310,7 +311,7 @@ public class JdoTemplate extends JdoAccessor implements JdoOperations {
} }
public void refreshAll(final Collection entities) throws DataAccessException { public void refreshAll(final Collection entities) throws DataAccessException {
execute(new JdoCallback() { execute(new JdoCallback<Object>() {
public Object doInJdo(PersistenceManager pm) throws JDOException { public Object doInJdo(PersistenceManager pm) throws JDOException {
pm.refreshAll(entities); pm.refreshAll(entities);
return null; return null;
@ -319,7 +320,7 @@ public class JdoTemplate extends JdoAccessor implements JdoOperations {
} }
public void refreshAll() throws DataAccessException { public void refreshAll() throws DataAccessException {
execute(new JdoCallback() { execute(new JdoCallback<Object>() {
public Object doInJdo(PersistenceManager pm) throws JDOException { public Object doInJdo(PersistenceManager pm) throws JDOException {
pm.refreshAll(); pm.refreshAll();
return null; return null;
@ -327,24 +328,24 @@ public class JdoTemplate extends JdoAccessor implements JdoOperations {
}, true); }, true);
} }
public Object makePersistent(final Object entity) throws DataAccessException { public <T> T makePersistent(final T entity) throws DataAccessException {
return execute(new JdoCallback() { return execute(new JdoCallback<T>() {
public Object doInJdo(PersistenceManager pm) throws JDOException { public T doInJdo(PersistenceManager pm) throws JDOException {
return pm.makePersistent(entity); return pm.makePersistent(entity);
} }
}, true); }, true);
} }
public Collection makePersistentAll(final Collection entities) throws DataAccessException { public <T> Collection<T> makePersistentAll(final Collection<T> entities) throws DataAccessException {
return (Collection) execute(new JdoCallback() { return execute(new JdoCallback<Collection<T>>() {
public Object doInJdo(PersistenceManager pm) throws JDOException { public Collection<T> doInJdo(PersistenceManager pm) throws JDOException {
return pm.makePersistentAll(entities); return pm.makePersistentAll(entities);
} }
}, true); }, true);
} }
public void deletePersistent(final Object entity) throws DataAccessException { public void deletePersistent(final Object entity) throws DataAccessException {
execute(new JdoCallback() { execute(new JdoCallback<Object>() {
public Object doInJdo(PersistenceManager pm) throws JDOException { public Object doInJdo(PersistenceManager pm) throws JDOException {
pm.deletePersistent(entity); pm.deletePersistent(entity);
return null; return null;
@ -353,7 +354,7 @@ public class JdoTemplate extends JdoAccessor implements JdoOperations {
} }
public void deletePersistentAll(final Collection entities) throws DataAccessException { public void deletePersistentAll(final Collection entities) throws DataAccessException {
execute(new JdoCallback() { execute(new JdoCallback<Object>() {
public Object doInJdo(PersistenceManager pm) throws JDOException { public Object doInJdo(PersistenceManager pm) throws JDOException {
pm.deletePersistentAll(entities); pm.deletePersistentAll(entities);
return null; return null;
@ -361,26 +362,26 @@ public class JdoTemplate extends JdoAccessor implements JdoOperations {
}, true); }, true);
} }
public Object detachCopy(final Object entity) { public <T> T detachCopy(final T entity) {
return execute(new JdoCallback() { return execute(new JdoCallback<T>() {
public Object doInJdo(PersistenceManager pm) throws JDOException { public T doInJdo(PersistenceManager pm) throws JDOException {
return pm.detachCopy(entity); return pm.detachCopy(entity);
} }
}, true); }, true);
} }
public Collection detachCopyAll(final Collection entities) { public <T> Collection<T> detachCopyAll(final Collection<T> entities) {
return (Collection) execute(new JdoCallback() { return execute(new JdoCallback<Collection<T>>() {
public Object doInJdo(PersistenceManager pm) throws JDOException { public Collection<T> doInJdo(PersistenceManager pm) throws JDOException {
return pm.detachCopyAll(entities); return pm.detachCopyAll(entities);
} }
}, true); }, true);
} }
public void flush() throws DataAccessException { public void flush() throws DataAccessException {
execute(new JdoCallback() { execute(new JdoCallback<Object>() {
public Object doInJdo(PersistenceManager pm) throws JDOException { public Object doInJdo(PersistenceManager pm) throws JDOException {
getJdoDialect().flush(pm); pm.flush();
return null; return null;
} }
}, true); }, true);
@ -391,145 +392,154 @@ public class JdoTemplate extends JdoAccessor implements JdoOperations {
// Convenience finder methods // Convenience finder methods
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
public Collection find(Class entityClass) throws DataAccessException { public <T> Collection<T> find(Class<T> entityClass) throws DataAccessException {
return find(entityClass, null, null); return find(entityClass, null, null);
} }
public Collection find(Class entityClass, String filter) throws DataAccessException { public <T> Collection<T> find(Class<T> entityClass, String filter) throws DataAccessException {
return find(entityClass, filter, null); return find(entityClass, filter, null);
} }
public Collection find(final Class entityClass, final String filter, final String ordering) public <T> Collection<T> find(final Class<T> entityClass, final String filter, final String ordering)
throws DataAccessException { throws DataAccessException {
return (Collection) execute(new JdoCallback() { return execute(new JdoCallback<Collection<T>>() {
public Object doInJdo(PersistenceManager pm) throws JDOException { @SuppressWarnings("unchecked")
public Collection<T> doInJdo(PersistenceManager pm) throws JDOException {
Query query = (filter != null ? pm.newQuery(entityClass, filter) : pm.newQuery(entityClass)); Query query = (filter != null ? pm.newQuery(entityClass, filter) : pm.newQuery(entityClass));
prepareQuery(query); prepareQuery(query);
if (ordering != null) { if (ordering != null) {
query.setOrdering(ordering); query.setOrdering(ordering);
} }
return query.execute(); return (Collection<T>) query.execute();
} }
}, true); }, true);
} }
public Collection find(Class entityClass, String filter, String parameters, Object[] values) public <T> Collection<T> find(Class<T> entityClass, String filter, String parameters, Object... values)
throws DataAccessException { throws DataAccessException {
return find(entityClass, filter, parameters, values, null); return find(entityClass, filter, parameters, values, null);
} }
public Collection find( public <T> Collection<T> find(
final Class entityClass, final String filter, final String parameters, final Object[] values, final Class<T> entityClass, final String filter, final String parameters, final Object[] values,
final String ordering) throws DataAccessException { final String ordering) throws DataAccessException {
return (Collection) execute(new JdoCallback() { return execute(new JdoCallback<Collection<T>>() {
public Object doInJdo(PersistenceManager pm) throws JDOException { @SuppressWarnings("unchecked")
public Collection<T> doInJdo(PersistenceManager pm) throws JDOException {
Query query = pm.newQuery(entityClass, filter); Query query = pm.newQuery(entityClass, filter);
prepareQuery(query); prepareQuery(query);
query.declareParameters(parameters); query.declareParameters(parameters);
if (ordering != null) { if (ordering != null) {
query.setOrdering(ordering); query.setOrdering(ordering);
} }
return query.executeWithArray(values); return (Collection<T>) query.executeWithArray(values);
} }
}, true); }, true);
} }
public Collection find(Class entityClass, String filter, String parameters, Map values) public <T> Collection<T> find(Class<T> entityClass, String filter, String parameters, Map values)
throws DataAccessException { throws DataAccessException {
return find(entityClass, filter, parameters, values, null); return find(entityClass, filter, parameters, values, null);
} }
public Collection find( public <T> Collection<T> find(
final Class entityClass, final String filter, final String parameters, final Map values, final Class<T> entityClass, final String filter, final String parameters, final Map values,
final String ordering) throws DataAccessException { final String ordering) throws DataAccessException {
return (Collection) execute(new JdoCallback() { return execute(new JdoCallback<Collection<T>>() {
public Object doInJdo(PersistenceManager pm) throws JDOException { @SuppressWarnings("unchecked")
public Collection<T> doInJdo(PersistenceManager pm) throws JDOException {
Query query = pm.newQuery(entityClass, filter); Query query = pm.newQuery(entityClass, filter);
prepareQuery(query); prepareQuery(query);
query.declareParameters(parameters); query.declareParameters(parameters);
if (ordering != null) { if (ordering != null) {
query.setOrdering(ordering); query.setOrdering(ordering);
} }
return query.executeWithMap(values); return (Collection<T>) query.executeWithMap(values);
} }
}, true); }, true);
} }
public Collection find(final String language, final Object queryObject) throws DataAccessException { public Collection find(final String language, final Object queryObject) throws DataAccessException {
return (Collection) execute(new JdoCallback() { return execute(new JdoCallback<Collection>() {
public Object doInJdo(PersistenceManager pm) throws JDOException { public Collection doInJdo(PersistenceManager pm) throws JDOException {
Query query = pm.newQuery(language, queryObject); Query query = pm.newQuery(language, queryObject);
prepareQuery(query); prepareQuery(query);
return query.execute(); return (Collection) query.execute();
} }
}, true); }, true);
} }
public Collection find(final String queryString) throws DataAccessException { public Collection find(final String queryString) throws DataAccessException {
return (Collection) execute(new JdoCallback() { return execute(new JdoCallback<Collection>() {
public Object doInJdo(PersistenceManager pm) throws JDOException { @SuppressWarnings("unchecked")
public Collection doInJdo(PersistenceManager pm) throws JDOException {
Query query = pm.newQuery(queryString); Query query = pm.newQuery(queryString);
prepareQuery(query); prepareQuery(query);
return query.execute(); return (Collection) query.execute();
} }
}, true); }, true);
} }
public Collection find(final String queryString, final Object[] values) throws DataAccessException { public Collection find(final String queryString, final Object[] values) throws DataAccessException {
return (Collection) execute(new JdoCallback() { return execute(new JdoCallback<Collection>() {
public Object doInJdo(PersistenceManager pm) throws JDOException { public Collection doInJdo(PersistenceManager pm) throws JDOException {
Query query = pm.newQuery(queryString); Query query = pm.newQuery(queryString);
prepareQuery(query); prepareQuery(query);
return query.executeWithArray(values); return (Collection) query.executeWithArray(values);
} }
}, true); }, true);
} }
public Collection find(final String queryString, final Map values) throws DataAccessException { public Collection find(final String queryString, final Map values) throws DataAccessException {
return (Collection) execute(new JdoCallback() { return execute(new JdoCallback<Collection>() {
public Object doInJdo(PersistenceManager pm) throws JDOException { public Collection doInJdo(PersistenceManager pm) throws JDOException {
Query query = pm.newQuery(queryString); Query query = pm.newQuery(queryString);
prepareQuery(query); prepareQuery(query);
return query.executeWithMap(values); return (Collection) query.executeWithMap(values);
} }
}, true); }, true);
} }
public Collection findByNamedQuery(final Class entityClass, final String queryName) throws DataAccessException { public <T> Collection<T> findByNamedQuery(final Class<T> entityClass, final String queryName)
return (Collection) execute(new JdoCallback() {
public Object doInJdo(PersistenceManager pm) throws JDOException {
Query query = pm.newNamedQuery(entityClass, queryName);
prepareQuery(query);
return query.execute();
}
}, true);
}
public Collection findByNamedQuery(final Class entityClass, final String queryName, final Object[] values)
throws DataAccessException { throws DataAccessException {
return (Collection) execute(new JdoCallback() { return execute(new JdoCallback<Collection<T>>() {
public Object doInJdo(PersistenceManager pm) throws JDOException { @SuppressWarnings("unchecked")
public Collection<T> doInJdo(PersistenceManager pm) throws JDOException {
Query query = pm.newNamedQuery(entityClass, queryName); Query query = pm.newNamedQuery(entityClass, queryName);
prepareQuery(query); prepareQuery(query);
return query.executeWithArray(values); return (Collection<T>) query.execute();
} }
}, true); }, true);
} }
public Collection findByNamedQuery(final Class entityClass, final String queryName, final Map values) public <T> Collection<T> findByNamedQuery(final Class<T> entityClass, final String queryName, final Object[] values)
throws DataAccessException { throws DataAccessException {
return (Collection) execute(new JdoCallback() { return execute(new JdoCallback<Collection<T>>() {
public Object doInJdo(PersistenceManager pm) throws JDOException { @SuppressWarnings("unchecked")
public Collection<T> doInJdo(PersistenceManager pm) throws JDOException {
Query query = pm.newNamedQuery(entityClass, queryName); Query query = pm.newNamedQuery(entityClass, queryName);
prepareQuery(query); prepareQuery(query);
return query.executeWithMap(values); return (Collection<T>) query.executeWithArray(values);
}
}, true);
}
public <T> Collection<T> findByNamedQuery(final Class<T> entityClass, final String queryName, final Map values)
throws DataAccessException {
return execute(new JdoCallback<Collection<T>>() {
@SuppressWarnings("unchecked")
public Collection<T> doInJdo(PersistenceManager pm) throws JDOException {
Query query = pm.newNamedQuery(entityClass, queryName);
prepareQuery(query);
return (Collection<T>) query.executeWithMap(values);
} }
}, true); }, true);
} }
@ -537,7 +547,7 @@ public class JdoTemplate extends JdoAccessor implements JdoOperations {
/** /**
* Prepare the given JDO query object. To be used within a JdoCallback. * Prepare the given JDO query object. To be used within a JdoCallback.
* Applies a transaction timeout, if any. If you don't use such timeouts, * <p>Applies a transaction timeout, if any. If you don't use such timeouts,
* the call is a no-op. * the call is a no-op.
* <p>In general, prefer a proxied PersistenceManager instead, which will * <p>In general, prefer a proxied PersistenceManager instead, which will
* automatically apply the transaction timeout (through the use of a special * automatically apply the transaction timeout (through the use of a special
@ -588,12 +598,10 @@ public class JdoTemplate extends JdoAccessor implements JdoOperations {
// Invoke method on target PersistenceManager. // Invoke method on target PersistenceManager.
try { try {
Object retVal = method.invoke(this.target, args); Object retVal = method.invoke(this.target, args);
// If return value is a JDO Query object, apply transaction timeout. // If return value is a JDO Query object, apply transaction timeout.
if (retVal instanceof Query) { if (retVal instanceof Query) {
prepareQuery(((Query) retVal)); prepareQuery(((Query) retVal));
} }
return retVal; return retVal;
} }
catch (InvocationTargetException ex) { catch (InvocationTargetException ex) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2008 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -20,7 +20,6 @@ import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import javax.jdo.JDOException; import javax.jdo.JDOException;
import javax.jdo.JDOHelper; import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManagerFactory; import javax.jdo.PersistenceManagerFactory;
@ -46,6 +45,12 @@ import org.springframework.util.CollectionUtils;
* dependency injection. Note that switching to a JNDI lookup or to a bean-style * dependency injection. Note that switching to a JNDI lookup or to a bean-style
* PersistenceManagerFactory instance is just a matter of configuration! * PersistenceManagerFactory instance is just a matter of configuration!
* *
* <p><b>NOTE: This class requires JDO 2.0 or higher, as of Spring 2.5.</b>
* Since JDO 2.1, it will also expose the JPA {@link javax.persistence.EntityManagerFactory}
* as long as the JDO provider creates a {@link javax.jdo.JDOEntityManagerFactory} reference
* underneath, which means that this class can be used as a replacement for
* {@link org.springframework.orm.jpa.LocalEntityManagerFactoryBean} in such a scenario.
*
* <p>Configuration settings can either be read from a properties file, * <p>Configuration settings can either be read from a properties file,
* specified as "configLocation", or locally specified. Properties * specified as "configLocation", or locally specified. Properties
* specified as "jdoProperties" here will override any settings in a file. * specified as "jdoProperties" here will override any settings in a file.
@ -53,8 +58,6 @@ import org.springframework.util.CollectionUtils;
* referring to a PMF definition in "META-INF/jdoconfig.xml" * referring to a PMF definition in "META-INF/jdoconfig.xml"
* (see {@link #setPersistenceManagerFactoryName}). * (see {@link #setPersistenceManagerFactoryName}).
* *
* <p><b>NOTE: This class requires JDO 2.0 or higher, as of Spring 2.5.</b>
*
* <p>This class also implements the * <p>This class also implements the
* {@link org.springframework.dao.support.PersistenceExceptionTranslator} * {@link org.springframework.dao.support.PersistenceExceptionTranslator}
* interface, as autodetected by Spring's * interface, as autodetected by Spring's
@ -105,8 +108,8 @@ import org.springframework.util.CollectionUtils;
* @see javax.jdo.PersistenceManagerFactory#close() * @see javax.jdo.PersistenceManagerFactory#close()
* @see org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor * @see org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor
*/ */
public class LocalPersistenceManagerFactoryBean public class LocalPersistenceManagerFactoryBean implements FactoryBean<PersistenceManagerFactory>,
implements FactoryBean, BeanClassLoaderAware, InitializingBean, DisposableBean, PersistenceExceptionTranslator { BeanClassLoaderAware, InitializingBean, DisposableBean, PersistenceExceptionTranslator {
protected final Log logger = LogFactory.getLog(getClass()); protected final Log logger = LogFactory.getLog(getClass());
@ -272,11 +275,11 @@ public class LocalPersistenceManagerFactoryBean
/** /**
* Return the singleton PersistenceManagerFactory. * Return the singleton PersistenceManagerFactory.
*/ */
public Object getObject() { public PersistenceManagerFactory getObject() {
return this.persistenceManagerFactory; return this.persistenceManagerFactory;
} }
public Class getObjectType() { public Class<? extends PersistenceManagerFactory> getObjectType() {
return (this.persistenceManagerFactory != null ? return (this.persistenceManagerFactory != null ?
this.persistenceManagerFactory.getClass() : PersistenceManagerFactory.class); this.persistenceManagerFactory.getClass() : PersistenceManagerFactory.class);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2008 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2008 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -20,7 +20,6 @@ import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import javax.jdo.PersistenceManager; import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory; import javax.jdo.PersistenceManagerFactory;
@ -31,7 +30,7 @@ import org.springframework.util.ClassUtils;
/** /**
* Proxy for a target JDO {@link javax.jdo.PersistenceManagerFactory}, * Proxy for a target JDO {@link javax.jdo.PersistenceManagerFactory},
* returning the current thread-bound PersistenceManager (the Spring-managed * returning the current thread-bound PersistenceManager (the Spring-managed
* transactional PersistenceManager or a the single OpenPersistenceManagerInView * transactional PersistenceManager or the single OpenPersistenceManagerInView
* PersistenceManager) on <code>getPersistenceManager()</code>, if any. * PersistenceManager) on <code>getPersistenceManager()</code>, if any.
* *
* <p>Essentially, <code>getPersistenceManager()</code> calls get seamlessly * <p>Essentially, <code>getPersistenceManager()</code> calls get seamlessly
@ -68,7 +67,7 @@ import org.springframework.util.ClassUtils;
* @see PersistenceManagerFactoryUtils#getPersistenceManager * @see PersistenceManagerFactoryUtils#getPersistenceManager
* @see PersistenceManagerFactoryUtils#releasePersistenceManager * @see PersistenceManagerFactoryUtils#releasePersistenceManager
*/ */
public class TransactionAwarePersistenceManagerFactoryProxy implements FactoryBean { public class TransactionAwarePersistenceManagerFactoryProxy implements FactoryBean<PersistenceManagerFactory> {
private PersistenceManagerFactory target; private PersistenceManagerFactory target;
@ -86,9 +85,9 @@ public class TransactionAwarePersistenceManagerFactoryProxy implements FactoryBe
public void setTargetPersistenceManagerFactory(PersistenceManagerFactory target) { public void setTargetPersistenceManagerFactory(PersistenceManagerFactory target) {
Assert.notNull(target, "Target PersistenceManagerFactory must not be null"); Assert.notNull(target, "Target PersistenceManagerFactory must not be null");
this.target = target; this.target = target;
Class[] ifcs = ClassUtils.getAllInterfacesForClass(target.getClass(), getClass().getClassLoader()); Class[] ifcs = ClassUtils.getAllInterfacesForClass(target.getClass(), target.getClass().getClassLoader());
this.proxy = (PersistenceManagerFactory) Proxy.newProxyInstance( this.proxy = (PersistenceManagerFactory) Proxy.newProxyInstance(
target.getClass().getClassLoader(), ifcs, new TransactionAwareFactoryInvocationHandler()); target.getClass().getClassLoader(), ifcs, new PersistenceManagerFactoryInvocationHandler());
} }
/** /**
@ -123,11 +122,11 @@ public class TransactionAwarePersistenceManagerFactoryProxy implements FactoryBe
} }
public Object getObject() { public PersistenceManagerFactory getObject() {
return this.proxy; return this.proxy;
} }
public Class getObjectType() { public Class<? extends PersistenceManagerFactory> getObjectType() {
return PersistenceManagerFactory.class; return PersistenceManagerFactory.class;
} }
@ -141,7 +140,7 @@ public class TransactionAwarePersistenceManagerFactoryProxy implements FactoryBe
* PersistenceManagerFactory proxy to PersistenceManagerFactoryUtils * PersistenceManagerFactory proxy to PersistenceManagerFactoryUtils
* for being aware of thread-bound transactions. * for being aware of thread-bound transactions.
*/ */
private class TransactionAwareFactoryInvocationHandler implements InvocationHandler { private class PersistenceManagerFactoryInvocationHandler implements InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// Invocation on PersistenceManagerFactory interface coming in... // Invocation on PersistenceManagerFactory interface coming in...
@ -158,9 +157,9 @@ public class TransactionAwarePersistenceManagerFactoryProxy implements FactoryBe
PersistenceManagerFactory target = getTargetPersistenceManagerFactory(); PersistenceManagerFactory target = getTargetPersistenceManagerFactory();
PersistenceManager pm = PersistenceManager pm =
PersistenceManagerFactoryUtils.doGetPersistenceManager(target, isAllowCreate()); PersistenceManagerFactoryUtils.doGetPersistenceManager(target, isAllowCreate());
Class[] ifcs = ClassUtils.getAllInterfacesForClass(pm.getClass(), getClass().getClassLoader()); Class[] ifcs = ClassUtils.getAllInterfacesForClass(pm.getClass(), pm.getClass().getClassLoader());
return Proxy.newProxyInstance( return Proxy.newProxyInstance(
pm.getClass().getClassLoader(), ifcs, new TransactionAwareInvocationHandler(pm, target)); pm.getClass().getClassLoader(), ifcs, new PersistenceManagerInvocationHandler(pm, target));
} }
// Invoke method on target PersistenceManagerFactory. // Invoke method on target PersistenceManagerFactory.
@ -178,13 +177,13 @@ public class TransactionAwarePersistenceManagerFactoryProxy implements FactoryBe
* Invocation handler that delegates close calls on PersistenceManagers to * Invocation handler that delegates close calls on PersistenceManagers to
* PersistenceManagerFactoryUtils for being aware of thread-bound transactions. * PersistenceManagerFactoryUtils for being aware of thread-bound transactions.
*/ */
private static class TransactionAwareInvocationHandler implements InvocationHandler { private static class PersistenceManagerInvocationHandler implements InvocationHandler {
private final PersistenceManager target; private final PersistenceManager target;
private final PersistenceManagerFactory persistenceManagerFactory; private final PersistenceManagerFactory persistenceManagerFactory;
public TransactionAwareInvocationHandler(PersistenceManager target, PersistenceManagerFactory pmf) { public PersistenceManagerInvocationHandler(PersistenceManager target, PersistenceManagerFactory pmf) {
this.target = target; this.target = target;
this.persistenceManagerFactory = pmf; this.persistenceManagerFactory = pmf;
} }
@ -202,10 +201,8 @@ public class TransactionAwarePersistenceManagerFactoryProxy implements FactoryBe
} }
else if (method.getName().equals("close")) { else if (method.getName().equals("close")) {
// Handle close method: only close if not within a transaction. // Handle close method: only close if not within a transaction.
if (this.persistenceManagerFactory != null) {
PersistenceManagerFactoryUtils.doReleasePersistenceManager( PersistenceManagerFactoryUtils.doReleasePersistenceManager(
this.target, this.persistenceManagerFactory); this.target, this.persistenceManagerFactory);
}
return null; return null;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2007 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -139,10 +139,8 @@ public class OpenPersistenceManagerInViewFilter extends OncePerRequestFilter {
logger.debug("Using PersistenceManagerFactory '" + getPersistenceManagerFactoryBeanName() + logger.debug("Using PersistenceManagerFactory '" + getPersistenceManagerFactoryBeanName() +
"' for OpenPersistenceManagerInViewFilter"); "' for OpenPersistenceManagerInViewFilter");
} }
WebApplicationContext wac = WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()); return wac.getBean(getPersistenceManagerFactoryBeanName(), PersistenceManagerFactory.class);
return (PersistenceManagerFactory)
wac.getBean(getPersistenceManagerFactoryBeanName(), PersistenceManagerFactory.class);
} }
} }

View File

@ -0,0 +1,186 @@
/*
* Copyright 2002-2009 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.jdo.support;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.orm.jdo.JdoAccessor;
import org.springframework.orm.jdo.PersistenceManagerFactoryUtils;
import org.springframework.util.Assert;
/**
* Proxy that implements the {@link javax.jdo.PersistenceManager} interface,
* delegating to the current thread-bound PersistenceManager (the Spring-managed
* transactional PersistenceManager or the single OpenPersistenceManagerInView
* PersistenceManager, if any) on each invocation. This class makes such a
* Spring-style PersistenceManager proxy available for bean references.
*
* <p>The main advantage of this proxy is that it allows DAOs to work with a
* plain JDO PersistenceManager reference in JDO 2.1 style
* (see {@link javax.jdo.PersistenceManagerFactory#getPersistenceManagerProxy()}),
* while still participating in Spring's resource and transaction management.
*
* <p>The behavior of this proxy matches the behavior that the JDO 2.1 spec
* defines for a PersistenceManager proxy. Hence, DAOs could seamlessly switch
* between {@link StandardPersistenceManagerProxyBean} and this Spring-style proxy,
* receiving the reference through Dependency Injection. This will work without
* any Spring API dependencies in the DAO code!
*
* <p>Note: In contrast to {@link StandardPersistenceManagerProxyBean}, this proxy
* works with JDO 2.0 and higher. It does not require JDO 2.1.
*
* @author Juergen Hoeller
* @since 3.0
* @see StandardPersistenceManagerProxyBean
* @see javax.jdo.PersistenceManagerFactory#getPersistenceManagerProxy()
* @see org.springframework.orm.jdo.PersistenceManagerFactoryUtils#getPersistenceManager
* @see org.springframework.orm.jdo.PersistenceManagerFactoryUtils#releasePersistenceManager
*/
public class SpringPersistenceManagerProxyBean extends JdoAccessor implements FactoryBean<PersistenceManager> {
private Class<? extends PersistenceManager> persistenceManagerInterface = PersistenceManager.class;
private boolean allowCreate = true;
private PersistenceManager proxy;
/**
* Specify the PersistenceManager interface to expose,
* possibly including vendor extensions.
* <p>Default is the standard <code>javax.jdo.PersistenceManager</code> interface.
*/
public void setPersistenceManagerInterface(Class<? extends PersistenceManager> persistenceManagerInterface) {
this.persistenceManagerInterface = persistenceManagerInterface;
Assert.notNull(persistenceManagerInterface, "persistenceManagerInterface must not be null");
Assert.isAssignable(PersistenceManager.class, persistenceManagerInterface);
}
/**
* Return the PersistenceManager interface to expose.
*/
protected Class<? extends PersistenceManager> getPersistenceManagerInterface() {
return this.persistenceManagerInterface;
}
/**
* Set whether the PersistenceManagerFactory proxy is allowed to create
* a non-transactional PersistenceManager when no transactional
* PersistenceManager can be found for the current thread.
* <p>Default is "true". Can be turned off to enforce access to
* transactional PersistenceManagers, which safely allows for DAOs
* written to get a PersistenceManager without explicit closing
* (i.e. a <code>PersistenceManagerFactory.getPersistenceManager()</code>
* call without corresponding <code>PersistenceManager.close()</code> call).
* @see org.springframework.orm.jdo.PersistenceManagerFactoryUtils#getPersistenceManager(javax.jdo.PersistenceManagerFactory, boolean)
*/
public void setAllowCreate(boolean allowCreate) {
this.allowCreate = allowCreate;
}
/**
* Return whether the PersistenceManagerFactory proxy is allowed to create
* a non-transactional PersistenceManager when no transactional
* PersistenceManager can be found for the current thread.
*/
protected boolean isAllowCreate() {
return this.allowCreate;
}
@Override
public void afterPropertiesSet() {
super.afterPropertiesSet();
this.proxy = (PersistenceManager) Proxy.newProxyInstance(
getPersistenceManagerFactory().getClass().getClassLoader(),
new Class[] {getPersistenceManagerInterface()}, new PersistenceManagerInvocationHandler());
}
public PersistenceManager getObject() {
return this.proxy;
}
public Class<? extends PersistenceManager> getObjectType() {
return getPersistenceManagerInterface();
}
public boolean isSingleton() {
return true;
}
/**
* Invocation handler that delegates close calls on PersistenceManagers to
* PersistenceManagerFactoryUtils for being aware of thread-bound transactions.
*/
private class PersistenceManagerInvocationHandler implements InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// Invocation on PersistenceManager interface coming in...
if (method.getName().equals("equals")) {
// Only consider equal when proxies are identical.
return (proxy == args[0]);
}
else if (method.getName().equals("hashCode")) {
// Use hashCode of PersistenceManager proxy.
return System.identityHashCode(proxy);
}
else if (method.getName().equals("toString")) {
// Deliver toString without touching a target EntityManager.
return "Spring PersistenceManager proxy for target factory [" + getPersistenceManagerFactory() + "]";
}
else if (method.getName().equals("getPersistenceManagerFactory")) {
// Return PersistenceManagerFactory without creating a PersistenceManager.
return getPersistenceManagerFactory();
}
else if (method.getName().equals("isClosed")) {
// Proxy is always usable.
return false;
}
else if (method.getName().equals("close")) {
// Suppress close method.
return null;
}
// Invoke method on target PersistenceManager.
PersistenceManager pm = PersistenceManagerFactoryUtils.doGetPersistenceManager(
getPersistenceManagerFactory(), isAllowCreate());
try {
Object retVal = method.invoke(pm, args);
if (retVal instanceof Query) {
PersistenceManagerFactoryUtils.applyTransactionTimeout(
(Query) retVal, getPersistenceManagerFactory(), getJdoDialect());
}
return retVal;
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
finally {
PersistenceManagerFactoryUtils.doReleasePersistenceManager(pm, getPersistenceManagerFactory());
}
}
}
}

View File

@ -0,0 +1,72 @@
/*
* Copyright 2002-2009 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 exprShess or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.orm.jdo.support;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.util.Assert;
/**
* Proxy that implements the {@link javax.jdo.PersistenceManager} interface,
* delegating to a thread-bound PersistenceManager on each invocation -
* as defined by the JDO 2.1 specification. This class makes such a standard
* JDO PersistenceManager proxy available for bean references.
*
* <p>The main advantage of this proxy is that it allows DAOs to work with a
* plain JDO PersistenceManager reference in JDO 2.1 style
* (see {@link javax.jdo.PersistenceManagerFactory#getPersistenceManagerProxy()}),
* exposing the exact behavior that the target JDO provider implements.
*
* <p>Note: This proxy requires JDO 2.1 or higher.
*
* @author Juergen Hoeller
* @since 3.0
* @see SpringPersistenceManagerProxyBean
* @see javax.jdo.PersistenceManagerFactory#getPersistenceManagerProxy()
*/
public class StandardPersistenceManagerProxyBean implements FactoryBean<PersistenceManager> {
private PersistenceManager proxy;
/**
* Set the target JDO PersistenceManagerFactory that this proxy should
* delegate to. This should be the raw PersistenceManagerFactory, as
* accessed by JdoTransactionManager.
* @see org.springframework.orm.jdo.JdoTransactionManager
*/
public void setPersistenceManagerFactory(PersistenceManagerFactory pmf) {
Assert.notNull(pmf, "PersistenceManagerFactory must not be null");
this.proxy = pmf.getPersistenceManagerProxy();
}
public PersistenceManager getObject() {
return this.proxy;
}
public Class<? extends PersistenceManager> getObjectType() {
return (this.proxy != null ? this.proxy.getClass() : PersistenceManager.class);
}
public boolean isSingleton() {
return true;
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2008 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -73,7 +73,7 @@ import org.springframework.util.CollectionUtils;
* @see LocalContainerEntityManagerFactoryBean * @see LocalContainerEntityManagerFactoryBean
*/ */
public abstract class AbstractEntityManagerFactoryBean implements public abstract class AbstractEntityManagerFactoryBean implements
FactoryBean, BeanClassLoaderAware, InitializingBean, DisposableBean, FactoryBean<EntityManagerFactory>, BeanClassLoaderAware, InitializingBean, DisposableBean,
EntityManagerFactoryInfo, PersistenceExceptionTranslator { EntityManagerFactoryInfo, PersistenceExceptionTranslator {
/** Logger available to subclasses */ /** Logger available to subclasses */
@ -370,7 +370,7 @@ public abstract class AbstractEntityManagerFactoryBean implements
return this.entityManagerFactory; return this.entityManagerFactory;
} }
public Class getObjectType() { public Class<? extends EntityManagerFactory> getObjectType() {
return (this.entityManagerFactory != null ? this.entityManagerFactory.getClass() : EntityManagerFactory.class); return (this.entityManagerFactory != null ? this.entityManagerFactory.getClass() : EntityManagerFactory.class);
} }

View File

@ -17,7 +17,6 @@
package org.springframework.orm.jpa; package org.springframework.orm.jpa;
import java.util.Map; import java.util.Map;
import javax.persistence.EntityExistsException; import javax.persistence.EntityExistsException;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory; import javax.persistence.EntityManagerFactory;
@ -26,6 +25,7 @@ import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException; import javax.persistence.NonUniqueResultException;
import javax.persistence.OptimisticLockException; import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException; import javax.persistence.PersistenceException;
import javax.persistence.Query;
import javax.persistence.TransactionRequiredException; import javax.persistence.TransactionRequiredException;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@ -248,6 +248,22 @@ public abstract class EntityManagerFactoryUtils {
} }
} }
/**
* Apply the current transaction timeout, if any, to the given JPA Query object.
* <p>This method sets the JPA 2.0 query hints "javax.persistence.lock.timeout"
* and "javax.persistence.query.timeout" accordingly.
* @param query the JPA Query object
* @param emf JPA EntityManagerFactory that the Query was created for
*/
public static void applyTransactionTimeout(Query query, EntityManagerFactory emf) {
EntityManagerHolder emHolder = (EntityManagerHolder) TransactionSynchronizationManager.getResource(emf);
if (emHolder != null && emHolder.hasTimeout()) {
int timeoutValue = emHolder.getTimeToLiveInSeconds();
query.setHint("javax.persistence.lock.timeout", timeoutValue);
query.setHint("javax.persistence.query.timeout", timeoutValue);
}
}
/** /**
* Convert the given runtime exception to an appropriate exception from the * Convert the given runtime exception to an appropriate exception from the
* <code>org.springframework.dao</code> hierarchy. * <code>org.springframework.dao</code> hierarchy.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2008 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -24,7 +24,6 @@ import java.lang.reflect.Proxy;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory; import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction; import javax.persistence.EntityTransaction;
@ -294,7 +293,7 @@ public abstract class ExtendedEntityManagerCreator {
this.target = target; this.target = target;
this.plusOperations = plusOperations; this.plusOperations = plusOperations;
this.exceptionTranslator = exceptionTranslator; this.exceptionTranslator = exceptionTranslator;
this.jta = (jta != null ? jta.booleanValue() : isJtaEntityManager()); this.jta = (jta != null ? jta : isJtaEntityManager());
this.containerManaged = containerManaged; this.containerManaged = containerManaged;
} }
@ -321,8 +320,16 @@ public abstract class ExtendedEntityManagerCreator {
return hashCode(); return hashCode();
} }
else if (method.getName().equals("getTargetEntityManager")) { else if (method.getName().equals("getTargetEntityManager")) {
// Handle EntityManagerProxy interface.
return this.target; return this.target;
} }
else if (method.getName().equals("unwrap")) {
// Handle JPA 2.0 unwrap method - could be a proxy match.
Class targetClass = (Class) args[0];
if (targetClass == null || targetClass.isInstance(proxy)) {
return proxy;
}
}
else if (method.getName().equals("isOpen")) { else if (method.getName().equals("isOpen")) {
if (this.containerManaged) { if (this.containerManaged) {
return true; return true;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2007 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -112,7 +112,7 @@ public abstract class JpaAccessor extends EntityManagerFactoryAccessor implement
public void afterPropertiesSet() { public void afterPropertiesSet() {
EntityManagerFactory emf = getEntityManagerFactory(); EntityManagerFactory emf = getEntityManagerFactory();
if (emf == null && getEntityManager() == null) { if (emf == null && getEntityManager() == null) {
throw new IllegalArgumentException("entityManagerFactory or entityManager is required"); throw new IllegalArgumentException("'entityManagerFactory' or 'entityManager' is required");
} }
if (emf instanceof EntityManagerFactoryInfo) { if (emf instanceof EntityManagerFactoryInfo) {
JpaDialect jpaDialect = ((EntityManagerFactoryInfo) emf).getJpaDialect(); JpaDialect jpaDialect = ((EntityManagerFactoryInfo) emf).getJpaDialect();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2006 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -30,7 +30,7 @@ import javax.persistence.PersistenceException;
* @see org.springframework.orm.jpa.JpaTemplate * @see org.springframework.orm.jpa.JpaTemplate
* @see org.springframework.orm.jpa.JpaTransactionManager * @see org.springframework.orm.jpa.JpaTransactionManager
*/ */
public interface JpaCallback { public interface JpaCallback<T> {
/** /**
* Gets called by <code>JpaTemplate.execute</code> with an active * Gets called by <code>JpaTemplate.execute</code> with an active
@ -53,6 +53,6 @@ public interface JpaCallback {
* @see org.springframework.orm.jpa.JpaTemplate#execute * @see org.springframework.orm.jpa.JpaTemplate#execute
* @see org.springframework.orm.jpa.JpaTemplate#executeFind * @see org.springframework.orm.jpa.JpaTemplate#executeFind
*/ */
Object doInJpa(EntityManager em) throws PersistenceException; T doInJpa(EntityManager em) throws PersistenceException;
} }

View File

@ -49,9 +49,9 @@ import org.springframework.dao.DataAccessException;
*/ */
public interface JpaOperations { public interface JpaOperations {
Object execute(JpaCallback action) throws DataAccessException; <T> T execute(JpaCallback<T> action) throws DataAccessException;
List executeFind(JpaCallback action) throws DataAccessException; List executeFind(JpaCallback<?> action) throws DataAccessException;
<T> T find(Class<T> entityClass, Object id) throws DataAccessException; <T> T find(Class<T> entityClass, Object id) throws DataAccessException;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2008 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -22,7 +22,6 @@ import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory; import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceException; import javax.persistence.PersistenceException;
@ -143,11 +142,11 @@ public class JpaTemplate extends JpaAccessor implements JpaOperations {
} }
public Object execute(JpaCallback action) throws DataAccessException { public <T> T execute(JpaCallback<T> action) throws DataAccessException {
return execute(action, isExposeNativeEntityManager()); return execute(action, isExposeNativeEntityManager());
} }
public List executeFind(JpaCallback action) throws DataAccessException { public List executeFind(JpaCallback<?> action) throws DataAccessException {
Object result = execute(action, isExposeNativeEntityManager()); Object result = execute(action, isExposeNativeEntityManager());
if (!(result instanceof List)) { if (!(result instanceof List)) {
throw new InvalidDataAccessApiUsageException( throw new InvalidDataAccessApiUsageException(
@ -165,7 +164,7 @@ public class JpaTemplate extends JpaAccessor implements JpaOperations {
* @return a result object returned by the action, or <code>null</code> * @return a result object returned by the action, or <code>null</code>
* @throws org.springframework.dao.DataAccessException in case of JPA errors * @throws org.springframework.dao.DataAccessException in case of JPA errors
*/ */
public Object execute(JpaCallback action, boolean exposeNativeEntityManager) throws DataAccessException { public <T> T execute(JpaCallback<T> action, boolean exposeNativeEntityManager) throws DataAccessException {
Assert.notNull(action, "Callback object must not be null"); Assert.notNull(action, "Callback object must not be null");
EntityManager em = getEntityManager(); EntityManager em = getEntityManager();
@ -181,7 +180,7 @@ public class JpaTemplate extends JpaAccessor implements JpaOperations {
try { try {
EntityManager emToExpose = (exposeNativeEntityManager ? em : createEntityManagerProxy(em)); EntityManager emToExpose = (exposeNativeEntityManager ? em : createEntityManagerProxy(em));
Object result = action.doInJpa(emToExpose); T result = action.doInJpa(emToExpose);
flushIfNecessary(em, !isNewEm); flushIfNecessary(em, !isNewEm);
return result; return result;
} }
@ -226,35 +225,32 @@ public class JpaTemplate extends JpaAccessor implements JpaOperations {
// Convenience methods for load, save, delete // Convenience methods for load, save, delete
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@SuppressWarnings("unchecked")
public <T> T find(final Class<T> entityClass, final Object id) throws DataAccessException { public <T> T find(final Class<T> entityClass, final Object id) throws DataAccessException {
return (T) execute(new JpaCallback() { return execute(new JpaCallback<T>() {
public Object doInJpa(EntityManager em) throws PersistenceException { public T doInJpa(EntityManager em) throws PersistenceException {
return em.find(entityClass, id); return em.find(entityClass, id);
} }
}, true); }, true);
} }
@SuppressWarnings("unchecked")
public <T> T getReference(final Class<T> entityClass, final Object id) throws DataAccessException { public <T> T getReference(final Class<T> entityClass, final Object id) throws DataAccessException {
return (T) execute(new JpaCallback() { return execute(new JpaCallback<T>() {
public Object doInJpa(EntityManager em) throws PersistenceException { public T doInJpa(EntityManager em) throws PersistenceException {
return em.getReference(entityClass, id); return em.getReference(entityClass, id);
} }
}, true); }, true);
} }
public boolean contains(final Object entity) throws DataAccessException { public boolean contains(final Object entity) throws DataAccessException {
Boolean result = (Boolean) execute(new JpaCallback() { return execute(new JpaCallback<Boolean>() {
public Object doInJpa(EntityManager em) throws PersistenceException { public Boolean doInJpa(EntityManager em) throws PersistenceException {
return em.contains(entity); return em.contains(entity);
} }
}, true); }, true);
return result;
} }
public void refresh(final Object entity) throws DataAccessException { public void refresh(final Object entity) throws DataAccessException {
execute(new JpaCallback() { execute(new JpaCallback<Object>() {
public Object doInJpa(EntityManager em) throws PersistenceException { public Object doInJpa(EntityManager em) throws PersistenceException {
em.refresh(entity); em.refresh(entity);
return null; return null;
@ -263,7 +259,7 @@ public class JpaTemplate extends JpaAccessor implements JpaOperations {
} }
public void persist(final Object entity) throws DataAccessException { public void persist(final Object entity) throws DataAccessException {
execute(new JpaCallback() { execute(new JpaCallback<Object>() {
public Object doInJpa(EntityManager em) throws PersistenceException { public Object doInJpa(EntityManager em) throws PersistenceException {
em.persist(entity); em.persist(entity);
return null; return null;
@ -271,17 +267,16 @@ public class JpaTemplate extends JpaAccessor implements JpaOperations {
}, true); }, true);
} }
@SuppressWarnings("unchecked")
public <T> T merge(final T entity) throws DataAccessException { public <T> T merge(final T entity) throws DataAccessException {
return (T) execute(new JpaCallback() { return execute(new JpaCallback<T>() {
public Object doInJpa(EntityManager em) throws PersistenceException { public T doInJpa(EntityManager em) throws PersistenceException {
return em.merge(entity); return em.merge(entity);
} }
}, true); }, true);
} }
public void remove(final Object entity) throws DataAccessException { public void remove(final Object entity) throws DataAccessException {
execute(new JpaCallback() { execute(new JpaCallback<Object>() {
public Object doInJpa(EntityManager em) throws PersistenceException { public Object doInJpa(EntityManager em) throws PersistenceException {
em.remove(entity); em.remove(entity);
return null; return null;
@ -290,7 +285,7 @@ public class JpaTemplate extends JpaAccessor implements JpaOperations {
} }
public void flush() throws DataAccessException { public void flush() throws DataAccessException {
execute(new JpaCallback() { execute(new JpaCallback<Object>() {
public Object doInJpa(EntityManager em) throws PersistenceException { public Object doInJpa(EntityManager em) throws PersistenceException {
em.flush(); em.flush();
return null; return null;
@ -308,9 +303,10 @@ public class JpaTemplate extends JpaAccessor implements JpaOperations {
} }
public List find(final String queryString, final Object... values) throws DataAccessException { public List find(final String queryString, final Object... values) throws DataAccessException {
return executeFind(new JpaCallback() { return execute(new JpaCallback<List>() {
public Object doInJpa(EntityManager em) throws PersistenceException { public List doInJpa(EntityManager em) throws PersistenceException {
Query queryObject = em.createQuery(queryString); Query queryObject = em.createQuery(queryString);
prepareQuery(queryObject);
if (values != null) { if (values != null) {
for (int i = 0; i < values.length; i++) { for (int i = 0; i < values.length; i++) {
queryObject.setParameter(i + 1, values[i]); queryObject.setParameter(i + 1, values[i]);
@ -322,9 +318,10 @@ public class JpaTemplate extends JpaAccessor implements JpaOperations {
} }
public List findByNamedParams(final String queryString, final Map<String, ?> params) throws DataAccessException { public List findByNamedParams(final String queryString, final Map<String, ?> params) throws DataAccessException {
return executeFind(new JpaCallback() { return execute(new JpaCallback<List>() {
public Object doInJpa(EntityManager em) throws PersistenceException { public List doInJpa(EntityManager em) throws PersistenceException {
Query queryObject = em.createQuery(queryString); Query queryObject = em.createQuery(queryString);
prepareQuery(queryObject);
if (params != null) { if (params != null) {
for (Map.Entry<String, ?> entry : params.entrySet()) { for (Map.Entry<String, ?> entry : params.entrySet()) {
queryObject.setParameter(entry.getKey(), entry.getValue()); queryObject.setParameter(entry.getKey(), entry.getValue());
@ -340,9 +337,10 @@ public class JpaTemplate extends JpaAccessor implements JpaOperations {
} }
public List findByNamedQuery(final String queryName, final Object... values) throws DataAccessException { public List findByNamedQuery(final String queryName, final Object... values) throws DataAccessException {
return executeFind(new JpaCallback() { return execute(new JpaCallback<List>() {
public Object doInJpa(EntityManager em) throws PersistenceException { public List doInJpa(EntityManager em) throws PersistenceException {
Query queryObject = em.createNamedQuery(queryName); Query queryObject = em.createNamedQuery(queryName);
prepareQuery(queryObject);
if (values != null) { if (values != null) {
for (int i = 0; i < values.length; i++) { for (int i = 0; i < values.length; i++) {
queryObject.setParameter(i + 1, values[i]); queryObject.setParameter(i + 1, values[i]);
@ -356,9 +354,10 @@ public class JpaTemplate extends JpaAccessor implements JpaOperations {
public List findByNamedQueryAndNamedParams(final String queryName, final Map<String, ?> params) public List findByNamedQueryAndNamedParams(final String queryName, final Map<String, ?> params)
throws DataAccessException { throws DataAccessException {
return executeFind(new JpaCallback() { return execute(new JpaCallback<List>() {
public Object doInJpa(EntityManager em) throws PersistenceException { public List doInJpa(EntityManager em) throws PersistenceException {
Query queryObject = em.createNamedQuery(queryName); Query queryObject = em.createNamedQuery(queryName);
prepareQuery(queryObject);
if (params != null) { if (params != null) {
for (Map.Entry<String, ?> entry : params.entrySet()) { for (Map.Entry<String, ?> entry : params.entrySet()) {
queryObject.setParameter(entry.getKey(), entry.getValue()); queryObject.setParameter(entry.getKey(), entry.getValue());
@ -370,10 +369,32 @@ public class JpaTemplate extends JpaAccessor implements JpaOperations {
} }
/**
* Prepare the given JPA query object. To be used within a JpaCallback.
* <p>Applies a transaction timeout, if any. If you don't use such timeouts,
* the call is a no-op.
* <p>In general, prefer a proxied EntityManager instead, which will
* automatically apply the transaction timeout (through the use of a special
* EntityManager proxy). You need to set the "exposeNativeEntityManager"
* property to "false" to activate this. Note that you won't be able to cast
* to a provider-specific JPA EntityManager class anymore then.
* @param query the JPA query object
* @see JpaCallback#doInJpa
* @see EntityManagerFactoryUtils#applyTransactionTimeout
* @see #setExposeNativeEntityManager
*/
public void prepareQuery(Query query) {
EntityManagerFactory emf = getEntityManagerFactory();
if (emf != null) {
EntityManagerFactoryUtils.applyTransactionTimeout(query, getEntityManagerFactory());
}
}
/** /**
* Invocation handler that suppresses close calls on JPA EntityManagers. * Invocation handler that suppresses close calls on JPA EntityManagers.
* Also prepares returned Query and Criteria objects. * Also prepares returned Query objects.
* @see javax.persistence.EntityManager#close * @see javax.persistence.EntityManager#close()
*/ */
private class CloseSuppressingInvocationHandler implements InvocationHandler { private class CloseSuppressingInvocationHandler implements InvocationHandler {
@ -401,7 +422,12 @@ public class JpaTemplate extends JpaAccessor implements JpaOperations {
// Invoke method on target EntityManager. // Invoke method on target EntityManager.
try { try {
return method.invoke(this.target, args); Object retVal = method.invoke(this.target, args);
// If return value is a JPA Query object, apply transaction timeout.
if (retVal instanceof Query) {
prepareQuery(((Query) retVal));
}
return retVal;
} }
catch (InvocationTargetException ex) { catch (InvocationTargetException ex) {
throw ex.getTargetException(); throw ex.getTargetException();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2008 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,7 +21,6 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.util.Map; import java.util.Map;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory; import javax.persistence.EntityManagerFactory;
import javax.persistence.Query; import javax.persistence.Query;
@ -151,6 +150,26 @@ public abstract class SharedEntityManagerCreator {
// Deliver toString without touching a target EntityManager. // Deliver toString without touching a target EntityManager.
return "Shared EntityManager proxy for target factory [" + this.targetFactory + "]"; return "Shared EntityManager proxy for target factory [" + this.targetFactory + "]";
} }
else if (method.getName().equals("getEntityManagerFactory")) {
// JPA 2.0: return EntityManagerFactory without creating an EntityManager.
return this.targetFactory;
}
else if (method.getName().equals("getQueryBuilder")) {
// JPA 2.0: return EntityManagerFactory's QueryBuilder (avoid creation of EntityManager).
try {
return EntityManagerFactory.class.getMethod("getQueryBuilder").invoke(this.targetFactory);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
else if (method.getName().equals("unwrap")) {
// JPA 2.0: handle unwrap method - could be a proxy match.
Class targetClass = (Class) args[0];
if (targetClass == null || targetClass.isInstance(proxy)) {
return proxy;
}
}
else if (method.getName().equals("isOpen")) { else if (method.getName().equals("isOpen")) {
// Handle isOpen method: always return true. // Handle isOpen method: always return true.
return true; return true;
@ -175,13 +194,24 @@ public abstract class SharedEntityManagerCreator {
EntityManager target = EntityManager target =
EntityManagerFactoryUtils.doGetTransactionalEntityManager(this.targetFactory, this.properties); EntityManagerFactoryUtils.doGetTransactionalEntityManager(this.targetFactory, this.properties);
// Handle EntityManagerProxy interface.
if (method.getName().equals("getTargetEntityManager")) { if (method.getName().equals("getTargetEntityManager")) {
// Handle EntityManagerProxy interface.
if (target == null) { if (target == null) {
throw new IllegalStateException("No transactional EntityManager available"); throw new IllegalStateException("No transactional EntityManager available");
} }
return target; return target;
} }
else if (method.getName().equals("unwrap")) {
// Handle JPA 2.0 unwrap method - could be a proxy match.
Class targetClass = (Class) args[0];
if (targetClass == null || targetClass.isInstance(proxy)) {
return proxy;
}
// We need a transactional target now.
if (target == null) {
throw new IllegalStateException("No transactional EntityManager available");
}
}
// Regular EntityManager operations. // Regular EntityManager operations.
boolean isNewEm = false; boolean isNewEm = false;
@ -196,11 +226,17 @@ public abstract class SharedEntityManagerCreator {
// Invoke method on current EntityManager. // Invoke method on current EntityManager.
try { try {
Object result = method.invoke(target, args); Object result = method.invoke(target, args);
if (isNewEm && result instanceof Query) { if (result instanceof Query) {
Query query = (Query) result;
if (isNewEm) {
result = Proxy.newProxyInstance(Query.class.getClassLoader(), new Class[] {Query.class}, result = Proxy.newProxyInstance(Query.class.getClassLoader(), new Class[] {Query.class},
new DeferredQueryInvocationHandler((Query) result, target)); new DeferredQueryInvocationHandler(query, target));
isNewEm = false; isNewEm = false;
} }
else {
EntityManagerFactoryUtils.applyTransactionTimeout(query, this.targetFactory);
}
}
return result; return result;
} }
catch (InvocationTargetException ex) { catch (InvocationTargetException ex) {
@ -241,6 +277,13 @@ public abstract class SharedEntityManagerCreator {
// Use hashCode of EntityManager proxy. // Use hashCode of EntityManager proxy.
return hashCode(); return hashCode();
} }
else if (method.getName().equals("unwrap")) {
// Handle JPA 2.0 unwrap method - could be a proxy match.
Class targetClass = (Class) args[0];
if (targetClass == null || targetClass.isInstance(proxy)) {
return proxy;
}
}
// Invoke method on actual Query object. // Invoke method on actual Query object.
try { try {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2008 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -147,10 +147,8 @@ public class OpenEntityManagerInViewFilter extends OncePerRequestFilter {
logger.debug("Using EntityManagerFactory '" + getEntityManagerFactoryBeanName() + logger.debug("Using EntityManagerFactory '" + getEntityManagerFactoryBeanName() +
"' for OpenEntityManagerInViewFilter"); "' for OpenEntityManagerInViewFilter");
} }
WebApplicationContext wac = WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()); return wac.getBean(getEntityManagerFactoryBeanName(), EntityManagerFactory.class);
return (EntityManagerFactory)
wac.getBean(getEntityManagerFactoryBeanName(), EntityManagerFactory.class);
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2008 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -26,7 +26,6 @@ import java.lang.reflect.Modifier;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import javax.naming.NamingException; import javax.naming.NamingException;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory; import javax.persistence.EntityManagerFactory;
@ -405,7 +404,7 @@ public class PersistenceAnnotationBeanPostProcessor extends JndiLocatorSupport
} }
if (jndiName != null) { if (jndiName != null) {
try { try {
return (EntityManagerFactory) lookup(jndiName, EntityManagerFactory.class); return lookup(jndiName, EntityManagerFactory.class);
} }
catch (NamingException ex) { catch (NamingException ex) {
throw new IllegalStateException("Could not obtain EntityManagerFactory [" + jndiName + "] from JNDI", ex); throw new IllegalStateException("Could not obtain EntityManagerFactory [" + jndiName + "] from JNDI", ex);
@ -437,7 +436,7 @@ public class PersistenceAnnotationBeanPostProcessor extends JndiLocatorSupport
} }
if (jndiName != null) { if (jndiName != null) {
try { try {
return (EntityManager) lookup(jndiName, EntityManager.class); return lookup(jndiName, EntityManager.class);
} }
catch (NamingException ex) { catch (NamingException ex) {
throw new IllegalStateException("Could not obtain EntityManager [" + jndiName + "] from JNDI", ex); throw new IllegalStateException("Could not obtain EntityManager [" + jndiName + "] from JNDI", ex);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2008 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -50,22 +50,23 @@ import org.springframework.util.Assert;
* @see org.springframework.orm.jpa.LocalEntityManagerFactoryBean * @see org.springframework.orm.jpa.LocalEntityManagerFactoryBean
* @see org.springframework.orm.jpa.JpaTransactionManager * @see org.springframework.orm.jpa.JpaTransactionManager
*/ */
public class SharedEntityManagerBean extends EntityManagerFactoryAccessor implements FactoryBean, InitializingBean { public class SharedEntityManagerBean extends EntityManagerFactoryAccessor
implements FactoryBean<EntityManager>, InitializingBean {
private Class entityManagerInterface; private Class<? extends EntityManager> entityManagerInterface;
private EntityManager shared; private EntityManager shared;
/** /**
* Specify the EntityManager interface to expose. * Specify the EntityManager interface to expose.
* <p>Default is the the EntityManager interface as defined by the * <p>Default is the EntityManager interface as defined by the
* EntityManagerFactoryInfo, if available. Else, the standard * EntityManagerFactoryInfo, if available. Else, the standard
* <code>javax.persistence.EntityManager</code> interface will be used. * <code>javax.persistence.EntityManager</code> interface will be used.
* @see org.springframework.orm.jpa.EntityManagerFactoryInfo#getEntityManagerInterface() * @see org.springframework.orm.jpa.EntityManagerFactoryInfo#getEntityManagerInterface()
* @see javax.persistence.EntityManager * @see javax.persistence.EntityManager
*/ */
public void setEntityManagerInterface(Class entityManagerInterface) { public void setEntityManagerInterface(Class<? extends EntityManager> entityManagerInterface) {
Assert.notNull(entityManagerInterface, "entityManagerInterface must not be null"); Assert.notNull(entityManagerInterface, "entityManagerInterface must not be null");
Assert.isAssignable(EntityManager.class, entityManagerInterface); Assert.isAssignable(EntityManager.class, entityManagerInterface);
this.entityManagerInterface = entityManagerInterface; this.entityManagerInterface = entityManagerInterface;
@ -108,8 +109,8 @@ public class SharedEntityManagerBean extends EntityManagerFactoryAccessor implem
return this.shared; return this.shared;
} }
public Class getObjectType() { public Class<? extends EntityManager> getObjectType() {
return this.entityManagerInterface; return (this.entityManagerInterface != null ? this.entityManagerInterface : EntityManager.class);
} }
public boolean isSingleton() { public boolean isSingleton() {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2008 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -22,7 +22,6 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.jdo.JDODataStoreException; import javax.jdo.JDODataStoreException;
import javax.jdo.JDOException; import javax.jdo.JDOException;
import javax.jdo.JDOFatalDataStoreException; import javax.jdo.JDOFatalDataStoreException;
@ -125,17 +124,12 @@ public class JdoTemplateTests extends TestCase {
} }
public void testTemplateExecuteWithThreadBoundAndFlushEager() { public void testTemplateExecuteWithThreadBoundAndFlushEager() {
MockControl dialectControl = MockControl.createControl(JdoDialect.class); pm.flush();
JdoDialect dialect = (JdoDialect) dialectControl.getMock(); pmControl.setVoidCallable(1);
dialect.flush(pm);
dialectControl.setVoidCallable(1);
pmfControl.replay(); pmfControl.replay();
pmControl.replay(); pmControl.replay();
dialectControl.replay();
JdoTemplate jt = new JdoTemplate(pmf); JdoTemplate jt = new JdoTemplate(pmf);
jt.setJdoDialect(dialect);
jt.setFlushEager(true); jt.setFlushEager(true);
jt.setAllowCreate(false); jt.setAllowCreate(false);
TransactionSynchronizationManager.bindResource(pmf, new PersistenceManagerHolder(pm)); TransactionSynchronizationManager.bindResource(pmf, new PersistenceManagerHolder(pm));
@ -148,7 +142,6 @@ public class JdoTemplateTests extends TestCase {
}); });
assertTrue("Correct result list", result == l); assertTrue("Correct result list", result == l);
TransactionSynchronizationManager.unbindResource(pmf); TransactionSynchronizationManager.unbindResource(pmf);
dialectControl.verify();
} }
public void testGetObjectById() { public void testGetObjectById() {
@ -373,23 +366,17 @@ public class JdoTemplateTests extends TestCase {
} }
public void testFlushWithDialect() { public void testFlushWithDialect() {
MockControl dialectControl = MockControl.createControl(JdoDialect.class);
JdoDialect dialect = (JdoDialect) dialectControl.getMock();
pmf.getPersistenceManager(); pmf.getPersistenceManager();
pmfControl.setReturnValue(pm); pmfControl.setReturnValue(pm);
dialect.flush(pm); pm.flush();
dialectControl.setVoidCallable(1); pmControl.setVoidCallable(1);
pm.close(); pm.close();
pmControl.setVoidCallable(1); pmControl.setVoidCallable(1);
pmfControl.replay(); pmfControl.replay();
pmControl.replay(); pmControl.replay();
dialectControl.replay();
JdoTemplate jt = new JdoTemplate(pmf); JdoTemplate jt = new JdoTemplate(pmf);
jt.setJdoDialect(dialect);
jt.flush(); jt.flush();
dialectControl.verify();
} }
public void testFind() { public void testFind() {

View File

@ -23,7 +23,6 @@ import java.sql.SQLException;
import java.sql.Savepoint; import java.sql.Savepoint;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.jdo.JDOFatalDataStoreException; import javax.jdo.JDOFatalDataStoreException;
import javax.jdo.PersistenceManager; import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory; import javax.jdo.PersistenceManagerFactory;
@ -41,6 +40,8 @@ import org.springframework.beans.TestBean;
import org.springframework.jdbc.datasource.ConnectionHandle; import org.springframework.jdbc.datasource.ConnectionHandle;
import org.springframework.jdbc.datasource.ConnectionHolder; import org.springframework.jdbc.datasource.ConnectionHolder;
import org.springframework.jdbc.datasource.SimpleConnectionHandle; import org.springframework.jdbc.datasource.SimpleConnectionHandle;
import org.springframework.orm.jdo.support.SpringPersistenceManagerProxyBean;
import org.springframework.orm.jdo.support.StandardPersistenceManagerProxyBean;
import org.springframework.transaction.InvalidIsolationLevelException; import org.springframework.transaction.InvalidIsolationLevelException;
import org.springframework.transaction.MockJtaTransaction; import org.springframework.transaction.MockJtaTransaction;
import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.PlatformTransactionManager;
@ -93,13 +94,15 @@ public class JdoTransactionManagerTests extends TestCase {
public void testTransactionCommit() { public void testTransactionCommit() {
pmf.getConnectionFactory(); pmf.getConnectionFactory();
pmfControl.setReturnValue(null, 2); pmfControl.setReturnValue(null, 3);
pmf.getPersistenceManager(); pmf.getPersistenceManager();
pmfControl.setReturnValue(pm, 1); pmfControl.setReturnValue(pm, 1);
pmf.getPersistenceManagerProxy();
pmfControl.setReturnValue(pm, 1);
pm.currentTransaction(); pm.currentTransaction();
pmControl.setReturnValue(tx, 3); pmControl.setReturnValue(tx, 3);
pm.flush(); pm.flush();
pmControl.setVoidCallable(2); pmControl.setVoidCallable(4);
pm.close(); pm.close();
pmControl.setVoidCallable(1); pmControl.setVoidCallable(1);
tx.begin(); tx.begin();
@ -126,10 +129,23 @@ public class JdoTransactionManagerTests extends TestCase {
TransactionAwarePersistenceManagerFactoryProxy proxyFactory = TransactionAwarePersistenceManagerFactoryProxy proxyFactory =
new TransactionAwarePersistenceManagerFactoryProxy(); new TransactionAwarePersistenceManagerFactoryProxy();
proxyFactory.setTargetPersistenceManagerFactory(pmf); proxyFactory.setTargetPersistenceManagerFactory(pmf);
PersistenceManagerFactory proxy = (PersistenceManagerFactory) proxyFactory.getObject(); PersistenceManagerFactory pmfProxy = proxyFactory.getObject();
assertEquals(pm.toString(), proxy.getPersistenceManager().toString()); assertEquals(pm.toString(), pmfProxy.getPersistenceManager().toString());
proxy.getPersistenceManager().flush(); pmfProxy.getPersistenceManager().flush();
proxy.getPersistenceManager().close(); pmfProxy.getPersistenceManager().close();
SpringPersistenceManagerProxyBean proxyBean = new SpringPersistenceManagerProxyBean();
proxyBean.setPersistenceManagerFactory(pmf);
proxyBean.afterPropertiesSet();
PersistenceManager pmProxy = proxyBean.getObject();
assertSame(pmf, pmProxy.getPersistenceManagerFactory());
pmProxy.flush();
pmProxy.close();
StandardPersistenceManagerProxyBean stdProxyBean = new StandardPersistenceManagerProxyBean();
stdProxyBean.setPersistenceManagerFactory(pmf);
PersistenceManager stdPmProxy = stdProxyBean.getObject();
stdPmProxy.flush();
JdoTemplate jt = new JdoTemplate(pmf); JdoTemplate jt = new JdoTemplate(pmf);
return jt.execute(new JdoCallback() { return jt.execute(new JdoCallback() {