Helper class that allows for writing JPA data access code in the same style
as with Spring's well-known JdoTemplate and HibernateTemplate classes.
Automatically converts PersistenceExceptions into Spring DataAccessExceptions,
following the
The central method is of this template is "execute", supporting JPA access code
implementing the JpaCallback interface. It provides JPA EntityManager
handling such that neither the JpaCallback implementation nor the calling code
needs to explicitly care about retrieving/closing EntityManagers, or handling
JPA lifecycle exceptions.
Can be used within a service implementation via direct instantiation with
a EntityManagerFactory reference, or get prepared in an application context
and given to services as bean reference. Note: The EntityManagerFactory should
always be configured as bean in the application context, in the first case
given to the service directly, in the second case to the prepared template.
JpaTemplate can be considered as direct alternative to working with the
native JPA EntityManager API (through a shared EntityManager reference,
as outlined above). The major advantage is its automatic conversion to
DataAccessExceptions; the major disadvantage is that it introduces
another thin layer on top of the native JPA API. Note that exception
translation can also be achieved through AOP advice; check out
org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor .
| Method from org.springframework.orm.jpa.JpaTemplate Detail: |
public boolean contains(Object entity) throws DataAccessException {
Boolean result = (Boolean) execute(new JpaCallback() {
public Object doInJpa(EntityManager em) throws PersistenceException {
return new Boolean(em.contains(entity));
}
}, true);
return result.booleanValue();
}
|
protected EntityManager createEntityManagerProxy(EntityManager em) {
Class[] ifcs = null;
EntityManagerFactory emf = getEntityManagerFactory();
if (emf instanceof EntityManagerFactoryInfo) {
Class entityManagerInterface = ((EntityManagerFactoryInfo) emf).getEntityManagerInterface();
if (entityManagerInterface != null) {
ifcs = new Class[] {entityManagerInterface};
}
}
if (ifcs == null) {
ifcs = ClassUtils.getAllInterfacesForClass(em.getClass());
}
return (EntityManager) Proxy.newProxyInstance(
em.getClass().getClassLoader(), ifcs, new CloseSuppressingInvocationHandler(em));
}
Create a close-suppressing proxy for the given JPA EntityManager.
The proxy also prepares returned JPA Query objects. |
public Object execute(JpaCallback action) throws DataAccessException {
return execute(action, isExposeNativeEntityManager());
}
|
public Object execute(JpaCallback action,
boolean exposeNativeEntityManager) throws DataAccessException {
Assert.notNull(action, "Callback object must not be null");
EntityManager em = getEntityManager();
boolean isNewEm = false;
if (em == null) {
em = getTransactionalEntityManager();
if (em == null) {
logger.debug("Creating new EntityManager for JpaTemplate execution");
em = createEntityManager();
isNewEm = true;
}
}
try {
EntityManager emToExpose = (exposeNativeEntityManager ? em : createEntityManagerProxy(em));
Object result = action.doInJpa(emToExpose);
flushIfNecessary(em, !isNewEm);
return result;
}
catch (RuntimeException ex) {
throw translateIfNecessary(ex);
}
finally {
if (isNewEm) {
logger.debug("Closing new EntityManager after JPA template execution");
EntityManagerFactoryUtils.closeEntityManager(em);
}
}
}
Execute the action specified by the given action object within a
EntityManager. |
public List executeFind(JpaCallback action) throws DataAccessException {
Object result = execute(action, isExposeNativeEntityManager());
if (!(result instanceof List)) {
throw new InvalidDataAccessApiUsageException(
"Result object returned from JpaCallback isn't a List: [" + result + "]");
}
return (List) result;
}
|
public List find(String queryString) throws DataAccessException {
return find(queryString, (Object[]) null);
}
|
public T find(Class entityClass,
Object id) throws DataAccessException {
return (T) execute(new JpaCallback() {
public Object doInJpa(EntityManager em) throws PersistenceException {
return em.find(entityClass, id);
}
}, true);
}
|
public List find(String queryString,
Object values) throws DataAccessException {
return executeFind(new JpaCallback() {
public Object doInJpa(EntityManager em) throws PersistenceException {
Query queryObject = em.createQuery(queryString);
if (values != null) {
for (int i = 0; i < values.length; i++) {
queryObject.setParameter(i + 1, values[i]);
}
}
return queryObject.getResultList();
}
});
}
|
public List findByNamedParams(String queryString,
Map params) throws DataAccessException {
return executeFind(new JpaCallback() {
public Object doInJpa(EntityManager em) throws PersistenceException {
Query queryObject = em.createQuery(queryString);
if (params != null) {
for (Map.Entry< String, ? > entry : params.entrySet()) {
queryObject.setParameter(entry.getKey(), entry.getValue());
}
}
return queryObject.getResultList();
}
});
}
|
public List findByNamedQuery(String queryName) throws DataAccessException {
return findByNamedQuery(queryName, (Object[]) null);
}
|
public List findByNamedQuery(String queryName,
Object values) throws DataAccessException {
return executeFind(new JpaCallback() {
public Object doInJpa(EntityManager em) throws PersistenceException {
Query queryObject = em.createNamedQuery(queryName);
if (values != null) {
for (int i = 0; i < values.length; i++) {
queryObject.setParameter(i + 1, values[i]);
}
}
return queryObject.getResultList();
}
});
}
|
public List findByNamedQueryAndNamedParams(String queryName,
Map params) throws DataAccessException {
return executeFind(new JpaCallback() {
public Object doInJpa(EntityManager em) throws PersistenceException {
Query queryObject = em.createNamedQuery(queryName);
if (params != null) {
for (Map.Entry< String, ? > entry : params.entrySet()) {
queryObject.setParameter(entry.getKey(), entry.getValue());
}
}
return queryObject.getResultList();
}
});
}
|
public void flush() throws DataAccessException {
execute(new JpaCallback() {
public Object doInJpa(EntityManager em) throws PersistenceException {
em.flush();
return null;
}
}, true);
}
|
public T getReference(Class entityClass,
Object id) throws DataAccessException {
return (T) execute(new JpaCallback() {
public Object doInJpa(EntityManager em) throws PersistenceException {
return em.getReference(entityClass, id);
}
}, true);
}
|
public boolean isExposeNativeEntityManager() {
return this.exposeNativeEntityManager;
}
Return whether to expose the native JPA EntityManager to JpaCallback
code, or rather an EntityManager proxy. |
public T merge(T entity) throws DataAccessException {
return (T) execute(new JpaCallback() {
public Object doInJpa(EntityManager em) throws PersistenceException {
return em.merge(entity);
}
}, true);
}
|
public void persist(Object entity) throws DataAccessException {
execute(new JpaCallback() {
public Object doInJpa(EntityManager em) throws PersistenceException {
em.persist(entity);
return null;
}
}, true);
}
|
public void refresh(Object entity) throws DataAccessException {
execute(new JpaCallback() {
public Object doInJpa(EntityManager em) throws PersistenceException {
em.refresh(entity);
return null;
}
}, true);
}
|
public void remove(Object entity) throws DataAccessException {
execute(new JpaCallback() {
public Object doInJpa(EntityManager em) throws PersistenceException {
em.remove(entity);
return null;
}
}, true);
}
|
public void setExposeNativeEntityManager(boolean exposeNativeEntityManager) {
this.exposeNativeEntityManager = exposeNativeEntityManager;
}
Set whether to expose the native JPA EntityManager to JpaCallback
code. Default is "false": a EntityManager proxy will be returned,
suppressing close calls and automatically applying transaction
timeouts (if any).
As there is often a need to cast to a provider-specific EntityManager
class in DAOs that use the JPA 1.0 API, for JPA 2.0 previews and other
provider-specific functionality, the exposed proxy implements all interfaces
implemented by the original EntityManager. If this is not sufficient,
turn this flag to "true". |