Back to Blog

TomEE and JPA DataSources

TomEE and JPA DataSources

Originally published on Medium, June 17, 2019

This short article shows the different places DataSources can be defined for web applications using JEE running in a TomEE server.

The situation

In order that your @PersistenceContext knows against which database it should connect, you have a META-INF/persistence.xml which defines a persistence-unit which defines a jta-data-source:

META-INF/persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
        http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"
 version="2.2">

   <persistence-unit name="PersUnitName" transaction-type="JTA">
      <jta-data-source>jdbc/mydatabase</jta-data-source>
   </persistence-unit>
</persistence>

Finally the database connection must be put into JNDI under jdbc/mydatabase or to be more precise under java:comp/env/openejb/Resource/<CONTEXT>/jdbc/mydatabase.

Where DataSources can be defined

In JEE 6 or later DataSources can be defined in:

  • a <data-source> in $WEBAPP/WEB-INF/web.xml (or application.xml, application-client.xml, ejb-jar.xml)
  • a @DataSourceDefinition in one of your Java classes

Tomcat adds DataSource definitions under some more locations [1]:

  • as a <Resource> inside <GlobalNamingResources> in $TOMCAT/conf/server.xml
  • as a <Resource> inside <Context> in $WEBAPP/META-INF/context.xml
  • as a <Resource> inside <Context> in $TOMCAT/conf/Catalina/localhost/mypath.xml
  • as a <Resource> inside <Context> in $TOMCAT/conf/server.xml

TomEE adds even more DataSource definition locations [2]:

  • as a <Resource> inside $TOMEE/conf/tomee.xml
  • as a <Resource> inside $WEBAPP/WEB-INF/resources.xml
  • as a list of key=value entries in $TOMEE/conf/system.properties
  • as a "-D" command-line option

The bad news

Defining the <Resource> at any location in a <Context> does add a DataSource object into JDNI, but it doesn't work for your application - this bug is filed under https://issues.apache.org/jira/browse/TOMEE-263

I came up with a (maybe too simple) solution.

DataSource definitions in some detail

As we have seen DataSources can be defined in various locations, unfortunately they have different formats.

Under META-INF/context.xml (or any other "context") it looks like:

<?xml version="1.0" encoding="UTF-8"?>
<Context>
  <Resource name="jdbc/mydatabase" auth="Container"
    type="javax.sql.DataSource" username="root" password=""
    driverClassName="com.mysql.cj.jdbc.Driver"
    url="jdbc:mysql://localhost/myschema" />
</Context>

While in WEB-INF/resources.xml:

<?xml version="1.0" encoding="UTF-8"?>
<tomee>

<Resource id="jdbc/mydatabase" type="DataSource">
   JdbcDriver = com.mysql.cj.jdbc.Driver
   JdbcUrl = jdbc:mysql://localhost/myschema
   UserName = root
</Resource>

</tomee>

So long story short, make sure you are using the right format at the right place.

Links