KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * Copyright 2002-2007 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 java.beans.PropertyDescriptor JavaDoc;
20 import java.lang.reflect.AccessibleObject JavaDoc;
21 import java.lang.reflect.Field JavaDoc;
22 import java.lang.reflect.InvocationTargetException JavaDoc;
23 import java.lang.reflect.Method JavaDoc;
24 import java.util.HashMap JavaDoc;
25 import java.util.LinkedList JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.Map JavaDoc;
28 import java.util.Properties JavaDoc;
29
30 import javax.naming.NamingException JavaDoc;
31 import javax.persistence.EntityManager;
32 import javax.persistence.EntityManagerFactory;
33 import javax.persistence.PersistenceContext;
34 import javax.persistence.PersistenceContextType;
35 import javax.persistence.PersistenceProperty;
36 import javax.persistence.PersistenceUnit;
37
38 import org.apache.commons.logging.Log;
39 import org.apache.commons.logging.LogFactory;
40
41 import org.springframework.beans.BeansException;
42 import org.springframework.beans.PropertyValues;
43 import org.springframework.beans.factory.BeanFactory;
44 import org.springframework.beans.factory.BeanFactoryAware;
45 import org.springframework.beans.factory.BeanFactoryUtils;
46 import org.springframework.beans.factory.ListableBeanFactory;
47 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
48 import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
49 import org.springframework.jndi.JndiLocatorSupport;
50 import org.springframework.orm.jpa.EntityManagerFactoryInfo;
51 import org.springframework.orm.jpa.ExtendedEntityManagerCreator;
52 import org.springframework.orm.jpa.SharedEntityManagerCreator;
53 import org.springframework.util.ObjectUtils;
54 import org.springframework.util.ReflectionUtils;
55 import org.springframework.util.StringUtils;
56
57 /**
58  * BeanPostProcessor that processes {@link javax.persistence.PersistenceUnit}
59  * and {@link javax.persistence.PersistenceContext} annotations, for injection of
60  * the corresponding JPA resources {@link javax.persistence.EntityManagerFactory}
61  * and {@link javax.persistence.EntityManager}. Any such annotated fields or methods
62  * in any Spring-managed object will automatically be injected.
63  *
64  * <p>This post-processor will inject sub-interfaces of <code>EntityManagerFactory</code>
65  * and <code>EntityManager</code> if the annotated fields or methods are declared as such.
66  * The actual type will be verified early, with the exception of a shared ("transactional")
67  * <code>EntityManager</code> reference, where type mismatches might be detected as late
68  * as on the first actual invocation.
69  *
70  * <p>Note: In the present implementation, PersistenceAnnotationBeanPostProcessor
71  * only supports <code>@PersistenceUnit</code> and <code>@PersistenceContext</code>
72  * with the "unitName" attribute, or no attribute at all (for the default unit).
73  * If those annotations are present with the "name" attribute at the class level,
74  * they will simply be ignored, since those only serve as deployment hint
75  * (as per the Java EE 5 specification).
76  *
77  * <p>This post-processor can either obtain EntityManagerFactory beans defined
78  * in the Spring application context (the default), or obtain EntityManagerFactory
79  * references from JNDI ("persistence unit references"). In the bean case,
80  * the persistence unit name will be matched against the actual deployed unit,
81  * with the bean name used as fallback unit name if no deployed name found.
82  * Typically, Spring's {@link org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean}
83  * will be used for setting up such EntityManagerFactory beans. The post-processor
84  * definition will then look as simple as this:
85  *
86  * <pre class="code">
87  * &lt;bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/&gt;</pre>
88  *
89  * In the JNDI case, specify the corresponding JNDI names in this post-processor's
90  * {@link #setPersistenceUnits "persistenceUnits" map}, typically with matching
91  * <code>persistence-unit-ref</code> entries in the Java EE deployment descriptor.
92  * By default, those names are considered as resource references (according to the
93  * Java EE resource-ref convention), located underneath the "java:comp/env/" namespace.
94  * For example:
95  *
96  * <pre class="code">
97  * &lt;bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"&gt;
98  * &lt;property name="persistenceUnits"&gt;
99  * &lt;map/gt;
100  * &lt;entry key="unit1" value="persistence/unit1"/&gt;
101  * &lt;entry key="unit2" value="persistence/unit2"/&gt;
102  * &lt;/map/gt;
103  * &lt;/property&gt;
104  * &lt;/bean&gt;</pre>
105  *
106  * In this case, the specified persistence units will always be resolved in JNDI
107  * rather than as Spring-defined beans. The entire persistence unit deployment,
108  * including the weaving of persistent classes, is then up to the Java EE server.
109  * Persistence contexts (i.e. EntityManager references) will be built based on
110  * those server-provided EntityManagerFactory references, using Spring's own
111  * transaction synchronization facilities for transactional EntityManager handling
112  * (typically with Spring's <code>@Transactional</code> annotation for demarcation
113  * and {@link org.springframework.transaction.jta.JtaTransactionManager} as backend).
114  *
115  * <p>If you prefer the Java EE server's own EntityManager handling, specify entries
116  * in this post-processor's {@link #setPersistenceContexts "persistenceContexts" map}
117  * (or {@link #setExtendedPersistenceContexts "extendedPersistenceContexts" map},
118  * typically with matching <code>persistence-context-ref</code> entries in the
119  * Java EE deployment descriptor. For example:
120  *
121  * <pre class="code">
122  * &lt;bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"&gt;
123  * &lt;property name="persistenceContexts"&gt;
124  * &lt;map/gt;
125  * &lt;entry key="unit1" value="persistence/context1"/&gt;
126  * &lt;entry key="unit2" value="persistence/context2"/&gt;
127  * &lt;/map/gt;
128  * &lt;/property&gt;
129  * &lt;/bean&gt;</pre>
130  *
131  * If the application only obtains EntityManager references in the first place,
132  * this is all you need to specify. If you need EntityManagerFactory references
133  * as well, specify entries for both "persistenceUnits" and "persistenceContexts",
134  * pointing to matching JNDI locations.
135  *
136  * <p><b>NOTE: In general, do not inject EXTENDED EntityManagers into STATELESS beans,
137  * i.e. do not use <code>@PersistenceContext</code> with type <code>EXTENDED</code> in
138  * Spring beans defined with scope 'singleton' (Spring's default scope).</b>
139  * Extended EntityManagers are <i>not</i> thread-safe, hence they must not be used
140  * in concurrently accessed beans (which Spring-managed singletons usually are).
141  *
142  * @author Rod Johnson
143  * @author Juergen Hoeller
144  * @since 2.0
145  * @see javax.persistence.PersistenceUnit
146  * @see javax.persistence.PersistenceContext
147  */

