/jboss-as-7.1.1.Final/jpa/core/src/main/java/org/jboss/as/jpa/service/PersistenceUnitServiceImpl.java
Java | 173 lines | 102 code | 23 blank | 48 comment | 2 complexity | 2d33004732bcc07c8322c2ea4048f0e8 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0
1/*
2 * JBoss, Home of Professional Open Source.
3 * Copyright 2011, Red Hat, Inc., and individual contributors
4 * as indicated by the @author tags. See the copyright.txt file in the
5 * distribution for a full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */
22
23package org.jboss.as.jpa.service;
24
25import java.util.Map;
26
27import javax.persistence.EntityManagerFactory;
28import javax.persistence.spi.PersistenceProvider;
29import javax.sql.DataSource;
30
31import org.jboss.as.jpa.classloader.TempClassLoaderFactoryImpl;
32import org.jboss.as.jpa.spi.PersistenceProviderAdaptor;
33import org.jboss.as.jpa.spi.PersistenceUnitMetadata;
34import org.jboss.as.jpa.spi.PersistenceUnitService;
35import org.jboss.as.jpa.util.JPAServiceNames;
36import org.jboss.as.naming.WritableServiceBasedNamingStore;
37import org.jboss.msc.inject.Injector;
38import org.jboss.msc.service.Service;
39import org.jboss.msc.service.ServiceName;
40import org.jboss.msc.service.StartContext;
41import org.jboss.msc.service.StartException;
42import org.jboss.msc.service.StopContext;
43import org.jboss.msc.value.InjectedValue;
44
45import static org.jboss.as.jpa.JpaLogger.JPA_LOGGER;
46
47/**
48 * Persistence Unit service that is created for each deployed persistence unit that will be referenced by the
49 * persistence context/unit injector.
50 * <p/>
51 * The persistence unit scoped
52 *
53 * @author Scott Marlow
54 */
55public class PersistenceUnitServiceImpl implements Service<PersistenceUnitServiceImpl>, PersistenceUnitService {
56
57
58 private final InjectedValue<Map> properties = new InjectedValue<Map>();
59
60 private final InjectedValue<DataSource> jtaDataSource = new InjectedValue<DataSource>();
61 private final InjectedValue<DataSource> nonJtaDataSource = new InjectedValue<DataSource>();
62
63 private final PersistenceProviderAdaptor persistenceProviderAdaptor;
64 private final PersistenceProvider persistenceProvider;
65 private final PersistenceUnitMetadata pu;
66 private final ClassLoader classLoader;
67
68 private volatile EntityManagerFactory entityManagerFactory;
69
70 public PersistenceUnitServiceImpl(final ClassLoader classLoader, final PersistenceUnitMetadata pu, final PersistenceProviderAdaptor persistenceProviderAdaptor, final PersistenceProvider persistenceProvider) {
71 this.pu = pu;
72 this.persistenceProviderAdaptor = persistenceProviderAdaptor;
73 this.persistenceProvider = persistenceProvider;
74 this.classLoader = classLoader;
75 }
76
77 @Override
78 public void start(StartContext context) throws StartException {
79 try {
80 JPA_LOGGER.startingService("Persistence Unit", pu.getScopedPersistenceUnitName());
81 pu.setTempClassLoaderFactory(new TempClassLoaderFactoryImpl(classLoader));
82 pu.setJtaDataSource(jtaDataSource.getOptionalValue());
83 pu.setNonJtaDataSource(nonJtaDataSource.getOptionalValue());
84 WritableServiceBasedNamingStore.pushOwner(context.getController().getServiceContainer().subTarget());
85 this.entityManagerFactory = createContainerEntityManagerFactory();
86 } finally {
87 pu.setTempClassLoaderFactory(null); // release the temp classloader factory (only needed when creating the EMF)
88 WritableServiceBasedNamingStore.popOwner();
89 }
90 }
91
92 @Override
93 public void stop(StopContext context) {
94 JPA_LOGGER.stoppingService("Persistence Unit", pu.getScopedPersistenceUnitName());
95 if (entityManagerFactory != null) {
96 WritableServiceBasedNamingStore.pushOwner(context.getController().getServiceContainer().subTarget());
97 try {
98 entityManagerFactory.close();
99 } finally {
100 entityManagerFactory = null;
101 pu.setTempClassLoaderFactory(null);
102 WritableServiceBasedNamingStore.popOwner();
103 }
104 }
105 }
106
107 @Override
108 public PersistenceUnitServiceImpl getValue() throws IllegalStateException, IllegalArgumentException {
109 return this;
110 }
111
112 /**
113 * Get the entity manager factory
114 *
115 * @return the entity manager factory
116 */
117 @Override
118 public EntityManagerFactory getEntityManagerFactory() {
119 return entityManagerFactory;
120 }
121
122 @Override
123 public String getScopedPersistenceUnitName() {
124 return pu.getScopedPersistenceUnitName();
125 }
126
127 public Injector<Map> getPropertiesInjector() {
128 return properties;
129 }
130
131 public Injector<DataSource> getJtaDataSourceInjector() {
132 return jtaDataSource;
133 }
134
135 public Injector<DataSource> getNonJtaDataSourceInjector() {
136 return nonJtaDataSource;
137 }
138
139 /**
140 * Returns the Persistence Unit service name used for creation or lookup.
141 * The service name contains the unique fully scoped persistence unit name
142 *
143 * @param pu persistence unit definition
144 * @return
145 */
146 public static ServiceName getPUServiceName(PersistenceUnitMetadata pu) {
147 return JPAServiceNames.getPUServiceName(pu.getScopedPersistenceUnitName());
148 }
149
150 public static ServiceName getPUServiceName(String scopedPersistenceUnitName) {
151 return JPAServiceNames.getPUServiceName(scopedPersistenceUnitName);
152 }
153
154 /**
155 * Create EE container entity manager factory
156 *
157 * @return EntityManagerFactory
158 */
159 private EntityManagerFactory createContainerEntityManagerFactory() {
160 persistenceProviderAdaptor.beforeCreateContainerEntityManagerFactory(pu);
161 try {
162 return persistenceProvider.createContainerEntityManagerFactory(pu, properties.getValue());
163 } finally {
164 try {
165 persistenceProviderAdaptor.afterCreateContainerEntityManagerFactory(pu);
166 } finally {
167 pu.setAnnotationIndex(null); // close reference to Annotation Index (only needed during call to createContainerEntityManagerFactory)
168 //This is needed if the datasource is restarted
169 //pu.setTempClassLoaderFactory(null); // close reference to temp classloader factory (only needed during call to createEntityManagerFactory)
170 }
171 }
172 }
173}