Contents

Overview

Helidon MP comes with deep integration for three specification-defined, broadly persistence-related technologies that can be used together or separately:

Each integration’s setup, configuration, and usage are described below.

Named Data Source Integration

Overview

Helidon MP’s named data source integration allows you to safely inject managed javax.sql.DataSource instances that are annotated with jakarta.inject.Named annotations into your Helidon MP application. java.sql.Connection objects acquired from these data sources will be pooled by your choice of one of two possible connection pool implementations.

The connections managed by the connection pool will be supplied by your relational database vendor’s JDBC driver.

How you set up Helidon MP’s named data source integration differs depending on which of these two connection pools, which JDBC driver, and which relational database product you use.

Representative setups are described below. The list of such setups is not exhaustive.

Project Setup

Setting Up a Connection Pool

Overview

Helidon MP’s named data source integration requires a connection pool implementation.

Helidon MP comes with support for two connection pools:

  1. HikariCP
  2. Oracle Universal Connection Pool

You can choose to use either, but not both.

Details concerning each connection pool’s setup are described below.

Setting Up the HikariCP Connection Pool
Maven Coordinates (HikariCP)

To include the HikariCP connection pool in your Helidon MP application:

  • Ensure your dependencies are managed

  • Ensure the following <dependency> element is present as a child element of your project’s pom.xml file’s <dependencies> element:

    <dependency>
        <groupId>io.helidon.integrations.cdi</groupId>
        <artifactId>helidon-integrations-cdi-datasource-hikaricp</artifactId>
        <scope>runtime</scope> 
    </dependency>
    Copied
    • The scope is runtime, indicating that the HikariCP integration will be available on the runtime classpath.
Setting Up the Oracle Universal Connection Pool
Maven Coordinates (Oracle Universal Connection Pool)

To include the Oracle Universal Connection Pool in your Helidon MP application:

  • Ensure your dependencies are managed

  • Ensure the following <dependency> element is present as a child element of your project’s pom.xml file’s <dependencies> element:

    <dependency>
      <groupId>io.helidon.integrations.cdi</groupId>
      <artifactId>helidon-integrations-cdi-datasource-ucp</artifactId>
      <scope>runtime</scope> 
    </dependency>
    Copied
    • The scope is runtime, indicating that the Oracle Universal Connection Pool integration will be available on the runtime classpath.

Setting Up a Database Driver

Overview

Regardless of which connection pool you use, at the lowest level JDBC database driver classes are responsible for making any connections to a relational database. JDBC database driver classes are database-product-specific.

Once you have decided upon a relational database product to use, and JDBC driver classes to use to connect to it, ensure your dependencies are managed, and then ensure that a runtime-scoped <dependency> element describing your JDBC driver classes is present as a child element of your project’s pom.xml file’s <dependencies> element.

See the JDBC 4.3 Specification for more information about JDBC.

Representative setups are described below. The list of such setups is not exhaustive.

Setting Up H2
Maven Coordinates (H2)

To include the H2 JDBC driver classes in your Helidon MP application so your application can connect to an H2 database (whether in-memory or persistent):

  • Ensure your dependencies are managed

  • Ensure the following <dependency> element is present as a child element of your project’s pom.xml file’s <dependencies> element:

    <dependency>
        <groupId>io.helidon.integrations.db</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope> 
    </dependency>
    Copied
    • The scope is runtime, indicating that the H2 JDBC driver classes will be available on the runtime classpath.
Setting Up the Oracle JDBC Drivers
Maven Coordinates (Oracle JDBC)

To include the Oracle JDBC driver classes in your Helidon MP application so your application can connect to an Oracle database:

  • Ensure your dependencies are managed

  • Read and understand Developer’s Guide For Oracle JDBC 21c on Maven Central

  • For a basic setup, ensure the following <dependency> element is present as a child element of your project’s pom.xml file’s <dependencies> element:

    <dependency>
        <groupId>io.helidon.integrations.db</groupId>
        <artifactId>ojdbc</artifactId>
        <scope>runtime</scope> 
    </dependency>
    Copied
    • The scope is runtime, indicating that the Oracle JDBC driver classes will be available on the runtime classpath.