148 public class PersistenceAnnotationBeanPostProcessor extends JndiLocatorSupport
149         implements InstantiationAwareBeanPostProcessor, BeanFactoryAware {
150
151     protected final Log logger = LogFactory.getLog(getClass());
152
153     private Map JavaDoc<String JavaDoc, String JavaDoc> persistenceUnits;
154
155     private Map JavaDoc<String JavaDoc, String JavaDoc> persistenceContexts;
156
157     private Map JavaDoc<String JavaDoc, String JavaDoc> extendedPersistenceContexts;
158
159     private ListableBeanFactory beanFactory;
160
161     private Map JavaDoc<Class JavaDoc<?>, List JavaDoc<AnnotatedMember>> classMetadata = new HashMap JavaDoc<Class JavaDoc<?>, List JavaDoc<AnnotatedMember>>();
162
163
164     public PersistenceAnnotationBeanPostProcessor() {
165         setResourceRef(true);
166     }
167
168
169     /**
170      * Specify the persistence units for EntityManagerFactory lookups,
171      * as a Map from persistence unit name to persistence unit JNDI name
172      * (which needs to resolve to an EntityManagerFactory instance).
173      * <p>JNDI names specified here should refer to <code>persistence-unit-ref</code>
174      * entries in the Java EE deployment descriptor, matching the target persistence unit.
175      * <p>This is mainly intended for use in a Java EE 5 environment, with all
176      * lookup driven by the standard JPA annotations, and all EntityManagerFactory
177      * references obtained from JNDI. No separate EntityManagerFactory bean
178      * definitions are necessary in such a scenario.
179      * <p>If no corresponding "persistenceContexts"/"extendedPersistenceContexts"
180      * are specified, <code>@PersistenceContext</code> will be resolved to
181      * EntityManagers built on top of the EntityManagerFactory defined here.
182      * Note that those will be Spring-managed EntityManagers, which implement
183      * transaction synchronization based on Spring's facilities.
184      * If you prefer the Java EE 5 server's own EntityManager handling,
185      * specify corresponding "persistenceContexts"/"extendedPersistenceContexts".
186      */

187     public void setPersistenceUnits(Map JavaDoc<String JavaDoc, String JavaDoc> persistenceUnits) {
188         this.persistenceUnits = persistenceUnits;
189     }
190
191     /**
192      * Specify the <i>transactional</i> persistence contexts for EntityManager lookups,
193      * as a Map from persistence unit name to persistence context JNDI name
194      * (which needs to resolve to an EntityManager instance).
195      * <p>JNDI names specified here should refer to <code>persistence-context-ref</code>
196      * entries in the Java EE deployment descriptors, matching the target persistence unit
197      * and being set up with persistence context type <code>Transaction</code>.
198      * <p>This is mainly intended for use in a Java EE 5 environment, with all
199      * lookup driven by the standard JPA annotations, and all EntityManager
200      * references obtained from JNDI. No separate EntityManagerFactory bean
201      * definitions are necessary in such a scenario, and all EntityManager
202      * handling is done by the Java EE 5 server itself.
203      */

204     public void setPersistenceContexts(Map JavaDoc<String JavaDoc, String JavaDoc> persistenceContexts) {
205         this.persistenceContexts = persistenceContexts;
206     }
207
208     /**
209      * Specify the <i>extended</i> persistence contexts for EntityManager lookups,
210      * as a Map from persistence unit name to persistence context JNDI name
211      * (which needs to resolve to an EntityManager instance).
212      * <p>JNDI names specified here should refer to <code>persistence-context-ref</code>
213      * entries in the Java EE deployment descriptors, matching the target persistence unit
214      * and being set up with persistence context type <code>Extended</code>.
215      * <p>This is mainly intended for use in a Java EE 5 environment, with all
216      * lookup driven by the standard JPA annotations, and all EntityManager
217      * references obtained from JNDI. No separate EntityManagerFactory bean
218      * definitions are necessary in such a scenario, and all EntityManager
219      * handling is done by the Java EE 5 server itself.
220      */

221     public void setExtendedPersistenceContexts(Map JavaDoc<String JavaDoc, String JavaDoc> extendedPersistenceContexts) {
222         this.extendedPersistenceContexts = extendedPersistenceContexts;
223     }
224
225     public void setBeanFactory(BeanFactory beanFactory) {
226         if (beanFactory instanceof ListableBeanFactory) {
227             this.beanFactory = (ListableBeanFactory) beanFactory;
228         }
229     }
230
231
232     public Object JavaDoc postProcessBeforeInstantiation(Class JavaDoc beanClass, String JavaDoc beanName) throws BeansException {
233         return null;
234     }
235
236     public boolean postProcessAfterInstantiation(Object JavaDoc bean, String JavaDoc beanName) throws BeansException {
237         List JavaDoc<AnnotatedMember> metadata = findClassMetadata(bean.getClass());
238         for (AnnotatedMember member : metadata) {
239             member.inject(bean);
240         }
241         return true;
242     }
243
244     public PropertyValues postProcessPropertyValues(
245             PropertyValues pvs, PropertyDescriptor JavaDoc[] pds, Object JavaDoc bean, String JavaDoc beanName) throws BeansException {
246
247         return pvs;
248     }
249
250     public Object JavaDoc postProcessBeforeInitialization(Object JavaDoc bean, String JavaDoc beanName) throws BeansException {
251         return bean;
252     }
253
254     public Object JavaDoc postProcessAfterInitialization(Object JavaDoc bean, String JavaDoc beanName) throws BeansException {
255         return bean;
256     }
257
258
259     private List JavaDoc<AnnotatedMember> findClassMetadata(Class JavaDoc<? extends Object JavaDoc> clazz) {
260         synchronized (this.classMetadata) {
261             List JavaDoc<AnnotatedMember> metadata = this.classMetadata.get(clazz);
262             if (metadata == null) {
263                 final List JavaDoc<AnnotatedMember> newMetadata = new LinkedList JavaDoc<AnnotatedMember>();
264                 ReflectionUtils.doWithFields(clazz, new ReflectionUtils.FieldCallback() {
265                     public void doWith(Field JavaDoc field) {
266                         addIfPresent(newMetadata, field);
267                     }
268                 });
269                 ReflectionUtils.doWithMethods(clazz, new ReflectionUtils.MethodCallback() {
270                     public void doWith(Method JavaDoc method) {
271                         addIfPresent(newMetadata, method);
272                     }
273                 });
274                 metadata = newMetadata;
275                 this.classMetadata.put(clazz, metadata);
276             }
277             return metadata;
278         }
279     }
280
281     private void addIfPresent(List JavaDoc<AnnotatedMember> metadata, AccessibleObject JavaDoc ao) {
282         PersistenceContext pc = ao.getAnnotation(PersistenceContext.class);
283         if (pc != null) {
284             Properties JavaDoc properties = null;
285             PersistenceProperty[] pps = pc.properties();
286             if (!ObjectUtils.isEmpty(pps)) {
287                 properties = new Properties JavaDoc();
288                 for (int i = 0; i < pps.length; i++) {
289                     PersistenceProperty pp = pps[i];
290                     properties.setProperty(pp.name(), pp.value());
291                 }
292             }
293             metadata.add(new AnnotatedMember(ao, pc.unitName(), pc.type(), properties));
294         }
295         else {
296             PersistenceUnit pu = ao.getAnnotation(PersistenceUnit.class);
297             if (pu != null) {
298                 metadata.add(new AnnotatedMember(ao, pu.unitName()));
299             }
300         }
301     }
302
303
304     /**
305      * Return a specified persistence unit for the given unit name,
306      * as defined through the "persistenceUnits" map.
307      * @param unitName the name of the persistence unit
308      * @return the corresponding EntityManagerFactory,
309      * or <code>null</code> if none found
310      * @see #setPersistenceUnits
311      */

312     protected EntityManagerFactory getPersistenceUnit(String JavaDoc unitName) {
313         if (this.persistenceUnits != null) {
314             String JavaDoc jndiName = this.persistenceUnits.get(unitName != null ? unitName : "");
315             if (jndiName == null && !StringUtils.hasLength(unitName) && this.persistenceUnits.size() == 1) {
316                 jndiName = this.persistenceUnits.values().iterator().next();
317             }
318             if (jndiName != null) {
319                 try {
320                     return (EntityManagerFactory) lookup(jndiName, EntityManagerFactory.class);
321                 }
322                 catch (NamingException JavaDoc ex) {
323                     throw new IllegalStateException JavaDoc("Could not obtain EntityManagerFactory [" + jndiName + "] from JNDI", ex);
324                 }
325             }
326         }
327         return null;
328     }
329
330     /**
331      * Return a specified persistence context for the given unit name, as defined
332      * through the "persistenceContexts" (or "extendedPersistenceContexts") map.
333      * @param unitName the name of the persistence unit
334      * @param extended whether to obtain an extended persistence context
335      * @return the corresponding EntityManager, or <code>null</code> if none found
336      * @see #setPersistenceContexts
337      * @see #setExtendedPersistenceContexts
338      */

339     protected EntityManager getPersistenceContext(String JavaDoc unitName, boolean extended) {
340         Map JavaDoc<String JavaDoc, String JavaDoc> contexts = (extended ? this.extendedPersistenceContexts : this.persistenceContexts);
341         if (contexts != null) {
342             String JavaDoc jndiName = contexts.get(unitName != null ? unitName : "");
343             if (jndiName == null && !StringUtils.hasLength(unitName) && contexts.size() == 1) {
344                 jndiName = contexts.values().iterator().next();
345             }
346             if (jndiName != null) {
347                 try {
348                     return (EntityManager) lookup(jndiName, EntityManager.class);
349                 }
350                 catch (NamingException JavaDoc ex) {
351                     throw new IllegalStateException JavaDoc("Could not obtain EntityManager [" + jndiName + "] from JNDI", ex);
352                 }
353             }
354         }
355         return null;
356     }
357
358     /**
359      * Find an EntityManagerFactory with the given name in the current Spring
360      * application context, falling back to a single default EntityManagerFactory
361      * (if any) in case of no unit name specified.
362      * @param unitName the name of the persistence unit (may be <code>null</code> or empty)
363      * @return the EntityManagerFactory
364      * @throws NoSuchBeanDefinitionException if there is no such EntityManagerFactory in the context
365      */

366     protected EntityManagerFactory findEntityManagerFactory(String JavaDoc unitName) throws NoSuchBeanDefinitionException {
367         if (this.beanFactory == null) {
368             throw new IllegalStateException JavaDoc("ListableBeanFactory required for EntityManagerFactory lookup");
369         }
370         if (StringUtils.hasLength(unitName)) {
371             return findNamedEntityManagerFactory(unitName);
372         }
373         else {
374             return findDefaultEntityManagerFactory();
375         }
376     }
377
378     /**
379      * Find an EntityManagerFactory with the given name in the current Spring
380      * application context.
381      * @param unitName the name of the persistence unit (never empty)
382      * @return the EntityManagerFactory
383      * @throws NoSuchBeanDefinitionException if there is no such EntityManagerFactory in the context
384      */

385     protected EntityManagerFactory findNamedEntityManagerFactory(String JavaDoc unitName) throws NoSuchBeanDefinitionException {
386         String JavaDoc[] candidateNames =
387                 BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, EntityManagerFactory.class);
388         for (String JavaDoc candidateName : candidateNames) {
389             EntityManagerFactory emf = (EntityManagerFactory) this.beanFactory.getBean(candidateName);
390             String JavaDoc nameToCompare = candidateName;
391             if (emf instanceof EntityManagerFactoryInfo) {
392                 EntityManagerFactoryInfo emfi = (EntityManagerFactoryInfo) emf;
393                 if (emfi.getPersistenceUnitName() != null) {
394                     nameToCompare = emfi.getPersistenceUnitName();
395                 }
396             }
397             if (unitName.equals(nameToCompare)) {
398                 return emf;
399             }
400         }
401         throw new NoSuchBeanDefinitionException(EntityManagerFactory.class,
402                 "No EntityManagerFactory found for persistence unit name '" + unitName + "'");
403     }
404
405     /**
406      * Find a single default EntityManagerFactory in the Spring application context.
407      * @return the default EntityManagerFactory
408      * @throws NoSuchBeanDefinitionException if there is no single EntityManagerFactory in the context
409      */

