By default, when creating a web app with Spring Roo, your JPA configuration is set up to use a Commons DBCP BasicDataSource. This works great for testing locally on Tomcat, but doesn’t work when deployed to the OpenShift environment, you’ll get errors like this as Hibernate tries to get connections and set up your schema based on your Entity mappings :
2012/03/08 18:17:03,423 ERROR [org.hibernate.tool.hbm2ddl.SchemaExport]
(MSC service thread 1-3) HHH000231: Schema export unsuccessful:
java.lang.UnsupportedOperationException: The application must supply JDBC connections
At the current time there isn’t a great deal of documentation on the Open Shift site that explains how to config your app to use a datasource, but this post on the community forum has some good clues (this one is Flex specific, but it mentions the standalone.xml JBoss config file).
When you add a database cartridge to your app in OpenShift, your JBoss in your environment is also configured with a DataSource using connection properties set up to access your MySQL (or other) db, and it’s ready to go.
To get your Spring Roo app configured to use the datasource requires a bit more effort. There’s various posts online about how to configure JPA2 to use a DataSource provided by a container, but getting all the right parts changed or removed in your existing config is a bit tricky. This post here lists all the steps needed, and most of the text below is taken from this post (thanks to the poster of this entry on the Spring forum as before I got to this stage I had already spent a few hours trying to piece this together) – here we go:
Edit src/main/resources/META-INF/spring/applicationContext.xml:
- remove the BasicDataSource bean (the DataSource is now specified in persistence.xml)
- remove the JpaTransactionManager bean
- add <tx:jta-transaction-manager /> to look up JBoss’ JtaTransactionManager from JNDI instead. The default name of the bean using this tag is ‘transactionManager’
- If you had previously used the <tx:annotation-driven> tag, make sure it’s transaction-manger attribute now uses ‘transactionManager’ (from the previous step):
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
- remove the LocalContainerEntityManagerFactoryBean
- add this bean:
<jee:jndi-lookup id="entityManagerFactory"
jndi-name="your/app/MyEntityManagerFactory"
expected-type="javax.persistence.EntityManagerFactory" />
Your EntityManagerFactory gets exposed by JBoss from the following changes to your persistence.xml files:
Edit src/main/resources/META-INF/persistence.xml:
- change the persistence-unit’s “transaction-type” attribute from RESOURCE_LOCAL to JTA
- add a child element to “persistence-unit” as follows:
<jta-data-source>java:/MyDSName</jta-data-source>
Add the following property to expose your EntityManagerFactory:
<property name="jboss.entity.manager.factory.jndi.name"
value="your/app/MyEntityManagerFactory"/>