Configuration

Overview

Each connection pool supported by Helidon’s named data source integration support is, itself, a DataSource that wraps a vendor-supplied DataSource present in the JDBC driver classes you added to your project. You must configure both the pool and the vendor-supplied DataSource.

To configure Helidon MP’s named data source integration:

  1. Decide where each property of the configuration will reside, as permitted by Helidon MP’s MicroProfile Config implementation
  2. Create configuration suitable for the combination of your selected connection pool and your selected vendor-supplied DataSource implementation in those locations

Helidon MP’s named data source integration relies on Helidon MP’s usage of MicroProfile Config, so you have many choices for each configuration property when deciding on your configuration’s location in (1) above.

The configuration property values themselves are necessarily specific to the connection pool you selected, and to the vendor-supplied DataSource responsible for actually connecting to your relational database. In general, at a minimum, in your configuration you typically supply:

  • Information so the connection pool knows which vendor-supplied DataSource implementation to manage

  • A JDBC URL specific to the vendor-supplied DataSource describing where the database is located, so the managed vendor-supplied DataSource knows how to connect to it

  • Information required for the vendor-supplied DataSource to authenticate to the database and otherwise tailor itself to it

Some examples for representative configurations follow. The list of such configurations is not exhaustive.

Configuration Prefixes

All MicroProfile Config-compatible property names for Helidon MP’s named data source integration follow a common pattern:

objecttype.datasourcename.propertyname
  • The name of a given configuration property always begins with the objecttype portion: a fully-qualified Java class name of the object being configured. Configuration for Helidon MP’s named data source integration concerns the behavior of javax.sql.DataSource objects, so Helidon MP’s named data source integration configuration property names begin with javax.sql.DataSource.

    • A period (.) separates the objecttype portion from the rest of the property name.

  • The datasourcename portion, the name of the data source being configured, comes next. It cannot contain a period (.).

    • A period (.) separates the datasourcename portion from the rest of the property name.

  • The propertyname portion, identifying the connection-pool- or vendor-supplied-DataSource-specific configuration property name, comes last. It may contain periods (.).

As an example, configuration to set an imaginary foo.bar property on the test data source’s associated connection pool or vendor-specific DataSource to baz looks like this in Java .properties format:

javax.sql.DataSource.test.foo.bar=baz   
Copied
  • The objecttype portion of the configuration property name is javax.sql.DataSource.
  • The datasourcename portion of the configuration property name is test.
  • The propertyname portion of the configuration property name is foo.bar.

Examples

Here are some examples illustrating general named data source configuration patterns in various common MicroProfile Config-compatible locations.

Example: META-INF/microprofile-config.properties Classpath Resource

Here is an example of some named data source configuration as might be found in a src/main/resources/META-INF/microprofile-config.properties configuration source:

javax.sql.DataSource.yourDataSourceName.somePropertyOfYourConnectionPoolAndDataSource = itsValue
javax.sql.DataSource.yourDataSourceName.someOtherPropertyOfYourConnectionPoolAndDataSource = anotherValue
Copied
Example: System Properties Set on the Command Line

Here is an example of some named data source configuration using system properties on the command line instead:

java \
  -Djavax.sql.DataSource.yourDataSourceName.somePropertyOfYourConnectionPoolAndDataSource=itsValue \
  -Djavax.sql.DataSource.yourDataSourceName.someOtherPropertyOfYourConnectionPoolAndDataSource=anotherValue \
  # ...
Copied
Example: Environment Variables Set on the Command Line

Here is an example of some named data source configuration using environment variables as typed directly into a command line shell, relying on MicroProfile Config’s mapping rules, since many shells will not understand environment variable names with periods (.) in them:

JAVAX_SQL_DATASOURCE_YOURDATASOURCENAME_SOMEPROPERTYOFYOURCONNECTIONPOOLANDDATASOURCE=itsValue \
JAVAX_SQL_DATASOURCE_YOURDATASOURCENAME_SOMEOTHERPROPERTYOFYOURCONNECTIONPOOLANDDATASOURCE=anotherValue \
java # ...
Copied
Example: Environment Variables Set By the env Command

