KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > orm > jpa > support > OpenEntityManagerInViewInterceptor


1 /*
2  * Copyright 2002-2006 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.orm.jpa.support;
18
19 import javax.persistence.EntityManager;
20 import javax.persistence.PersistenceException;
21
22 import org.springframework.dao.DataAccessException;
23 import org.springframework.dao.DataAccessResourceFailureException;
24 import org.springframework.orm.jpa.EntityManagerFactoryAccessor;
25 import org.springframework.orm.jpa.EntityManagerHolder;
26 import org.springframework.transaction.support.TransactionSynchronizationManager;
27 import org.springframework.ui.ModelMap;
28 import org.springframework.web.context.request.WebRequest;
29 import org.springframework.web.context.request.WebRequestInterceptor;
30
31 /**
32  * Spring web HandlerInterceptor that binds a JPA EntityManager to the
33  * thread for the entire processing of the request. Intended for the "Open
34  * EntityManager in View" pattern, i.e. to allow for lazy loading in
35  * web views despite the original transactions already being completed.
36  *
37  * <p>This filter works similar to the AOP JpaInterceptor: It just makes JPA
38  * EntityManagers available via the thread. It is suitable for
39  * non-transactional execution but also for middle tier transactions via
40  * JpaTransactionManager or JtaTransactionManager. In the latter case,
41  * EntityManagers pre-bound by this filter will automatically be used
42  * for the transactions.
43  *
44  * <p>In contrast to OpenEntityManagerInViewFilter, this interceptor is set
45  * up in a Spring application context and can thus take advantage of bean wiring.
46  * It derives from JpaAccessor to inherit common JPA configuration properties.
47  *
48  * @author Juergen Hoeller
49  * @since 2.0
50  * @see OpenEntityManagerInViewFilter
51  * @see org.springframework.orm.jpa.JpaInterceptor
52  * @see org.springframework.orm.jpa.JpaTransactionManager
53  * @see org.springframework.orm.jpa.JpaTemplate#execute
54  * @see org.springframework.orm.jpa.SharedEntityManagerCreator
55  * @see org.springframework.transaction.support.TransactionSynchronizationManager
56  */

57 public class OpenEntityManagerInViewInterceptor extends EntityManagerFactoryAccessor implements WebRequestInterceptor {
58
59     /**
60      * Suffix that gets appended to the EntityManagerFactory toString
61      * representation for the "participate in existing entity manager
62      * handling" request attribute.
63      * @see #getParticipateAttributeName
64      */

65     public static final String JavaDoc PARTICIPATE_SUFFIX = ".PARTICIPATE";
66
67
68     public void preHandle(WebRequest request) throws DataAccessException {
69         if (TransactionSynchronizationManager.hasResource(getEntityManagerFactory())) {
70             // do not modify the EntityManager: just mark the request accordingly
71
String JavaDoc participateAttributeName = getParticipateAttributeName();
72             Integer JavaDoc count = (Integer JavaDoc) request.getAttribute(participateAttributeName, WebRequest.SCOPE_REQUEST);
73             int newCount = (count != null) ? count.intValue() + 1 : 1;
74             request.setAttribute(getParticipateAttributeName(), new Integer JavaDoc(newCount), WebRequest.SCOPE_REQUEST);
75         }
76         else {
77             logger.debug("Opening JPA EntityManager in OpenEntityManagerInViewInterceptor");
78             try {
79                 EntityManager em = createEntityManager();
80                 TransactionSynchronizationManager.bindResource(getEntityManagerFactory(), new EntityManagerHolder(em));
81             }
82             catch (PersistenceException ex) {
83                 throw new DataAccessResourceFailureException("Could not create JPA EntityManager", ex);
84             }
85         }
86     }
87
88     public void postHandle(WebRequest request, ModelMap model) {
89     }
90
91     public void afterCompletion(WebRequest request, Exception JavaDoc ex) throws DataAccessException {
92         String JavaDoc participateAttributeName = getParticipateAttributeName();
93         Integer JavaDoc count = (Integer JavaDoc) request.getAttribute(participateAttributeName, WebRequest.SCOPE_REQUEST);
94         if (count != null) {
95             // Do not modify the EntityManager: just clear the marker.
96
if (count.intValue() > 1) {
97                 request.setAttribute(participateAttributeName, new Integer JavaDoc(count.intValue() - 1), WebRequest.SCOPE_REQUEST);
98             }
99             else {
100                 request.removeAttribute(participateAttributeName, WebRequest.SCOPE_REQUEST);
101             }
102         }
103         else {
104             EntityManagerHolder emHolder = (EntityManagerHolder)
105                     TransactionSynchronizationManager.unbindResource(getEntityManagerFactory());
106             logger.debug("Closing JPA EntityManager in OpenEntityManagerInViewInterceptor");
107             emHolder.getEntityManager().close();
108         }
109     }
110
111     /**
112      * Return the name of the request attribute that identifies that a request is
113      * already filtered. Default implementation takes the toString representation
114      * of the EntityManagerFactory instance and appends ".FILTERED".
115      * @see #PARTICIPATE_SUFFIX
116      */

117     protected String JavaDoc getParticipateAttributeName() {
118         return getEntityManagerFactory().toString() + PARTICIPATE_SUFFIX;
119     }
120
121 }
122
Popular Tags