Source Code Cross Referenced for JpaTemplate.java in  » J2EE » spring-framework-2.5 » org » springframework » orm » jpa » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » spring framework 2.5 » org.springframework.orm.jpa 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2002-2007 the original author or authors.
003:         *
004:         * Licensed under the Apache License, Version 2.0 (the "License");
005:         * you may not use this file except in compliance with the License.
006:         * You may obtain a copy of the License at
007:         *
008:         *      http://www.apache.org/licenses/LICENSE-2.0
009:         *
010:         * Unless required by applicable law or agreed to in writing, software
011:         * distributed under the License is distributed on an "AS IS" BASIS,
012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013:         * See the License for the specific language governing permissions and
014:         * limitations under the License.
015:         */
016:
017:        package org.springframework.orm.jpa;
018:
019:        import java.lang.reflect.InvocationHandler;
020:        import java.lang.reflect.InvocationTargetException;
021:        import java.lang.reflect.Method;
022:        import java.lang.reflect.Proxy;
023:        import java.util.Iterator;
024:        import java.util.List;
025:        import java.util.Map;
026:
027:        import javax.persistence.EntityManager;
028:        import javax.persistence.EntityManagerFactory;
029:        import javax.persistence.PersistenceException;
030:        import javax.persistence.Query;
031:
032:        import org.springframework.dao.DataAccessException;
033:        import org.springframework.dao.InvalidDataAccessApiUsageException;
034:        import org.springframework.util.Assert;
035:        import org.springframework.util.ClassUtils;
036:
037:        /**
038:         * Helper class that allows for writing JPA data access code in the same style
039:         * as with Spring's well-known JdoTemplate and HibernateTemplate classes.
040:         * Automatically converts PersistenceExceptions into Spring DataAccessExceptions,
041:         * following the <code>org.springframework.dao</code> exception hierarchy.
042:         *
043:         * <p>The central method is of this template is "execute", supporting JPA access code
044:         * implementing the {@link JpaCallback} interface. It provides JPA EntityManager
045:         * handling such that neither the JpaCallback implementation nor the calling code
046:         * needs to explicitly care about retrieving/closing EntityManagers, or handling
047:         * JPA lifecycle exceptions.
048:         *
049:         * <p>Can be used within a service implementation via direct instantiation with
050:         * a EntityManagerFactory reference, or get prepared in an application context
051:         * and given to services as bean reference. Note: The EntityManagerFactory should
052:         * always be configured as bean in the application context, in the first case
053:         * given to the service directly, in the second case to the prepared template.
054:         *
055:         * <p><b>NOTE: JpaTemplate mainly exists as a sibling of JdoTemplate and
056:         * HibernateTemplate, offering the same style for people used to it. For newly
057:         * started projects, consider adopting the standard JPA style of coding data
058:         * access objects instead, based on a "shared EntityManager" reference injected
059:         * via a Spring bean definition or the JPA PersistenceContext annotation.</b>
060:         * (Using Spring's SharedEntityManagerBean / PersistenceAnnotationBeanPostProcessor,
061:         * or using a direct JNDI lookup for an EntityManager on a Java EE 5 server.)
062:         *
063:         * <p>JpaTemplate can be considered as direct alternative to working with the
064:         * native JPA EntityManager API (through a shared EntityManager reference,
065:         * as outlined above). The major advantage is its automatic conversion to
066:         * DataAccessExceptions; the major disadvantage is that it introduces
067:         * another thin layer on top of the native JPA API. Note that exception
068:         * translation can also be achieved through AOP advice; check out
069:         * {@link org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor}.
070:         *
071:         * <p>{@link LocalContainerEntityManagerFactoryBean} is the preferred way of
072:         * obtaining a reference to an EntityManagerFactory, at least outside of a full
073:         * Java EE 5 environment. The Spring application context will manage its lifecycle,
074:         * initializing and shutting down the factory as part of the application.
075:         * Within a Java EE 5 environment, you will typically work with a server-managed
076:         * EntityManagerFactory that is exposed via JNDI, obtained through Spring's
077:         * {@link org.springframework.jndi.JndiObjectFactoryBean}.
078:         *
079:         * @author Juergen Hoeller
080:         * @since 2.0
081:         * @see #setEntityManagerFactory
082:         * @see JpaCallback
083:         * @see javax.persistence.EntityManager
084:         * @see LocalEntityManagerFactoryBean
085:         * @see LocalContainerEntityManagerFactoryBean
086:         * @see JpaTransactionManager
087:         * @see org.springframework.transaction.jta.JtaTransactionManager
088:         * @see org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
089:         * @see org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor
090:         */
091:        public class JpaTemplate extends JpaAccessor implements  JpaOperations {
092:
093:            private boolean exposeNativeEntityManager = false;
094:
095:            /**
096:             * Create a new JpaTemplate instance.
097:             */
098:            public JpaTemplate() {
099:            }
100:
101:            /**
102:             * Create a new JpaTemplate instance.
103:             * @param emf EntityManagerFactory to create EntityManagers
104:             */
105:            public JpaTemplate(EntityManagerFactory emf) {
106:                setEntityManagerFactory(emf);
107:                afterPropertiesSet();
108:            }
109:
110:            /**
111:             * Create a new JpaTemplate instance.
112:             * @param em EntityManager to use
113:             */
114:            public JpaTemplate(EntityManager em) {
115:                setEntityManager(em);
116:                afterPropertiesSet();
117:            }
118:
119:            /**
120:             * Set whether to expose the native JPA EntityManager to JpaCallback
121:             * code. Default is "false": a EntityManager proxy will be returned,
122:             * suppressing <code>close</code> calls and automatically applying transaction
123:             * timeouts (if any).
124:             * <p>As there is often a need to cast to a provider-specific EntityManager
125:             * class in DAOs that use the JPA 1.0 API, for JPA 2.0 previews and other
126:             * provider-specific functionality, the exposed proxy implements all interfaces
127:             * implemented by the original EntityManager. If this is not sufficient,
128:             * turn this flag to "true".
129:             * @see JpaCallback
130:             * @see javax.persistence.EntityManager
131:             */
132:            public void setExposeNativeEntityManager(
133:                    boolean exposeNativeEntityManager) {
134:                this .exposeNativeEntityManager = exposeNativeEntityManager;
135:            }
136:
137:            /**
138:             * Return whether to expose the native JPA EntityManager to JpaCallback
139:             * code, or rather an EntityManager proxy.
140:             */
141:            public boolean isExposeNativeEntityManager() {
142:                return this .exposeNativeEntityManager;
143:            }
144:
145:            public Object execute(JpaCallback action)
146:                    throws DataAccessException {
147:                return execute(action, isExposeNativeEntityManager());
148:            }
149:
150:            public List executeFind(JpaCallback action)
151:                    throws DataAccessException {
152:                Object result = execute(action, isExposeNativeEntityManager());
153:                if (!(result instanceof  List)) {
154:                    throw new InvalidDataAccessApiUsageException(
155:                            "Result object returned from JpaCallback isn't a List: ["
156:                                    + result + "]");
157:                }
158:                return (List) result;
159:            }
160:
161:            /**
162:             * Execute the action specified by the given action object within a
163:             * EntityManager.
164:             * @param action callback object that specifies the JPA action
165:             * @param exposeNativeEntityManager whether to expose the native
166:             * JPA entity manager to callback code
167:             * @return a result object returned by the action, or <code>null</code>
168:             * @throws org.springframework.dao.DataAccessException in case of JPA errors
169:             */
170:            public Object execute(JpaCallback action,
171:                    boolean exposeNativeEntityManager)
172:                    throws DataAccessException {
173:                Assert.notNull(action, "Callback object must not be null");
174:
175:                EntityManager em = getEntityManager();
176:                boolean isNewEm = false;
177:                if (em == null) {
178:                    em = getTransactionalEntityManager();
179:                    if (em == null) {
180:                        logger
181:                                .debug("Creating new EntityManager for JpaTemplate execution");
182:                        em = createEntityManager();
183:                        isNewEm = true;
184:                    }
185:                }
186:
187:                try {
188:                    EntityManager emToExpose = (exposeNativeEntityManager ? em
189:                            : createEntityManagerProxy(em));
190:                    Object result = action.doInJpa(emToExpose);
191:                    flushIfNecessary(em, !isNewEm);
192:                    return result;
193:                } catch (RuntimeException ex) {
194:                    throw translateIfNecessary(ex);
195:                } finally {
196:                    if (isNewEm) {
197:                        logger
198:                                .debug("Closing new EntityManager after JPA template execution");
199:                        em.close();
200:                    }
201:                }
202:            }
203:
204:            /**
205:             * Create a close-suppressing proxy for the given JPA EntityManager.
206:             * The proxy also prepares returned JPA Query objects.
207:             * @param em the JPA EntityManager to create a proxy for
208:             * @return the EntityManager proxy, implementing all interfaces
209:             * implemented by the passed-in EntityManager object (that is,
210:             * also implementing all provider-specific extension interfaces)
211:             * @see javax.persistence.EntityManager#close
212:             */
213:            protected EntityManager createEntityManagerProxy(EntityManager em) {
214:                Class[] ifcs = ClassUtils.getAllInterfaces(em);
215:                return (EntityManager) Proxy.newProxyInstance(getClass()
216:                        .getClassLoader(), ifcs,
217:                        new CloseSuppressingInvocationHandler(em));
218:            }
219:
220:            //-------------------------------------------------------------------------
221:            // Convenience methods for load, save, delete
222:            //-------------------------------------------------------------------------
223:
224:            public <T> T find(final Class<T> entityClass, final Object id)
225:                    throws DataAccessException {
226:                return (T) execute(new JpaCallback() {
227:                    public Object doInJpa(EntityManager em)
228:                            throws PersistenceException {
229:                        return em.find(entityClass, id);
230:                    }
231:                }, true);
232:            }
233:
234:            public <T> T getReference(final Class<T> entityClass,
235:                    final Object id) throws DataAccessException {
236:                return (T) execute(new JpaCallback() {
237:                    public Object doInJpa(EntityManager em)
238:                            throws PersistenceException {
239:                        return em.getReference(entityClass, id);
240:                    }
241:                }, true);
242:            }
243:
244:            public boolean contains(final Object entity)
245:                    throws DataAccessException {
246:                Boolean result = (Boolean) execute(new JpaCallback() {
247:                    public Object doInJpa(EntityManager em)
248:                            throws PersistenceException {
249:                        return new Boolean(em.contains(entity));
250:                    }
251:                }, true);
252:                return result.booleanValue();
253:            }
254:
255:            public void refresh(final Object entity) throws DataAccessException {
256:                execute(new JpaCallback() {
257:                    public Object doInJpa(EntityManager em)
258:                            throws PersistenceException {
259:                        em.refresh(entity);
260:                        return null;
261:                    }
262:                }, true);
263:            }
264:
265:            public void persist(final Object entity) throws DataAccessException {
266:                execute(new JpaCallback() {
267:                    public Object doInJpa(EntityManager em)
268:                            throws PersistenceException {
269:                        em.persist(entity);
270:                        return null;
271:                    }
272:                }, true);
273:            }
274:
275:            public <T> T merge(final T entity) throws DataAccessException {
276:                return (T) execute(new JpaCallback() {
277:                    public Object doInJpa(EntityManager em)
278:                            throws PersistenceException {
279:                        return em.merge(entity);
280:                    }
281:                }, true);
282:            }
283:
284:            public void remove(final Object entity) throws DataAccessException {
285:                execute(new JpaCallback() {
286:                    public Object doInJpa(EntityManager em)
287:                            throws PersistenceException {
288:                        em.remove(entity);
289:                        return null;
290:                    }
291:                }, true);
292:            }
293:
294:            public void flush() throws DataAccessException {
295:                execute(new JpaCallback() {
296:                    public Object doInJpa(EntityManager em)
297:                            throws PersistenceException {
298:                        em.flush();
299:                        return null;
300:                    }
301:                }, true);
302:            }
303:
304:            //-------------------------------------------------------------------------
305:            // Convenience finder methods
306:            //-------------------------------------------------------------------------
307:
308:            public List find(String queryString) throws DataAccessException {
309:                return find(queryString, (Object[]) null);
310:            }
311:
312:            public List find(final String queryString, final Object... values)
313:                    throws DataAccessException {
314:                return executeFind(new JpaCallback() {
315:                    public Object doInJpa(EntityManager em)
316:                            throws PersistenceException {
317:                        Query queryObject = em.createQuery(queryString);
318:                        if (values != null) {
319:                            for (int i = 0; i < values.length; i++) {
320:                                queryObject.setParameter(i + 1, values[i]);
321:                            }
322:                        }
323:                        return queryObject.getResultList();
324:                    }
325:                });
326:            }
327:
328:            public List findByNamedParams(final String queryString,
329:                    final Map<String, ? extends Object> params)
330:                    throws DataAccessException {
331:                return executeFind(new JpaCallback() {
332:                    public Object doInJpa(EntityManager em)
333:                            throws PersistenceException {
334:                        Query queryObject = em.createQuery(queryString);
335:                        if (params != null) {
336:                            for (Iterator it = params.entrySet().iterator(); it
337:                                    .hasNext();) {
338:                                Map.Entry<String, Object> entry = (Map.Entry<String, Object>) it
339:                                        .next();
340:                                queryObject.setParameter(entry.getKey(), entry
341:                                        .getValue());
342:                            }
343:                        }
344:                        return queryObject.getResultList();
345:                    }
346:                });
347:            }
348:
349:            public List findByNamedQuery(String queryName)
350:                    throws DataAccessException {
351:                return findByNamedQuery(queryName, (Object[]) null);
352:            }
353:
354:            public List findByNamedQuery(final String queryName,
355:                    final Object... values) throws DataAccessException {
356:                return executeFind(new JpaCallback() {
357:                    public Object doInJpa(EntityManager em)
358:                            throws PersistenceException {
359:                        Query queryObject = em.createNamedQuery(queryName);
360:                        if (values != null) {
361:                            for (int i = 0; i < values.length; i++) {
362:                                queryObject.setParameter(i + 1, values[i]);
363:                            }
364:                        }
365:                        return queryObject.getResultList();
366:                    }
367:                });
368:            }
369:
370:            public List findByNamedQueryAndNamedParams(final String queryName,
371:                    final Map<String, ? extends Object> params)
372:                    throws DataAccessException {
373:
374:                return executeFind(new JpaCallback() {
375:                    public Object doInJpa(EntityManager em)
376:                            throws PersistenceException {
377:                        Query queryObject = em.createNamedQuery(queryName);
378:                        if (params != null) {
379:                            for (Iterator it = params.entrySet().iterator(); it
380:                                    .hasNext();) {
381:                                Map.Entry<String, Object> entry = (Map.Entry<String, Object>) it
382:                                        .next();
383:                                queryObject.setParameter(entry.getKey(), entry
384:                                        .getValue());
385:                            }
386:                        }
387:                        return queryObject.getResultList();
388:                    }
389:                });
390:            }
391:
392:            /**
393:             * Invocation handler that suppresses close calls on JPA EntityManagers.
394:             * Also prepares returned Query and Criteria objects.
395:             * @see javax.persistence.EntityManager#close
396:             */
397:            private class CloseSuppressingInvocationHandler implements 
398:                    InvocationHandler {
399:
400:                private final EntityManager target;
401:
402:                public CloseSuppressingInvocationHandler(EntityManager target) {
403:                    this .target = target;
404:                }
405:
406:                public Object invoke(Object proxy, Method method, Object[] args)
407:                        throws Throwable {
408:                    // Invocation on EntityManager interface (or provider-specific extension) coming in...
409:
410:                    if (method.getName().equals("equals")) {
411:                        // Only consider equal when proxies are identical.
412:                        return (proxy == args[0] ? Boolean.TRUE : Boolean.FALSE);
413:                    } else if (method.getName().equals("hashCode")) {
414:                        // Use hashCode of EntityManager proxy.
415:                        return new Integer(hashCode());
416:                    } else if (method.getName().equals("close")) {
417:                        // Handle close method: suppress, not valid.
418:                        return null;
419:                    }
420:
421:                    // Invoke method on target EntityManager.
422:                    try {
423:                        return method.invoke(this .target, args);
424:                    } catch (InvocationTargetException ex) {
425:                        throw ex.getTargetException();
426:                    }
427:                }
428:            }
429:
430:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.