Home > Mobile >  JakartaEE JPA container-managed entity manager with in memory db
JakartaEE JPA container-managed entity manager with in memory db

Time:12-14

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?

CodePudding user response:

In JakartaEE, you can use the @DataSourceDefinition annotation to define a data source programmatically. The annotation can be used at the class level to define a data source that can be injected into your application using the @Resource annotation.

Here is an example of how you can use the @DataSourceDefinition annotation to define a data source for an in-memory HSQLDB database:

@DataSourceDefinition(
    name="java:app/datasources/testDS",
    className="org.hsqldb.jdbc.JDBCDataSource",
    url="jdbc:hsqldb:mem:testdb",
    user="sa",
    password=""
)
public class TestDataSource {
    // Your application code here
}

To use this data source in your application, you can inject it using the @Resource annotation like this:

@PersistenceContext(unitName="test")
private EntityManager em;

@Resource(lookup="java:app/datasources/testDS")
private DataSource dataSource;

You can then use the dataSource variable to obtain a JDBC connection, create a jakarta.transaction.UserTransaction instance, and so on.

I hope this helps! Let me know if you have any other questions.

  • Related