Search code examples
javajpajakarta-eejtapersistence.xml

JakartaEE JPA container-managed entity manager with in memory db


I am currently exploring JakartaEE and have a very basic application with a few jax-rs endpoints, a service and a "repository". My repository uses the EntityManger to write to the database. Since I am just testing, I wanted to use an in memory database; for this I chose hsqldb.

Right now I create the EntityManger myself via the EntityManagerFactory. Thus, I also have to handle transactions myself.

As a next step, I wanted to use a container-managed EntityManager using the @PersistenceContext annotation, to also be able to use the @Transactional annotation.

My draft persistence.xml for this approach is the following:

    <persistence-unit name="test" transaction-type="JTA">
        <jta-data-source>TODO</jta-data-source>
        <class>demo.Jakarta.user.UserEntity</class>
        <properties>
            <property name="jakarta.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver"/>
            <property name="jakarta.persistence.jdbc.url" value="jdbc:hsqldb:mem:testdb;DB_CLOSE_DELAY=-1"/>
            <property name="jakarta.persistence.jdbc.user" value="sa"/>
            <property name="jakarta.persistence.jdbc.password" value=""/>
            <property name="jakarta.persistence.schema-generation.database.action" value="create"/>
        </properties>
    </persistence-unit>

As you can probably tell by now, I am having trouble with the jta-data-source. I found some older references (glasfish 4.5) where you could create a vendor-specific xml-file to declare the data source.

Is there a programmatic approach to declare this resource and ensure that the JNDI lookup does not fail on startup?


Solution

  • As an alternative to defining datasources directly in your application server, you may use a bean with the annotation jakarta.annotation.sql.DataSourceDefinition, such as:

    import jakarta.annotation.sql.DataSourceDefinition;
    
    @DataSourceDefinition(
        class = "org.hsqldb.jdbcDriver",
        name = "yourdatasourcename",
        url = "jdbc:hsqldb:mem:bookdb;DB_CLOSE_DELAY=1",
        user = "sa",
        password = "sa")
    public class YourDefinitionClass {
    }
    

    Please refer to the javadoc to apprehend all caveats of this strategy. Note, also, that this kind of coding lock of datasource data will make your project less portable.

    Since your persistence unit datasource will be fetched using the <jta-data-source>, you should remove all connection properties of your persistence.xml.