View Javadoc
1   /*
2    * JBoss, Home of Professional Open Source
3    * Copyright 2014, Red Hat, Inc. and/or its affiliates, and individual
4    * contributors by the @authors tag. See the copyright.txt in the
5    * distribution for a full listing of individual contributors.
6    *
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   * http://www.apache.org/licenses/LICENSE-2.0
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.jboss.as.quickstarts.bmt;
18  
19  import javax.ejb.Stateless;
20  import javax.inject.Inject;
21  import javax.persistence.PersistenceContext;
22  import javax.transaction.Status;
23  import javax.transaction.UserTransaction;
24  import javax.ejb.TransactionManagement;
25  import javax.ejb.TransactionManagementType;
26  import javax.persistence.EntityManager;
27  
28  /**
29   * A session bean for updating a database table within a JTA transaction
30   *
31   * @author Mike Musgrove
32   */
33  
34  /*
35   * Mark the component as managed by the container. In the context of the example this has 3 consequences: - it becomes eligible
36   * for injection into other components (eg the {@linkplain TransactionServlet}): - it becomes eligible for other components to
37   * be injected; - it becomes eligible for Container Managed Transactions (although this example does not use CMT)
38   */
39  @Stateless
40  @TransactionManagement(TransactionManagementType.BEAN)
41  // tell the container not to manage transactions
42  public class ManagedComponent {
43      /**
44       * Ask the container to inject an Entity Manager (EM). As a consequence the EM will be automatically enlisted into any new
45       * transactions started by the managed component.
46       * 
47       */
48      @PersistenceContext
49      private EntityManager entityManager;
50  
51      // Inject a UserTransaction for manual transaction demarcation.
52      @Inject
53      private UserTransaction userTransaction;
54  
55      // Inject a utility class for updating JPA entities
56      @Inject
57      private UnManagedComponent helper;
58  
59      /**
60       * Maintain a simple key value store using JPA. The method uses a Container managed Entity Manager with manual transaction
61       * demarcation.
62       *
63       * @param key the key. If the key does not exist then a new key/value pair is entered into the database. If the key already
64       *        exists then the associated value is updated.
65       * @param value the value
66       *
67       * @return a string representing the keys values pairs if no key is provided, or the key value pair if one is provided, or
68       *         the error if anything went wrong
69       */
70      public String updateKeyValueDatabase(String key, String value) {
71          /*
72           * Since this is a session bean method we are guaranteed to be thread safe so it is OK to use the injected Entity
73           * Manager. Contrast this with UnManagedComponent class where the developer must create an EM for the duration of the
74           * method call
75           */
76          try {
77              userTransaction.begin();
78  
79              /*
80               * Since the bean is managed by the container the Entity Manager (EM) and JTA transaction manager (TM) cooperate so
81               * there is no need to tell the EM about the transaction. Compare this with the UnManagedComponent class where the
82               * developer is managing the EM himself and therefore must explicitly tell the EM to join the transaction
83               */
84              String result = helper.updateKeyValueDatabase(entityManager, key, value);
85  
86              userTransaction.commit();
87  
88              return result;
89          } catch (Exception e) {
90              return e.getMessage();
91          } finally {
92              /*
93               * Clean up
94               */
95              try {
96                  if (userTransaction.getStatus() == Status.STATUS_ACTIVE)
97                      userTransaction.rollback();
98              } catch (Throwable e) {
99                  // ignore
100             }
101         }
102     }
103 }