View Javadoc
1   package org.myorg.jpatickets.ejb;
2   
3   import java.io.StringWriter;
4   import java.util.ArrayList;
5   import java.util.HashMap;
6   import java.util.List;
7   import java.util.Map;
8   import java.util.concurrent.TimeUnit;
9   
10  import javax.annotation.PostConstruct;
11  import javax.annotation.Resource;
12  import javax.ejb.AccessTimeout;
13  import javax.ejb.ConcurrencyManagement;
14  import javax.ejb.ConcurrencyManagementType;
15  import javax.ejb.EJBException;
16  import javax.ejb.LockType;
17  import javax.ejb.Singleton;
18  import javax.ejb.Startup;
19  import javax.ejb.TransactionManagement;
20  import javax.ejb.TransactionManagementType;
21  import javax.persistence.EntityManager;
22  import javax.persistence.EntityManagerFactory;
23  import javax.persistence.Persistence;
24  import javax.persistence.PersistenceUnit;
25  import javax.transaction.UserTransaction;
26  
27  import org.slf4j.Logger;
28  import org.slf4j.LoggerFactory;
29  
30  @Singleton
31  @Startup
32  @ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
33  @AccessTimeout(value=1, unit=TimeUnit.SECONDS)
34  @TransactionManagement(TransactionManagementType.BEAN)
35  public class TicketsInitTxEJB {
36      private static final Logger logger = LoggerFactory.getLogger(TicketsInitEJB.class);
37      private static final String PU_NAME = "jpatickets-schemagen-labex";
38      
39      @PersistenceUnit(unitName=PU_NAME)
40      private EntityManagerFactory emf;
41      
42      @Resource
43      private UserTransaction utx;
44      
45      private String dropScript;
46      private String createScript;
47  
48      @PostConstruct
49      public void init() {
50          StringWriter createScriptWriter = new StringWriter();
51          StringWriter dropScriptWriter = new StringWriter();
52          Map<String, Object> props = new HashMap<String, Object>();
53          props.put("javax.persistence.schema-generation.scripts.create-database-schemas", "true");
54          props.put("javax.persistence.schema-generation.scripts.action", "drop-and-create");
55          props.put("hibernate.id.new_generator_mappings", "true"); //tell JSE schemagen to use SEQUENCE for @Id=AUTO
56          props.put("javax.persistence.schema-generation.scripts.create-target", createScriptWriter);
57          props.put("javax.persistence.schema-generation.scripts.drop-target", dropScriptWriter);
58          Persistence.generateSchema(PU_NAME, props);
59          dropScript = dropScriptWriter.toString();
60          createScript = createScriptWriter.toString();
61          logger.debug("createScript={}", createScript);
62          logger.debug("dropScript={}", dropScript);
63      }
64      
65      private List<String> getCommands(String script) {
66          List<String> commands = new ArrayList<String>();
67          for (String line : script.split("\n")) {
68              commands.add(line);
69          }
70          return commands;
71      }
72  
73      @javax.ejb.Lock(LockType.WRITE)
74      public int dropDB() {
75          logger.info("*** dropDB ***");
76          int updates=0;
77          EntityManager em = emf.createEntityManager();
78          try {
79              for (String nativeSQLCommand : getCommands(dropScript)) {
80                  try {
81                      utx.begin();
82                      em.joinTransaction();
83                      updates += em.createNativeQuery(nativeSQLCommand).executeUpdate();
84                      utx.commit();
85                  } catch (Exception ex) {
86                      try { utx.rollback(); } catch (Exception ex2) { throw new EJBException(ex2); }
87                      logger.warn("error executing SQL:" + ex + ", " + nativeSQLCommand);
88                      //keep going
89                  }
90              }
91          } finally {
92              em.close();
93          }
94          return updates;
95      }
96      
97      @javax.ejb.Lock(LockType.WRITE)
98      public int createDB() {
99          logger.info("*** createDB ***");
100         int updates=0;
101         EntityManager em = emf.createEntityManager();
102         try {
103             utx.begin();
104             em.joinTransaction();
105             //all in one transaction
106             for (String nativeSQLCommand : getCommands(createScript)) {
107                 updates += em.createNativeQuery(nativeSQLCommand).executeUpdate();
108             }
109             utx.commit();
110         } catch (Exception ex) {
111             logger.warn("error executing SQL:" + ex);
112             try { utx.rollback(); } catch (Exception ex2) { throw new EJBException(ex2); }
113         } finally {
114             em.close();
115         }
116         return updates;
117     }
118 }