Source Code Cross Referenced for JtaEntityManagerRegistry.java in  » J2EE » openejb3 » org » apache » openejb » persistence » 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 » openejb3 » org.apache.openejb.persistence 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /**
002:         *
003:         * Licensed to the Apache Software Foundation (ASF) under one or more
004:         * contributor license agreements.  See the NOTICE file distributed with
005:         * this work for additional information regarding copyright ownership.
006:         * The ASF licenses this file to You under the Apache License, Version 2.0
007:         * (the "License"); you may not use this file except in compliance with
008:         * the License.  You may obtain a copy of the License at
009:         *
010:         *     http://www.apache.org/licenses/LICENSE-2.0
011:         *
012:         *  Unless required by applicable law or agreed to in writing, software
013:         *  distributed under the License is distributed on an "AS IS" BASIS,
014:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015:         *  See the License for the specific language governing permissions and
016:         *  limitations under the License.
017:         */package org.apache.openejb.persistence;
018:
019:        import java.util.Map;
020:        import java.util.HashMap;
021:        import javax.persistence.EntityManager;
022:        import javax.persistence.EntityManagerFactory;
023:        import javax.persistence.TransactionRequiredException;
024:        import javax.transaction.Status;
025:        import javax.transaction.Synchronization;
026:        import javax.transaction.TransactionSynchronizationRegistry;
027:
028:        /**
029:         * The JtaEntityManagerRegistry tracks JTA entity managers for transation and extended scoped
030:         * entity managers.  A signle instance of this object should be created and shared by all
031:         * JtaEntityManagers in the server instance.  Failure to do this will result in multiple entity
032:         * managers being created for a single persistence until, and that will result in cache
033:         * incoherence.
034:         */
035:        public class JtaEntityManagerRegistry {
036:            /**
037:             * Registry of transaction associated entity managers.
038:             */
039:            private final TransactionSynchronizationRegistry transactionRegistry;
040:
041:            /**
042:             * Registry of entended context entity managers.
043:             */
044:            private final ThreadLocal<ExtendedRegistry> extendedRegistry = new ThreadLocal<ExtendedRegistry>() {
045:                protected ExtendedRegistry initialValue() {
046:                    return new ExtendedRegistry();
047:                }
048:            };
049:
050:            /**
051:             * Creates a JtaEntityManagerRegistry using the specified transactionSynchronizationRegistry for the registry
052:             * if transaction associated entity managers.
053:             */
054:            public JtaEntityManagerRegistry(
055:                    TransactionSynchronizationRegistry transactionSynchronizationRegistry) {
056:                this .transactionRegistry = transactionSynchronizationRegistry;
057:            }
058:
059:            /**
060:             * Gets an entity manager instance from the transaction registry, extended regitry or for a transaction scoped
061:             * entity manager, creates a new one when an exisitng instance is not found.
062:             * </p>
063:             * It is important that a component adds extended scoped entity managers to this registry when the component is
064:             * entered and removes them when exited.  If this registration is not preformed, an IllegalStateException will
065:             * be thrown when entity manger is fetched.
066:             * @param entityManagerFactory the entity manager factory from which an entity manager is required
067:             * @param properties the properties passed to the entity manager factory when an entity manager is created
068:             * @param extended is the entity manager an extended context
069:             * @return the new entity manager
070:             * @throws IllegalStateException if the entity manger is extended and there is not an existing entity manager
071:             * instance already registered
072:             */
073:            public EntityManager getEntityManager(
074:                    EntityManagerFactory entityManagerFactory, Map properties,
075:                    boolean extended) throws IllegalStateException {
076:                if (entityManagerFactory == null)
077:                    throw new NullPointerException(
078:                            "entityManagerFactory is null");
079:                EntityManagerTxKey txKey = new EntityManagerTxKey(
080:                        entityManagerFactory);
081:                boolean transactionActive = isTransactionActive();
082:
083:                // if we have an active transaction, check the tx registry
084:                if (transactionActive) {
085:                    EntityManager entityManager = (EntityManager) transactionRegistry
086:                            .getResource(txKey);
087:                    if (entityManager != null) {
088:                        return entityManager;
089:                    }
090:                }
091:
092:                // if extended context, there must be an entity manager already registered with the tx
093:                if (extended) {
094:                    EntityManager entityManager = getInheritedEntityManager(entityManagerFactory);
095:                    if (entityManager == null) {
096:                        throw new IllegalStateException(
097:                                "InternalError: an entity manager should already be registered for this entended persistence unit");
098:                    }
099:
100:                    // if transaction is active, we need to register the entity manager with the transaction manager
101:                    if (transactionActive) {
102:                        entityManager.joinTransaction();
103:                        transactionRegistry.putResource(txKey, entityManager);
104:                    }
105:
106:                    return entityManager;
107:                } else {
108:                    // create a new entity manager
109:                    EntityManager entityManager;
110:                    if (properties != null) {
111:                        entityManager = entityManagerFactory
112:                                .createEntityManager(properties);
113:                    } else {
114:                        entityManager = entityManagerFactory
115:                                .createEntityManager();
116:                    }
117:
118:                    // if we are in a transaction associate the entity manager with the transaction; otherwise it is
119:                    // expected the caller will close this entity manager after use
120:                    if (transactionActive) {
121:                        transactionRegistry
122:                                .registerInterposedSynchronization(new CloseEntityManager(
123:                                        entityManager));
124:                        transactionRegistry.putResource(txKey, entityManager);
125:                    }
126:                    return entityManager;
127:                }
128:            }
129:
130:            /**
131:             * Adds the entity managers for the specified component to the registry.  This should be called when the component
132:             * is entered.
133:             * @param deploymentId the id of the component
134:             * @param entityManagers the entity managers to register
135:             * @throws EntityManagerAlreadyRegisteredException if an entity manager is already registered with the transaction
136:             * for one of the supplied entity manager factories; for EJBs this should be caught and rethown as an EJBException
137:             */
138:            public void addEntityManagers(String deploymentId,
139:                    Object primaryKey,
140:                    Map<EntityManagerFactory, EntityManager> entityManagers)
141:                    throws EntityManagerAlreadyRegisteredException {
142:                extendedRegistry.get().addEntityManagers(
143:                        new InstanceId(deploymentId, primaryKey),
144:                        entityManagers);
145:            }
146:
147:            /**
148:             * Removed the registered entity managers for the specified component.
149:             * @param deploymentId the id of the component
150:             */
151:            public void removeEntityManagers(String deploymentId,
152:                    Object primaryKey) {
153:                extendedRegistry.get().removeEntityManagers(
154:                        new InstanceId(deploymentId, primaryKey));
155:            }
156:
157:            /**
158:             * Gets an exiting extended entity manager created by a component down the call stack.
159:             * @param entityManagerFactory the entity manager factory from which an entity manager is needed
160:             * @return the existing entity manager or null if one is not found
161:             */
162:            public EntityManager getInheritedEntityManager(
163:                    EntityManagerFactory entityManagerFactory) {
164:                return extendedRegistry.get().getInheritedEntityManager(
165:                        entityManagerFactory);
166:            }
167:
168:            /**
169:             * Notifies the registry that a user transaction has been started or the specified component.  When a transaction
170:             * is started for a component with registered extended entity managers, the entity managers are enrolled in the
171:             * transaction.
172:             * @param deploymentId the id of the component
173:             */
174:            public void transactionStarted(String deploymentId,
175:                    Object primaryKey) {
176:                extendedRegistry.get().transactionStarted(
177:                        new InstanceId(deploymentId, primaryKey));
178:            }
179:
180:            /**
181:             * Is a transaction active?
182:             * @return true if a transaction is active; false otherwise
183:             */
184:            public boolean isTransactionActive() {
185:                int txStatus = transactionRegistry.getTransactionStatus();
186:                boolean transactionActive = txStatus == Status.STATUS_ACTIVE
187:                        || txStatus == Status.STATUS_MARKED_ROLLBACK;
188:                return transactionActive;
189:            }
190:
191:            private class ExtendedRegistry {
192:                private final Map<InstanceId, Map<EntityManagerFactory, EntityManager>> entityManagersByDeploymentId = new HashMap<InstanceId, Map<EntityManagerFactory, EntityManager>>();
193:
194:                private void addEntityManagers(InstanceId instanceId,
195:                        Map<EntityManagerFactory, EntityManager> entityManagers)
196:                        throws EntityManagerAlreadyRegisteredException {
197:                    if (instanceId == null) {
198:                        throw new NullPointerException("instanceId is null");
199:                    }
200:                    if (entityManagers == null) {
201:                        throw new NullPointerException("entityManagers is null");
202:                    }
203:
204:                    if (isTransactionActive()) {
205:                        for (Map.Entry<EntityManagerFactory, EntityManager> entry : entityManagers
206:                                .entrySet()) {
207:                            EntityManagerFactory entityManagerFactory = entry
208:                                    .getKey();
209:                            EntityManager entityManager = entry.getValue();
210:                            EntityManagerTxKey txKey = new EntityManagerTxKey(
211:                                    entityManagerFactory);
212:                            EntityManager oldEntityManager = (EntityManager) transactionRegistry
213:                                    .getResource(txKey);
214:                            if (entityManager == oldEntityManager) {
215:                                break;
216:                            }
217:                            if (oldEntityManager != null) {
218:                                throw new EntityManagerAlreadyRegisteredException(
219:                                        "Another entity manager is already registered for this persistence unit");
220:                            }
221:
222:                            entityManager.joinTransaction();
223:                            transactionRegistry.putResource(txKey,
224:                                    entityManager);
225:                        }
226:                    }
227:                    entityManagersByDeploymentId
228:                            .put(instanceId, entityManagers);
229:                }
230:
231:                private void removeEntityManagers(InstanceId instanceId) {
232:                    if (instanceId == null) {
233:                        throw new NullPointerException("InstanceId is null");
234:                    }
235:
236:                    entityManagersByDeploymentId.remove(instanceId);
237:                }
238:
239:                private EntityManager getInheritedEntityManager(
240:                        EntityManagerFactory entityManagerFactory) {
241:                    if (entityManagerFactory == null) {
242:                        throw new NullPointerException(
243:                                "entityManagerFactory is null");
244:                    }
245:
246:                    for (Map<EntityManagerFactory, EntityManager> entityManagers : entityManagersByDeploymentId
247:                            .values()) {
248:                        EntityManager entityManager = entityManagers
249:                                .get(entityManagerFactory);
250:                        if (entityManager != null) {
251:                            return entityManager;
252:                        }
253:                    }
254:                    return null;
255:                }
256:
257:                private void transactionStarted(InstanceId instanceId) {
258:                    if (instanceId == null) {
259:                        throw new NullPointerException("instanceId is null");
260:                    }
261:                    if (!isTransactionActive()) {
262:                        throw new TransactionRequiredException();
263:                    }
264:
265:                    Map<EntityManagerFactory, EntityManager> entityManagers = entityManagersByDeploymentId
266:                            .get(instanceId);
267:                    if (entityManagers == null) {
268:                        return;
269:                    }
270:
271:                    for (Map.Entry<EntityManagerFactory, EntityManager> entry : entityManagers
272:                            .entrySet()) {
273:                        EntityManagerFactory entityManagerFactory = entry
274:                                .getKey();
275:                        EntityManager entityManager = entry.getValue();
276:                        entityManager.joinTransaction();
277:                        EntityManagerTxKey txKey = new EntityManagerTxKey(
278:                                entityManagerFactory);
279:                        transactionRegistry.putResource(txKey, entityManager);
280:                    }
281:                }
282:            }
283:
284:            private static class InstanceId {
285:                private final String deploymentId;
286:                private final Object primaryKey;
287:
288:                public InstanceId(String deploymentId, Object primaryKey) {
289:                    if (deploymentId == null) {
290:                        throw new NullPointerException("deploymentId is null");
291:                    }
292:                    if (primaryKey == null) {
293:                        throw new NullPointerException("primaryKey is null");
294:                    }
295:                    this .deploymentId = deploymentId;
296:                    this .primaryKey = primaryKey;
297:                }
298:
299:                public boolean equals(Object o) {
300:                    if (this  == o) {
301:                        return true;
302:                    }
303:                    if (o == null || getClass() != o.getClass()) {
304:                        return false;
305:                    }
306:
307:                    final InstanceId that = (InstanceId) o;
308:                    return deploymentId.equals(that.deploymentId)
309:                            && primaryKey.equals(that.primaryKey);
310:
311:                }
312:
313:                public int hashCode() {
314:                    int result;
315:                    result = deploymentId.hashCode();
316:                    result = 29 * result + primaryKey.hashCode();
317:                    return result;
318:                }
319:            }
320:
321:            private static class CloseEntityManager implements  Synchronization {
322:                private final EntityManager entityManager;
323:
324:                public CloseEntityManager(EntityManager entityManager) {
325:                    this .entityManager = entityManager;
326:                }
327:
328:                public void beforeCompletion() {
329:                }
330:
331:                public void afterCompletion(int i) {
332:                    entityManager.close();
333:                }
334:            }
335:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.