Here is an example of some named data source configuration using environment variables as supplied via the env shell command, thus removing the need for MicroProfile Config’s mapping rules:

env 'javax.sql.DataSource.yourDataSourceName.somePropertyOfYourConnectionPoolAndDataSource=itsValue' \
  'javax.sql.DataSource.yourDataSourceName.someOtherPropertyOfYourConnectionPoolAndDataSource=anotherValue' \
  java # ...
Copied
Example: application.yaml Classpath Resource

Here is an example of some named data source configuration as might be found in a src/main/resources/application.yaml classpath resource:

javax:
  sql:
    DataSource:
      yourDataSourceName:
        somePropertyOfYourConnectionPoolAndDataSource: itsValue
        someOtherPropertyOfYourConnectionPoolAndDataSource: anotherValue
Copied
Example: Configuring the Oracle Universal Connection Pool and Oracle JDBC

This example presumes you have:

This example, in Java properties file format, configures an Oracle Universal Connection Pool-managed data source named main to connect to an Oracle Database on localhost port 1521, using the oracle.jdbc.poolOracleDataSource vendor-supplied DataSource, with a service name of XE, a user of scott, and a password of tiger:

javax.sql.DataSource.main.connectionFactoryClassName = oracle.jdbc.pool.OracleDataSource 
javax.sql.DataSource.main.url = jdbc:oracle:thin://@localhost:1521/XE 
javax.sql.DataSource.main.user = scott
javax.sql.DataSource.main.password = tiger
Copied

In general, the properties that can be set on the Oracle Universal Connection Pool can be inferred from the "setter" methods found in the javadoc for the PoolDataSourceImpl class.

In general, the properties that can be set on the oracle.jdbc.pool.OracleDataSource DataSource implementation can be inferred from the "setter" methods found in its javadoc.

Unlike HikariCP, the Oracle Universal Connection Pool does not distinguish cleanly between configuration properties that affect its behavior and those that affect the behavior of the vendor-supplied DataSource implementation whose connections it pools. For example, in the example above it is not possible to tell that connectionFactoryClassName is a property of the Oracle Universal Connection Pool, and user is a property of the oracle.jdbc.pool.OracleDataSource DataSource implementation. In some cases, the Oracle Universal Connection Pool will set the given property on both the connection pool itself and on the vendor-supplied DataSource it manages.

Example: Configuring the HikariCP Connection Pool and H2

This example presumes you have:

This example, in Java properties file format, configures a HikariCP-managed data source named test to connect to an in-memory H2 database named unit-testing with a user of sa and an empty password:

javax.sql.DataSource.test.dataSourceClassName = org.h2.jdbcx.JdbcDataSource 
javax.sql.DataSource.test.dataSource.url = jdbc:h2:mem:unit-testing;DB_CLOSE_DELAY=-1  
javax.sql.DataSource.test.dataSource.user = sa
javax.sql.DataSource.test.dataSource.password =
Copied

HikariCP’s configuration properties are described on its Github repository. Properties that should be forwarded on to the vendor-supplied DataSource are prefixed with dataSource. as seen in the example above.

In general, the properties that can be set on the org.h2.jdbcx.JdbcDataSource vendor-supplied DataSource can be inferred from the "setter" methods found in its javadoc.

Usage

You use Helidon MP’s named data source integration in the same way, regardless of your choices of vendor-supplied DataSource and connection pool.

To use Helidon MP’s named data source integration in your application, once it has been set up and configured, create an ordinary DataSource-typed injection point in a Java class representing a CDI bean somewhere in your application, annotated with the name of the data source you wish to use.

Here is how to define such a field-backed injection point:

import javax.sql.DataSource;

import jakarta.inject.Inject;
import jakarta.inject.Named;

// ...

@Inject 
@Named("test") 
private DataSource ds; 
Copied

Here is how to define such a constructor parameter injection point:

import javax.sql.DataSource;

import jakarta.inject.Inject;
import jakarta.inject.Named;

// ...

private final DataSource ds; 

