KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > util > EntityManagerWrapper


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.enterprise.util;
24
25 import java.io.Serializable JavaDoc;
26 import java.util.logging.*;
27 import java.util.Map JavaDoc;
28
29 import javax.persistence.*;
30
31 import com.sun.enterprise.Switch;
32 import com.sun.enterprise.J2EETransactionManager;
33 import com.sun.enterprise.distributedtx.J2EETransaction;
34 import com.sun.ejb.ContainerFactory;
35 import com.sun.enterprise.deployment.types.EntityManagerReference;
36
37 import com.sun.logging.*;
38
39 /**
40  * Implementation of a container-managed entity manager.
41  * A new instance of this class will be created for each injected
42  * EntityManager reference or each lookup of an EntityManager
43  * reference within the component jndi environment.
44  * The underlying EntityManager object does not support concurrent access.
45  * Likewise, this wrapper does not support concurrent access.
46  *
47  * @author Kenneth Saks
48  */

49 public class EntityManagerWrapper implements EntityManager, Serializable JavaDoc {
50
51     static Logger _logger=LogDomains.getLogger(LogDomains.UTIL_LOGGER);
52
53     static private LocalStringManagerImpl localStrings =
54         new LocalStringManagerImpl(EntityManagerWrapper.class);
55
56     // Serializable state
57

58     private String JavaDoc unitName;
59     private PersistenceContextType contextType;
60     private Map JavaDoc emProperties;
61
62     // transient state
63

64     transient private EntityManagerFactory entityManagerFactory;
65     transient private J2EETransactionManager txManager;
66     transient private ContainerFactory containerFactory;
67     
68     // Only used to cache entity manager with EXTENDED persistence context
69
transient private EntityManager extendedEntityManager;
70
71     // set and cleared after each non-tx, non EXTENDED call to _getDelegate()
72
transient private EntityManager nonTxEntityManager;
73
74     public EntityManagerWrapper(EntityManagerReference
75                                 referenceDescriptor) {
76         this.unitName = referenceDescriptor.getUnitName();
77         this.contextType = referenceDescriptor.getPersistenceContextType();
78         this.emProperties = referenceDescriptor.getProperties();
79     }
80
81     private void init() {
82
83         entityManagerFactory = EntityManagerFactoryWrapper.
84             lookupEntityManagerFactory(unitName);
85         
86         if( entityManagerFactory == null ) {
87             throw new IllegalStateException JavaDoc
88                 ("Unable to retrieve EntityManagerFactory for unitName "
89                  + unitName);
90         }
91         
92         txManager = Switch.getSwitch().getTransactionManager();
93         containerFactory = Switch.getSwitch().getContainerFactory();
94
95     }
96
97     private void doTransactionScopedTxCheck() {
98         
99         if( contextType != PersistenceContextType.TRANSACTION) {
100             return;
101         }
102         
103         doTxRequiredCheck();
104
105     }
106
107     private void doTxRequiredCheck() {
108
109         if( entityManagerFactory == null ) {
110             init();
111         }
112
113         J2EETransaction tx = null;
114         try {
115             tx = (J2EETransaction) txManager.getTransaction();
116         } catch(Exception JavaDoc e) {
117             throw new IllegalStateException JavaDoc("exception retrieving tx", e);
118         }
119             
120         if( tx == null ) {
121             throw new TransactionRequiredException();
122         }
123
124     }
125     private EntityManager _getDelegate() {
126
127         // Populate any transient objects the first time
128
// this method is called.
129

130         if( entityManagerFactory == null ) {
131             init();
132         }
133
134         EntityManager delegate = null;
135
136         if( nonTxEntityManager != null ) {
137             cleanupNonTxEntityManager();
138         }
139
140         if( contextType == PersistenceContextType.TRANSACTION ) {
141
142             J2EETransaction tx = null;
143             try {
144                 tx = (J2EETransaction) txManager.getTransaction();
145             } catch(Exception JavaDoc e) {
146                 throw new IllegalStateException JavaDoc("exception retrieving tx", e);
147             }
148             
149             if( tx != null ) {
150
151                 // If there is an active extended persistence context
152
// for the same entity manager factory and the same tx,
153
// it takes precendence.
154
delegate = tx.getExtendedEntityManager(entityManagerFactory);
155
156                 if( delegate == null ) {
157
158                     delegate = tx.getTxEntityManager(entityManagerFactory);
159
160                     if( delegate == null ) {
161
162                         // If there is a transaction and this is the first
163
// access of the wrapped entity manager, create an
164
// actual entity manager and associate it with the
165
// entity manager factory.
166
delegate = entityManagerFactory.
167                             createEntityManager(emProperties);
168
169                         tx.addTxEntityManagerMapping(entityManagerFactory,
170                                                      delegate);
171                     }
172                 }
173
174             } else {
175
176                 nonTxEntityManager = entityManagerFactory.createEntityManager
177                     (emProperties);
178
179                 // Return a new non-transactional entity manager.
180
delegate = nonTxEntityManager;
181                     
182             }
183
184         } else {
185
186             // EXTENDED Persitence Context
187

188             if( extendedEntityManager == null ) {
189                 extendedEntityManager = containerFactory.
190                     lookupExtendedEntityManager(entityManagerFactory);
191                     
192             }
193       
194             delegate = extendedEntityManager;
195
196         }
197         
198         if( _logger.isLoggable(Level.FINE) ) {
199             _logger.fine("In EntityManagerWrapper::_getDelegate(). " +
200                          "Logical entity manager = " + this);
201             _logger.fine("Physical entity manager = " + delegate);
202         }
203
204         return delegate;
205
206     }
207     
208     private void cleanupNonTxEntityManager() {
209         if( nonTxEntityManager != null ) {
210             nonTxEntityManager.close();
211             nonTxEntityManager = null;
212         }
213     }
214
215     public void persist(Object JavaDoc entity) {
216         doTransactionScopedTxCheck();
217         _getDelegate().persist(entity);
218
219         // tx is required so there's no need to do any non-tx cleanup
220
}
221
222     public <T> T merge(T entity) {
223         doTransactionScopedTxCheck();
224         return _getDelegate().merge(entity);
225
226         // tx is required so there's no need to do any non-tx cleanup
227
}
228
229     public void remove(Object JavaDoc entity) {
230         doTransactionScopedTxCheck();
231         _getDelegate().remove(entity);
232
233         // tx is required so there's no need to do any non-tx cleanup
234
}
235
236     public <T> T find(Class JavaDoc<T> entityClass, Object JavaDoc primaryKey) {
237         T returnValue = null;
238         try {
239             returnValue = _getDelegate().find(entityClass, primaryKey);
240         } finally {
241             if( nonTxEntityManager != null ) {
242                 cleanupNonTxEntityManager();
243             }
244         }
245         return returnValue;
246     }
247
248     public <T> T getReference(Class JavaDoc<T> entityClass, Object JavaDoc primaryKey) {
249         T returnValue = null;
250         try {
251             returnValue = _getDelegate().getReference(entityClass, primaryKey);
252         } finally {
253             if( nonTxEntityManager != null ) {
254                 cleanupNonTxEntityManager();
255             }
256         }
257         return returnValue;
258     }
259
260     public void flush() {
261         // tx is ALWAYS required, regardless of persistence context type.
262
doTxRequiredCheck();
263         _getDelegate().flush();
264
265         // tx is required so there's no need to do any non-tx cleanup
266
}
267
268     public Query createQuery(String JavaDoc ejbqlString) {
269         Query returnValue = null;
270         try {
271             EntityManager delegate = _getDelegate();
272             returnValue = delegate.createQuery(ejbqlString);
273
274             if( nonTxEntityManager != null ) {
275                 Query queryDelegate = returnValue;
276                 returnValue = QueryWrapper.createQueryWrapper
277                     (entityManagerFactory, emProperties, delegate,
278                      queryDelegate, ejbqlString);
279                 // It's now the responsibility of the QueryWrapper to
280
// close the non-tx EM delegate
281
nonTxEntityManager = null;
282             }
283         } catch(RuntimeException JavaDoc re) {
284             if( nonTxEntityManager != null ) {
285                 cleanupNonTxEntityManager();
286             }
287             throw re;
288         }
289         return returnValue;
290     }
291
292     public Query createNamedQuery(String JavaDoc name) {
293         Query returnValue = null;
294         try {
295             EntityManager delegate = _getDelegate();
296             returnValue = delegate.createNamedQuery(name);
297
298             if( nonTxEntityManager != null ) {
299                 Query queryDelegate = returnValue;
300                 returnValue = QueryWrapper.createNamedQueryWrapper
301                     (entityManagerFactory, emProperties, delegate,
302                      queryDelegate, name);
303                 // It's now the responsibility of the QueryWrapper to
304
// close the non-tx EM delegate
305
nonTxEntityManager = null;
306             }
307         } catch(RuntimeException JavaDoc re) {
308             if( nonTxEntityManager != null ) {
309                 cleanupNonTxEntityManager();
310             }
311             throw re;
312         }
313
314         return returnValue;
315     }
316
317     public Query createNativeQuery(String JavaDoc sqlString) {
318         Query returnValue = null;
319         try {
320             EntityManager delegate = _getDelegate();
321             returnValue = delegate.createNativeQuery(sqlString);
322
323             if( nonTxEntityManager != null ) {
324                 Query queryDelegate = returnValue;
325                 returnValue = QueryWrapper.createNativeQueryWrapper
326                     (entityManagerFactory, emProperties, delegate,
327                      queryDelegate, sqlString);
328                 // It's now the responsibility of the QueryWrapper to
329
// close the non-tx EM delegate
330
nonTxEntityManager = null;
331             }
332         } catch(RuntimeException JavaDoc re) {
333             if( nonTxEntityManager != null ) {
334                 cleanupNonTxEntityManager();
335             }
336             throw re;
337         }
338         return returnValue;
339     }
340
341     public Query createNativeQuery(String JavaDoc sqlString, Class JavaDoc resultClass) {
342         Query returnValue = null;
343         try {
344             EntityManager delegate = _getDelegate();
345             returnValue = delegate.createNativeQuery(sqlString, resultClass);
346
347             if( nonTxEntityManager != null ) {
348                 Query queryDelegate = returnValue;
349                 returnValue = QueryWrapper.createNativeQueryWrapper
350                     (entityManagerFactory, emProperties, delegate,
351                      queryDelegate, sqlString, resultClass);
352                 // It's now the responsibility of the QueryWrapper to
353
// close the non-tx EM delegate
354
nonTxEntityManager = null;
355             }
356         } catch(RuntimeException JavaDoc re) {
357             if( nonTxEntityManager != null ) {
358                 cleanupNonTxEntityManager();
359             }
360             throw re;
361         }
362         return returnValue;
363     }
364
365     public Query createNativeQuery(String JavaDoc sqlString, String JavaDoc resultSetMapping) {
366         Query returnValue = null;
367         try {
368             EntityManager delegate = _getDelegate();
369             returnValue = delegate.createNativeQuery
370                 (sqlString, resultSetMapping);
371
372             if( nonTxEntityManager != null ) {
373                 Query queryDelegate = returnValue;
374                 returnValue = QueryWrapper.createNativeQueryWrapper
375                     (entityManagerFactory, emProperties, delegate,
376                      queryDelegate, sqlString, resultSetMapping);
377                 // It's now the responsibility of the QueryWrapper to
378
// close the non-tx EM delegate
379
nonTxEntityManager = null;
380             }
381         } catch(RuntimeException JavaDoc re) {
382             if( nonTxEntityManager != null ) {
383                 cleanupNonTxEntityManager();
384             }
385             throw re;
386         }
387         return returnValue;
388     }
389
390     public void refresh(Object JavaDoc entity) {
391         doTransactionScopedTxCheck();
392         _getDelegate().refresh(entity);
393
394         // tx is required so there's no need to do any non-tx cleanup
395
}
396
397     public boolean contains(Object JavaDoc entity) {
398         try {
399             EntityManager delegate = _getDelegate();
400             return delegate.contains(entity);
401         } finally {
402             if( nonTxEntityManager != null ) {
403                 cleanupNonTxEntityManager();
404             }
405         }
406     }
407
408     public void close() {
409         // close() not allowed on container-managed EMs.
410
throw new IllegalStateException JavaDoc();
411     }
412
413     public boolean isOpen() {
414         // Not relevant for container-managed EMs. Just return true.
415
return true;
416     }
417
418     public EntityTransaction getTransaction() {
419         try {
420             return _getDelegate().getTransaction();
421         } finally {
422             if( nonTxEntityManager != null ) {
423                 cleanupNonTxEntityManager();
424             }
425         }
426     }
427
428     public void lock(Object JavaDoc entity, LockModeType lockMode) {
429         try {
430             _getDelegate().lock(entity, lockMode);
431         } finally {
432             if( nonTxEntityManager != null ) {
433                 cleanupNonTxEntityManager();
434             }
435         }
436     }
437
438     public void clear() {
439         try {
440             _getDelegate().clear();
441         } finally {
442             if( nonTxEntityManager != null ) {
443                 cleanupNonTxEntityManager();
444             }
445         }
446     }
447
448     public Object JavaDoc getDelegate() {
449         try {
450             return _getDelegate();
451         } finally {
452             if( nonTxEntityManager != null ) {
453                 // In this case we can't close the physical EntityManager
454
// before returning it to the application, so we just clear
455
// the EM wrapper's reference to it.
456
nonTxEntityManager = null;
457             }
458         }
459
460     }
461
462     public FlushModeType getFlushMode() {
463         try {
464             return _getDelegate().getFlushMode();
465         } finally {
466             if( nonTxEntityManager != null ) {
467                 cleanupNonTxEntityManager();
468             }
469         }
470     }
471
472     public void setFlushMode(FlushModeType flushMode) {
473         try {
474             _getDelegate().setFlushMode(flushMode);
475         } finally {
476             if( nonTxEntityManager != null ) {
477                 cleanupNonTxEntityManager();
478             }
479         }
480     }
481
482     public void joinTransaction() {
483         // Doesn't apply to the container-managed case, but all the
484
// spec says is that an exception should be thrown if called
485
// without a tx.
486
doTxRequiredCheck();
487
488         // There's no point in calling anything on the physical
489
// entity manager since in all tx cases it will be
490
// correctly associated with a tx already.
491
}
492
493 }
494
Popular Tags