@Override public void beforeInvocation() { // // Prevent the regular JPA Plugin from starting a transaction. // JPA.entityManagerFactory = null; // // If we have no databases defined, and we have a directive to permit this state, allow it. // if (factoryMap.isEmpty() && Play.configuration.getProperty("mjpa.runWithNoDB", "").equals("true")) { log.debug("Empty factory map--using dummy factory"); JPA.entityManagerFactory = getDummyFactory(); return; } log.debug("Extracting DB key from request: " + Request.current()); // // Find the database key, so that we'll have one for the transaction. // String dbKey = keyExtractor.extractKey(Request.current()); log.debug("Found key: " + dbKey); try { if (dbKey != null) { // // Start the transaction // startTx(dbKey, false); } } catch (InvalidDatabaseException e) { throw new NotFound(e.getMessage()); } }
@SuppressWarnings("unchecked") @Override public void onApplicationStart() { // // NOTE: this uses the JPA class to store the request's entityManagerFactory. // The trick is that the MJPAPlugin has higher priority than Play's native JPAPlugin. // if (JPA.entityManagerFactory == null) { List<Class> classes = Play.classloader.getAnnotatedClasses(Entity.class); if (classes.isEmpty() && Play.configuration.getProperty("jpa.entities", "").equals("")) { return; } if (MDB.datasources == null || MDB.datasources.isEmpty()) { if (Play.configuration.getProperty("mjpa.runWithNoDB", "").equals("true")) { // // Create a dummy entity manager factory, so that JPA is prevented from screaming. // JPA.entityManagerFactory = getDummyFactory(); log.info( "No properly configured databases found. JPA will not be initialized until databases are added"); } else { throw new JPAException( "Cannot start a MJPA manager without a properly configured database", new NullPointerException("No datasource configured")); } } else { // // Iterate over the datasources and build a configuration for each. // for (Entry<String, DataSource> entry : MDB.datasources.entrySet()) { ComboPooledDataSource datasource = (ComboPooledDataSource) entry.getValue(); Ejb3Configuration cfg = buildEjbConfiguration(classes, datasource); Logger.trace("Initializing JPA ..."); try { EntityManagerFactory factory = cfg.buildEntityManagerFactory(); JPA.entityManagerFactory = factory; factoryMap.put(entry.getKey(), factory); log.debug("Added datasource: " + datasource.getJdbcUrl()); } catch (PersistenceException e) { throw new JPAException(e.getMessage(), e.getCause() != null ? e.getCause() : e); } } } JPQLDialect.instance = new JPQLDialect(); } // // Set up the key extractor here, by looking for an application class that implements it. // List<Class> extractors = Play.classloader.getAssignableClasses(RequestDBKeyExtractor.class); if (extractors.size() > 1) { throw new JPAException( "Too many DB Key extract classes. " + "The Multiple DB plugin must use a single extractor class to " + "specify its extractor. These classes where found: " + extractors); } else if (!extractors.isEmpty()) { Class clazz = extractors.get(0); try { keyExtractor = (RequestDBKeyExtractor) clazz.newInstance(); } catch (InstantiationException e) { log.error("Unable to instantiate extractor class:", e); } catch (IllegalAccessException e) { log.error("Invalid access to extractor class:", e); } log.debug("Using application DB key extractor class: " + keyExtractor.getClass().getName()); } else { log.debug("Using default DB key extractor class: " + keyExtractor.getClass().getName()); } }