@Inject 
public SomeObject(@Named("test") DataSource ds) { 
    this.ds = ds; 
}
Copied

References

Jakarta Transactions (JTA) Integration

Overview

Helidon MP’s Jakarta Transactions integration integrates the Naryana transaction engine, an implementation of the Jakarta Transactions Specification, into Helidon MP. It lets you use @jakarta.transaction.Transactional to declare JTA transactions in your Java code.

Maven Coordinates (JTA)

To include Helidon’s JTA integration in your application:

  • Ensure your dependencies are managed

  • Ensure the following <dependency> elements are present as child elements of your project’s pom.xml file’s <dependencies> element:

    <dependency>
        <groupId>jakarta.transaction</groupId>
        <artifactId>jakarta.transaction-api</artifactId>
        <scope>provided</scope> 
    </dependency>
    <dependency>
        <groupId>io.helidon.integrations.cdi</groupId>
        <artifactId>helidon-integrations-cdi-jta-weld</artifactId>
        <scope>runtime</scope> 
    </dependency>
    Copied

Configuration

Overview

Helidon MP’s Jakarta Transactions integration does not require configuration, but configuration is possible. Because configuration is of the underlying Narayana transaction engine, any restrictions are those of the engine, not of Helidon itself.

Narayana, unlike Helidon MP, does not use MicroProfile Config, so its configuration options are less flexible.

Some common examples of Narayana configuration follow.

Configuring the Object Store Directory

Narayana features an object store directory which it uses to store information about transaction outcomes. To set its location, you may set the ObjectStoreEnvironmentBean.objectStoreDir system property to the full path of a writeable directory:

java -DObjectStoreEnvironmentBean.objectStoreDir=/var/tmp # ...
Copied

See Specifying the object store location for more information.

Configuring the Default Transaction Manager Timeout

To configure Narayana’s default transaction manager timeout, set the com.arjuna.ats.arjuna.coordinator.defaultTimeout system property to an integral value in seconds:

java -Dcom.arjuna.ats.arjuna.coordinator.defaultTimeout=60 # ...
Copied

For more on configuring Narayana, see Setting Properties in the Naryana documentation.

Usage

To use Helidon MP’s Jakarta Transactions integration, annotate a method with the jakarta.transaction.Transactional annotation:

import jakarta.transaction.Transactional;

// ...

@Transactional 
public String getGreeting(Integer id) {
  // Use a JTA-aware facility to do something transactional here. 
}
Copied

References

Jakarta Persistence (JPA)

Overview

Helidon MP’s Jakarta Persistence integration allows you to interact with Jakarta Persistence (JPA) objects as if your code were running in an application server, handling automatic creation and management of objects such as EntityManager and EntityManagerFactory instances.

More pragmatically, it allows you to inject managed EntityManager instances using the @PersistenceContext annotation.

Jakarta Persistence is a Jakarta EE specification that describes, among other things, how it is implemented:

  1. Map Java objects to relational database tables
  2. Manage such persistent Java objects
  3. Interact with Jakarta Transactions
  4. Interact with named data sources

Jakarta Persistence may be used in an entirely application-managed manner, which requires no integration at all. This application-managed mode places the burden of error handling, thread safety, transaction management, and other concerns on the user. This documentation does not cover application-managed mode JPA.

Jakarta Persistence may also (preferably) be used in a fully container-managed manner, which requires that a container, like Helidon MP, handle error management, thread safety and transaction management on behalf of the user. This documentation covers this container-managed mode of JPA exclusively.

Helidon MP’s Jakarta Persistence integration comes with support for two JPA implementations, known as JPA providers:

  1. Hibernate ORM
  2. Eclipselink

In any given project, you use one or the other, but not both.

How you set up Helidon MP’s Jakarta Persistence integration differs depending on which of these JPA providers you choose to use.

Jakarta Persistence requires Jakarta Transactions and makes use of named data sources, so as you set up your project you will need to understand:

Project Setup

Setting Up a JPA Provider

Overview

While the Jakarta Persistence specification standardizes many aspects around programming and usage, it deliberately leaves many required setup and configuration aspects up to the JPA provider. You will need to set up your project differently depending on which JPA provider you choose.

