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