410     protected EntityManagerFactory findDefaultEntityManagerFactory() {
411         return (EntityManagerFactory) BeanFactoryUtils.beanOfTypeIncludingAncestors(
412                 this.beanFactory, EntityManagerFactory.class);
413     }
414
415
416     /**
417      * Class representing injection information about an annotated field
418      * or setter method.
419      */

420     private class AnnotatedMember {
421
422         private final AccessibleObject JavaDoc member;
423
424         private final String JavaDoc unitName;
425
426         private final PersistenceContextType type;
427
428         private final Properties JavaDoc properties;
429
430         public AnnotatedMember(AccessibleObject JavaDoc member, String JavaDoc unitName) {
431             this(member, unitName, null, null);
432         }
433
434         public AnnotatedMember(AccessibleObject JavaDoc member, String JavaDoc unitName, PersistenceContextType type, Properties JavaDoc properties) {
435             this.unitName = unitName;
436             this.type = type;
437             this.properties = properties;
438             this.member = member;
439             
440             // Validate member type
441
Class JavaDoc<?> memberType = getMemberType();
442             if (!(EntityManagerFactory.class.isAssignableFrom(memberType) ||
443                     EntityManager.class.isAssignableFrom(memberType))) {
444                 throw new IllegalArgumentException JavaDoc("Cannot inject " + member + ": not a supported JPA type");
445             }
446         }
447
448         public void inject(Object JavaDoc instance) {
449             Object JavaDoc value = resolve();
450             try {
451                 if (!this.member.isAccessible()) {
452                     this.member.setAccessible(true);
453                 }
454                 if (this.member instanceof Field JavaDoc) {
455                     ((Field JavaDoc) this.member).set(instance, value);
456                 }
457                 else if (this.member instanceof Method JavaDoc) {
458                     ((Method JavaDoc) this.member).invoke(instance, value);
459                 }
460                 else {
461                     throw new IllegalArgumentException JavaDoc("Cannot inject unknown AccessibleObject type " + this.member);
462                 }
463             }
464             catch (IllegalAccessException JavaDoc ex) {
465                 throw new IllegalArgumentException JavaDoc("Cannot inject member " + this.member, ex);
466             }
467             catch (InvocationTargetException JavaDoc ex) {
468                 // Method threw an exception
469
throw new IllegalArgumentException JavaDoc("Attempt to inject setter method " + this.member +
470                         " resulted in an exception", ex);
471             }
472         }
473         
474         /**
475          * Return the type of the member, whether it's a field or a method.
476          */

477         public Class JavaDoc<?> getMemberType() {
478             if (this.member instanceof Field JavaDoc) {
479                 return ((Field JavaDoc) member).getType();
480             }
481             else if (this.member instanceof Method JavaDoc) {
482                 Method JavaDoc setter = (Method JavaDoc) this.member;
483                 if (setter.getParameterTypes().length != 1) {
484                     throw new IllegalArgumentException JavaDoc(
485                             "Supposed setter [" + this.member + "] must have 1 argument, not " +
486                             setter.getParameterTypes().length);
487                 }
488                 return setter.getParameterTypes()[0];
489             }
490             else {
491                 throw new IllegalArgumentException JavaDoc(
492                         "Unknown AccessibleObject type [" + this.member.getClass() +
493                         "]; can only inject setter methods and fields");
494             }
495         }
496
497         /**
498          * Resolve the object against the application context.
499          */

500         private Object JavaDoc resolve() {
501             // Resolves to EntityManagerFactory or EntityManager.
502
if (EntityManagerFactory.class.isAssignableFrom(getMemberType())) {
503                 EntityManagerFactory emf = resolveEntityManagerFactory();
504                 if (!getMemberType().isInstance(emf)) {
505                     throw new IllegalArgumentException JavaDoc("Cannot inject [" + this.member +
506                             "] with EntityManagerFactory [" + emf + "]: type mismatch");
507                 }
508                 return emf;
509             }
510             else {
511                 // OK, so we need an EntityManager...
512
EntityManager em = (this.type == PersistenceContextType.EXTENDED ?
513                         resolveExtendedEntityManager() : resolveEntityManager());
514                 if (!getMemberType().isInstance(em)) {
515                     throw new IllegalArgumentException JavaDoc("Cannot inject [" + this.member +
516                             "] with EntityManager [" + em + "]: type mismatch");
517                 }
518                 return em;
519             }
520         }
521
522         private EntityManagerFactory resolveEntityManagerFactory() {
523             // Obtain EntityManagerFactory from JNDI?
524
EntityManagerFactory emf = getPersistenceUnit(this.unitName);
525             if (emf == null) {
526                 // Need to search for EntityManagerFactory beans.
527
emf = findEntityManagerFactory(this.unitName);
528             }
529             return emf;
530         }
531
532         private EntityManager resolveEntityManager() {
533             // Obtain EntityManager reference from JNDI?
534
EntityManager em = getPersistenceContext(this.unitName, false);
535             if (em == null) {
536                 // No pre-built EntityManager found -> build one based on factory.
537
// Obtain EntityManagerFactory from JNDI?
538
EntityManagerFactory emf = getPersistenceUnit(this.unitName);
539                 if (emf == null) {
540                     // Need to search for EntityManagerFactory beans.
541
emf = findEntityManagerFactory(this.unitName);
542                 }
543                 // Inject a shared transactional EntityManager proxy.
544
if (emf instanceof EntityManagerFactoryInfo &&
545                         !EntityManager.class.equals(((EntityManagerFactoryInfo) emf).getEntityManagerInterface())) {
546                     // Create EntityManager based on the info's vendor-specific type
547
// (which might be more specific than the field's type).
548
em = SharedEntityManagerCreator.createSharedEntityManager(emf, this.properties);
549                 }
550                 else {
551                     // Create EntityManager based on the field's type.
552
em = SharedEntityManagerCreator.createSharedEntityManager(emf, this.properties, getMemberType());
553                 }
554             }
555             return em;
556         }
557
558         private EntityManager resolveExtendedEntityManager() {
559             // Obtain EntityManager reference from JNDI?
560
EntityManager em = getPersistenceContext(this.unitName, true);
561             if (em == null) {
562                 // No pre-built EntityManager found -> build one based on factory.
563
// Obtain EntityManagerFactory from JNDI?
564
EntityManagerFactory emf = getPersistenceUnit(this.unitName);
565                 if (emf == null) {
566                     // Need to search for EntityManagerFactory beans.
567
emf = findEntityManagerFactory(this.unitName);
568                 }
569                 // Inject a container-managed extended EntityManager.
570
em = ExtendedEntityManagerCreator.createContainerManagedEntityManager(emf, this.properties);
571             }
572             return em;
573         }
574     }
575
576 }
577
Popular Tags