To set up Helidon MP’s Jakarta Persistence integration in your application to work with your chosen JPA provider, you must:

  1. Set up and configure named data sources as appropriate
  2. Set up and configure Helidon MP’s Jakarta Transactions support
  3. Include the proper Jakarta Persistence-related dependencies
  4. Set up your project to generate and compile the static metamodel
  5. Set up your project for static weaving

Details and examples for each supported JPA provider are below.

Maven Coordinates (Common)

To include the Jakarta Persistence APIs that you will need and to include the core of Helidon’s Jakarta Persistence integration:

These <dependency> elements do not set up a JPA provider. See details below for the JPA provider you have chosen to use.

Setting Up Static Metamodel Generation

To generate and compile the Jakarta Persistence static metamodel for your application, regardless of whether you are using Hibernate ORM or Eclipselink, make sure the <plugin> element in the following code snippet is present as a child element of the <pluginManagement><plugins> element sequence as shown below:

<pluginManagement>
    <plugins>

        <!-- ... -->

        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <executions>
                <execution>
                    <id>default-compile</id>
                    <configuration>
                        <annotationProcessorPaths>
                            <annotationProcessorPath>
                                <groupId>org.hibernate.orm</groupId>
                                <artifactId>hibernate-jpamodelgen</artifactId> 
                                <version>6.1.1.Final</version> 
                            </annotationProcessorPath>
                        </annotationProcessorPaths>
                    </configuration>
                </execution>
            </executions>
        </plugin>

        <!-- ... -->

    </plugins>
</pluginManagement>
Copied

For more on the Hibernate ORM hibernate-jpamodelgen annotation processor, see Hibernate Metamodel Generator in Hibernate ORM’s documentation.

Many parts of Hibernate ORM’s documentation of this feature are outdated.

Maven Coordinates (Hibernate ORM)

To include Helidon’s Jakarta Persistence-related integration for Hibernate ORM:

  • Ensure your dependencies are managed

  • Ensure the basics of your JPA project are set up properly

  • Ensure the following <dependency> elements are present as child elements of your project’s pom.xml file’s <dependencies> element:

    <dependency>
        <groupId>io.helidon.integrations.cdi</groupId>
        <artifactId>helidon-integrations-cdi-hibernate</artifactId>
        <scope>runtime</scope> 
    </dependency>
    Copied
    • The scope is runtime, which ensures that Helidon MP’s Hibernate ORM integration is available at runtime.
Setting Up Static Weaving (Hibernate ORM)

Hibernate ORM can alter your classes' bytecode at build time to keep track of changes made to objects participating in Jakarta Persistence workflows.

To set up this required static weaving for Hibernate ORM, ensure that the following <plugin> element is present as a child element of your project’s pom.xml file’s <plugins> element:

<plugin>
    <groupId>org.hibernate.orm.tooling</groupId>
    <artifactId>hibernate-enhance-maven-plugin</artifactId>
    <!--
        Ideally, your plugin versions are managed via a
        <pluginManagement> element, which is why the <version> element
        is commented out below.  If, nevertheless, you opt for the
        explicit version, check
        https://search.maven.org/artifact/org.hibernate.orm/hibernate-enhance-maven-plugin
        for up-to-date versions, and make sure the version is the same
        as that of Hibernate ORM itself.
    -->
    <!-- <version>6.1.1.Final</version> -->
    <executions>
        <execution>
            <id>Statically enhance JPA entities for Hibernate</id>
            <phase>compile</phase>
            <goals>
                <goal>enhance</goal>
            </goals>
            <configuration>
                <failOnError>true</failOnError>
                <enableDirtyTracking>true</enableDirtyTracking>
                <enableLazyInitialization>true</enableLazyInitialization>
            </configuration>
        </execution>
    </executions>
</plugin>
Copied

You must also add a file named src/main/resources/META-INF/hibernate.properties with the following line as its sole contents:

src/main/resources/META-INF/hibernate.properties
hibernate.bytecode.provider=none 
Copied

For more on the hibernate-enhance-maven-plugin in particular, see its documentation.

