2 Replies Latest reply on Sep 1, 2011 7:45 AM by tcoup

    How do you programmatically create datasources in JBoss5

    tcoup

      Hi,

       

      I have a need to dynamically create datasources (and entitymanagers for that matter) within JBoss5 as my database URL's are unknown until runtime. I've several other people asking after the same thing, but the closest to a real answer i've found is: https://issues.jboss.org/browse/JBJCA-12. Which is quite old and looks pretty crazy.

       

      Is there a more concise method to do this?

       

      Thanks,


      Tom

        • 1. Re: How do you programmatically create datasources in JBoss5
          xiaofancn

          You can use the factory pattern to build your own EMF. Then injected.

          • 2. Re: How do you programmatically create datasources in JBoss5
            tcoup

            Following 'fans xnet's excellant advise i did create a factory. I even (eventually) worked out what to put in it!

             

            In order to build an EMF you need to do something like:

             

             

            {code}

            public EntityManagerFactory buildEntityManagerFactory(DataSource datasource) {

                    Ejb3Configuration ejbconf = new Ejb3Configuration();

             

                    ejbconf.setDataSource(datasource);

                    ejbconf.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");

                    ejbconf.setProperty("hibernate.show_sql", "false");

             

                    //Make transactionally aware

                    ejbconf.setProperty("hibernate.transaction.manager_lookup_class", "org.hibernate.transaction.JBossTransactionManagerLookup");

                    ejbconf.setProperty("jta.UserTransaction", "java:comp/UserTransaction");

                    ejbconf.setProperty("hibernate.current_session_context_class", "jta");

                    ejbconf.setProperty(HibernatePersistence.TRANSACTION_TYPE, PersistenceUnitTransactionType.JTA.name());

             

                    //Add caching

                    ejbconf.setProperty("hibernate.cache.provider_class", "HibernateEhCacheProviderClass");

                    ejbconf.setProperty("hibernate.cache.use_second_level_cache", "true");

                    ejbconf.setProperty("net.sf.ehcache.configurationResourceName", "META-INF/ehcache.xml");

             

                    //Add you entity beans here

                    ejbconf.addAnnotatedClass(SomeEntityBean.class);

             

                    return  ejbconf.buildEntityManagerFactory();

            }

            {code}

             

            Knocking up a datasource with DBCP looks like:

             

            {code}

            public DataSource buildDatasource(String connectionUrl) {

                    // Create base connection factory that produces raw db connections.

                    ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(connectionUrl, libraryUser,

                            libraryPassword);

             

                    // Object pool for pooling raw connections

                    GenericObjectPool connPool = new GenericObjectPool();

                    connPool.setMaxActive(maxShardConns);

                    connPool.setMinIdle(minShardConns);

                    connPool.setMaxIdle(maxIdleConns);

                    connPool.setMinEvictableIdleTimeMillis(shardConnTimeOutMins * 60 * 1000);

                    connPool.setTestOnBorrow(true);

             

                    connPool = new InstrumentedObjectPool(extractServerName(connectionUrl), connPool);

             

                    String connectionValidationSql = "SELECT 1;";

                    KeyedObjectPoolFactory preparedStatementPool = null;

                    Boolean defaultConnectionsToReadOnly = false;

                    Boolean defaultConnectionsToAutoCommit = false;

             

                    TransactionManager transactionManager;

                    try {

                        transactionManager = (TransactionManager) InitialContext.doLookup("java:/TransactionManager");

                    } catch (NamingException e) {

                        throw new RuntimeException("Unable to lookup transaction manager", e);

                    }

             

                    LocalXAConnectionFactory transactionFactory = new LocalXAConnectionFactory(transactionManager,

                            connectionFactory);

             

                    // Create factory to manage the connectionPool

                    PoolableManagedConnectionFactory poolableConnectionFactory = new PoolableManagedConnectionFactory(

                            transactionFactory, connPool, preparedStatementPool, connectionValidationSql,

                            defaultConnectionsToReadOnly, defaultConnectionsToAutoCommit);

             

                    ManagedDataSource dataSource = new ManagedDataSource(connPool, transactionFactory.getTransactionRegistry());

             

                    return dataSource;

            }

            {code}

             

            Using these in combination will give you a transactionally aware EMF with connection pooling.