For more on Hibernate ORM’s bytecode enhancement (weaving) in general, see Bytecode Enhancement in Hibernate ORM’s documentation.

For more on bytecode enhancement properties, see Bytecode Enhancement Properties in Hibernate ORM’s documentation.

To include Helidon’s Jakarta Persistence-related integration for Eclipselink:

  • Ensure your dependencies are managed

  • Ensure the basics of your JPA project are set up properly

  • Ensure the following <dependency> elements are present as child elements of your project’s pom.xml file’s <dependencies> element:

    <dependency>
        <groupId>io.helidon.integrations.cdi</groupId>
        <artifactId>helidon-integrations-cdi-eclipselink</artifactId>
        <scope>runtime</scope> 
    </dependency>
    Copied
    • The scope is runtime, which ensures that Helidon MP’s Eclipselink integration is available at runtime.

Eclipselink can alter your classes' bytecode at build time to keep track of changes made to objects participating in Jakarta Persistence workflows.

To set up this required static weaving for Eclipselink, ensure that the following <plugin> element is present as a child element of your project’s pom.xml file’s <plugins> element:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>3.1.0</version> 
    <executions>
        <execution>
            <id>weave</id>
            <phase>process-classes</phase>
            <goals>
                <goal>java</goal>
            </goals>
            <configuration combine.self="override">
                <classpathScope>compile</classpathScope>
                <mainClass>org.eclipse.persistence.tools.weaving.jpa.StaticWeave</mainClass>
                <arguments>
                    <argument>-loglevel</argument>
                    <argument>INFO</argument>
                    <argument>-persistenceinfo</argument>
                    <argument>${project.build.outputDirectory}</argument>
                    <argument>${project.build.outputDirectory}</argument>
                    <argument>${project.build.outputDirectory}</argument>
                </arguments>
            </configuration>
        </execution>
    </executions>
</plugin>
Copied

For more on the Eclipselink static weaving command-line utility, see Static Weaving in the Eclipselink documentation.

Configuration

To configure Helidon MP’s Jakarta Persistence integration, you author a src/main/resources/META-INF/persistence.xml file. It contains a mix of standardized elements and JPA provider-specific properties.

For details about the structure and syntax of the META-INF/persistence.xml file, see persistence.xml file in the Jakarta Persistence specification.

Fundamentally, a META-INF/persistence.xml file contains a collection of persistence units. A persistence unit represents a collection of entities in a relational database loosely coupled to a named data source that knows how to connect to it.

Your src/main/resources/META-INF/persistence.xml file must begin (and end) with the following XML:

src/main/resources/META-INF/persistence.xml
<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence
                                 https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"
             version="3.0">  

</persistence>
Copied

Persistence Unit

You list your application’s persistence units as <persistence-unit> child elements of the enclosing <persistence> element. Each <persistence-unit> element identifies a named persistence unit that will correspond to an EntityManager in your code, and represents a collection of entities in a relational database.

Example: Persistence Unit Skeleton

Here is a partial example of a persistence unit named prod with a helpful description:

src/main/resources/META-INF/persistence.xml
<!-- ... -->

<persistence-unit name="prod" transaction-type="JTA"> 
    <description>The production database</description>

    

</persistence-unit>

<!-- ... -->
Copied
  • Because Helidon MP’s JPA integration is for container-managed JPA, the transaction-type attribute must in practice always be set to JTA.
  • The order of subsequent child elements is significant and governed by the XML schema.

In most microservices, there will be only one persistence unit.

A <persistence-unit> is represented in Jakarta Persistence as an instance of the PersistenceUnitInfo class.

JTA Data Source

A persistence unit is always associated with exactly one named data source.

Because Helidon MP’s Jakarta Persistence integration provides support for container-managed JPA, and because container-managed JPA requires Jakarta Transactions (JTA), the kind of named data source a persistence unit is associated with is always a JTA data source. The <jta-data-source> element, a child of the <persistence-unit> element, is how you link a persistence unit to a named data source you previously configured.

Example: Persistence Unit with JTA Data Source

Here is a partial example of a persistence unit named prod, with a helpful description, linked with a JTA data source named main:

src/main/resources/META-INF/persistence.xml
<!-- ... --->

<persistence-unit name="prod" transaction-type="JTA">
    <description>The production database</description>
    <jta-data-source>main</jta-data-source>  

</persistence-unit>

<!-- ... -->
Copied
Classes

A persistence unit lists the classes that should be managed and that will take part in Jakarta Persistence workflows. You must list:

  1. Entity classes
  2. Embeddable classes
  3. Mapped superclasses
  4. Converter classes

You use a sequence of <class> elements to do this. Each <class> element contains the fully-qualified class name of one of the types of managed classes listed above.

There are other mechanisms that can be used in a META-INF/persistence.xml file to describe managed classes, but they may or may not be honored by a given JPA provider.

Example: Persistence Unit with Class Elements

Here is a partial example of a persistence unit named prod, with a helpful description, linked with a JTA data source named main, containing two entity classes:

src/main/resources/META-INF/persistence.xml
<!-- ... --->

<persistence-unit name="prod" transaction-type="JTA">
    <description>The production database</description>
    <jta-data-source>main</jta-data-source>
    <class>com.example.ExampleEntity0</class> 
    <class>com.example.ExampleEntity1</class>

    

</persistence-unit>

<!-- ... -->
Copied
  • Each entity class is listed with a separate <class> element, and there is no containing <classes> element or similar.
  • Other persistence unit characteristics go here.
Properties

Persistence units can have simple properties attached to them to further configure the backing JPA provider. You use the <properties> element to specify them.

Helidon MP’s Jakarta Persistence integration is for container-managed JPA, so the vendor-independent properties described in the specification directly concerned with database connectivity information, such as jakarta.persistence.jdbc.url, do not apply and will be ignored if present. See the JTA Data Source section above for how a persistence unit is linked to a named data source.

Example: Persistence Unit with Properties

Here is a partial exmaple of a persistence unit named prod, with a helpful description, linked with a JTA data source named main, containing two entity classes, configuring a Hibernate ORM-specific property:

src/main/resources/META-INF/persistence.xml
<!-- ... --->

<persistence-unit name="prod" transaction-type="JTA">
    <description>The production database</description>
    <jta-data-source>main</jta-data-source> 
    <class>com.example.ExampleEntity0</class>
    <class>com.example.ExampleEntity1</class>
    <properties>
        <property name="hibernate.show_sql" value="true"/> 
        <property name="eclipselink.weaving" value="false"/> 
    </properties>
</persistence-unit>

<!-- ... -->
Copied
  • The name identifies a name present in the datasourcename portion of a named datasource configuration. There is no need for any kind of reserved prefix (like java:comp/env).
  • This is a Hibernate ORM-specific property and will be properly ignored if the JPA provider you have set up is Eclipselink. See Statement logging and statistics in the Hibernate ORM documentation for more details about the hibernate.show_sql property.
  • This is an Eclipselink-specific property (and (a) is required and (b) must be set to false if you are using Eclipselink), and will be properly ignored if the JPA provider you have set up is Hibernate ORM. See weaving in the Eclipselink documentation for more details about the eclipselink.weaving property.

For an exhaustive list of Hibernate ORM-specific properties, see Configurations in the Hibernate ORM documentation.

For an exhaustive list of Eclipselink-specific properties, see Persistence Property Extensions Reference in the Eclipselink documentation.

Usage

To use Helidon MP’s Jakarta Persistence integration, once you have set up and configured your project, you use the Jakarta Persistence APIs in almost the same manner as if your project were deployed to a Jakarta EE server.

Specifically, you:

  1. Annotate your managed classes (entities, mapped superclasses, etc.) appropriately (using @Entity and similar annotations)
  2. Inject EntityManager instances appropriately with the @PersistenceContext annotation
  3. Use an injected EntityManager to work with your managed objects

In addition, you use Helidon MP’s JTA integration to declare transactional boundaries where appropriate.

A full tutorial of Jakarta Persistence is well beyond the scope of this documentation. Consult the specification for details on how to map your entity classes to relational database tables, and how to perform other related tasks.

Examples

References

References