Skip to main content

Database Connection

Schema and Table Naming

DataElements map to tables in a database. By default, the schema and table naming follows a certain convention. But there are options to customize the names.

The configuration is reflected in {dataElement.name}Data classes, e.g.

@Table(name="User", schema="ACCOUNT")
public class UserData {
// ...
}

No Configuration

This is the default configuration if no customization options are defined. It uses the dataElement's name as the table name, and the dataElement's component name as the schema name.

// no configuration
@Table(name="{dataElement.name}", schema="{component.name.toUpperCase}")

// example
// no configuration
@Table(name="User", schema="ACCOUNT")
note

The target database must support schemas, such as Postgres or HSQLDB.

Different Naming Strategies

Option
db.global.noSchemas ApplicationApplicationInstance

This global option disables schemas for all elements, even if there is component/dataElement schema customization.

Required for databases that do not support schemas, such as MySQL.

note

This may introduce naming conflicts if you have DataElements with the same name. You can prevent this by adding a different Table naming strategy. (see below)

@Table(name="{dataElement.name}")

// example
@Table(name="User")
<options>
<db.global.noSchemas/>
</options>
Option
db.global.schemaName ApplicationApplicationInstance

Similar to db.global.noSchemas, but instead forces all elements to use the specified schema, even if there is component/dataElement schema customization.

// option("db.global.schemaName : {GLOBAL_SCHEMA}")
@Table(name="{dataElement.name}", schema="{GLOBAL_SCHEMA}")

// example
// option("db.global.schemaName : MY_SCHEMA")
@Table(name="User", schema="MY_SCHEMA")
<options>
<db.global.schemaName>MY_SCHEMA</db.global.schemaName>
</options>
Option
db.tableName.format ApplicationApplicationInstance

Sets a naming strategy for Table names. The value can be one of the following formats.

Available db.tableName.format formats:

uppercase

Uses the DataElement name in uppercase format. E.g. CITY.

lowercase

Uses the DataElement name in lowercase format. E.g. city.

lastPackage

Uses the last part of the packageName as prefix.

tableName = dataElement.packageName.lastSegment
+ '_' + dataElement.name
// Example for dataElement("net.democritus.acl.DataAccess")
tableName = "acl_DataAccess"
appl4_comp4_prefix

Creates a prefix from the Application and Component names.

tableName = application.shortName.first(4).toUpperCase()
+ '_' + component.name.first(4).toUpperCase()
+ '_' + dataElement.name
// Example for application("bookingApp"), component("account"), dataElement("DataAccess")
tableName = "BOOK_ACCO_DataAccess"
<options>
<db.tableName.format>uppercase</db.tableName.format>
</options>
<options>
<db.tableName.format>lowercase</db.tableName.format>
</options>
<options>
<db.tableName.format>lastPackage</db.tableName.format>
</options>
<options>
<db.tableName.format>appl4_comp4_prefix</db.tableName.format>
</options>
Option
db.schema.enableEscapeTableName ApplicationApplicationInstance

Escapes the table name of the DataElement, as some names could be seen as reserved keywords by the database engine.

<options>
<db.schema.enableEscapeTableName/>
</options>

Changing Specific Names

note

Schema (but not table) customizations are ignored if a global schema/noSchema option is defined.

Schemas and tableName names can be further customized to fit specific needs.

Option
db.schema DataElementComponent

Sets the schema name for the current element. If defined on a component it will be used on all dataElements which do not specify a schema itself.

<options>
<db.schema>SPACESHIPS</db.schema>
</options>
Option
db.tableName DataElement

Overrides the database table name for this DataElement.

<options>
<db.tableName>SPACESHIP</db.tableName>
</options>
Option
hasDataBaseSchema DeprecatedComponent

Sets the schema name for all DataElements in the component, unless otherwise specified in the DataElement itself.

<options>
<hasDataBaseSchema>SPACE</hasDataBaseSchema>
</options>
Option
hasDataSchemaName DeprecatedDataElement

Overrides the schema name for this DataElement and changes the table name to be unique. If defined, it will also change the table naming to use lastPackage format.

<options>
<hasDataSchemaName>SPACESHIPS</hasDataSchemaName>
</options>
Option
hasDataTableName DeprecatedDataElement

Overrides the database table name for this DataElement.

<options>
<hasDataTableName>SPACESHIP</hasDataTableName>
</options>

Column Names

Option
hasDataFieldName Field

Changes the name of the column in the database for this field.

<options>
<hasDataFieldName>creation_date</hasDataFieldName>
</options>
Option
hasOtmMappedBy Field

Set the inverse field name for an Ln04 field. (Inverse field should be a Ln02 field on the linked element)

<options>
<hasOtmMappedBy/>
</options>
Option
hasMtmMappedBy Field

Set the inverse field name for an Ln06 field. (Inverse field should be a Ln03 field on the linked element)

<options>
<hasMtmMappedBy/>
</options>
Option
hasMtmTable Field

Sets the name for the join table for an Ln03 field.

<options>
<hasMtmTable/>
</options>

Usage In Expanders

Expanders are provided with two options that wrap the logic described above.

  • dataElement.getOption("databaseTableName")
    • table name of the given dataElement
    • always defined and the value is non-empty
  • dataElement.getOption("databaseSchemaName")
    • schema name of the given dataElement, if any
    • not defined (.empty) if schemaName logic resolves to null/empty()none()/""
    • defined (.defined + .value) if resolved schemaName is a non-empty String.

Id generation

There are several strategies to generate identifiers the data of a DataElement in the database. A DataElement maps to a table in a relational database and the primary key of those tables is a number (of type Long) that must be at least unique within that table.

By default the id generation depends on the persistence framework used. The default strategy for many databases using Hibernate is to use a global native sequence hibernate_sequence and for OpenJPA the default is to use separate tables to track the id.

In an ideal scenario, you would define the exact strategy for id generation independent of default of the persistence framework. That will also make it easier to transition to other frameworks if needed.

Option
persistence.identifier ApplicationApplicationInstanceComponentDataElement

Selects a specific identity generation strategy at any level in the application model. The option is cascaded down and can be overridden on lower levels.

  • identityColumn: Forces the use of identity generation using an auto-incremented column. The implementation can differ depending on the database engine, but the behavior should be the same.
  • sequence: Forces the use of native sequence. By default they are stored int he schema fo the component and shared betweeen all DataElements in that component.
  • custom: No strategy is applied, the application is responsible for supplying an id on persisting new entities.
<options>
<persistence.identifier>identityColumn</persistence.identifier>
</options>
<options>
<persistence.identifier>sequence</persistence.identifier>
</options>
<options>
<persistence.identifier>custom</persistence.identifier>
</options>

Auto-generating identity columns

Some databases such as MySQL provide functionality to automatically generate an id for an identity column that is unique to a specific table. Other database engines such as Postgresql also mimic this behavior by coupling a native sequence to an id column.

This strategy can be applied using the persistence.identifier with value identityColumn.

Native sequence

Most SQL database engines support native sequences. These are a separate data structure within the database that can be used to generate sequential numbers efficiently. It is possible to use native sequences to generate identifiers for a table. This strategy can be applied using the persistence.identifier with value sequence.

Option
persistence.sequence.name ApplicationApplicationInstanceComponentDataElement

If present, this option determines the name of the sequence used for the generation of identifiers. The default name is NS_SEQUENCE if this option is not set. The option is cascaded down and can be overridden on lower levels.

<options>
<persistence.sequence.name>MY_FAVORITE_SEQUENCE</persistence.sequence.name>
</options>
Option
persistence.sequence.schema ApplicationApplicationInstanceComponentDataElement

If present, this option determines the name of the schema used for the generation of identifiers. The default schema is the schema of the DataElement (typically that of the Component). The option is cascaded down and can be overridden on lower levels.

<options>
<persistence.sequence.schema>public</persistence.sequence.schema>
</options>

Global Sequence

By default Hibernate uses a global sequence when the database supports native sequences. For OpenJPA we provide an option to do the same.

Option
persistence.useGlobalSequence ApplicationApplicationInstance

Enables the use of a native database sequence to generate IDs in OpenJPA with the name NS_SEQUENCE.

<options>
<persistence.useGlobalSequence/>
</options>
caution

It is discouraged to use a global sequence. In the case of Hibernate, the behavior is simply a default and could change over the course of Hibernate's development.

For OpenJPA with the persistence.useGlobalSequence option (and Hibernate default), there's also the concerns that a global sequence implies that identifiers have to be unique within an entire application. It makes sense when using native sequences, to use these at a component level, so they are only unique within the data of the concerns handled by that component.

JPA Configuration

Entity Names

By default, the JPA Entity names for a DataElement will be {dataElement.packageName}.{dataElement.name}. This can, however, be configured with the option jpa.entity.name.format:

Option
jpa.entity.name.format ApplicationApplicationInstance

Set the naming strategy for entity names in the data layer.

  • java_underscore: packageName with underscores instead of dots
  • element: {component}.{dataElement}
  • underscore: {component}_{dataElement}
<options>
<jpa.entity.name.format>java_underscore</jpa.entity.name.format>
</options>
<options>
<jpa.entity.name.format>element</jpa.entity.name.format>
</options>
<options>
<jpa.entity.name.format>underscore</jpa.entity.name.format>
</options>

DataSources

DataSources are database connections configured in the application server. By default, each Component will link to a DataSource {application}_{component}, e.g. spaceApp_space.

Option
jpa.datasource ApplicationApplicationInstanceComponent

Set the name of the target datasource in the persistence.xml file.

<options>
<jpa.datasource>my_database</jpa.datasource>
</options>
Option
jpa.datasource.nonjta ApplicationApplicationInstanceComponent

Set the name of the target non-jta datasource in the persistence.xml file.

<options>
<jpa.datasource.nonjta>my_database</jpa.datasource.nonjta>
</options>

Automatic schema updating

Persistence frameworks that implement the JPA standard, usually offer some form of automated database migration in case the data classes are modified. Though it is encouraged (especially in a production environment) to not make use of this for NS applications, it is enabled by default for backwards compatibility.

Option
persistence.schemaUpdating ApplicationApplicationInstance

This option can toggle automatic schema updating through a JPA implementation. Currently supported for Hibernate, OpenJPA and EclipseLink.

ValueBehavior
updateAutomatically migrates the schema. (Currently the default behavior if no option is defined.)
validateValidates that the schema matches the data model when the application starts. (Since Expanders 5.15.2)
nonePerform no action.

The configuration of this functionality is applied in the persistence.xml file.

caution

The validate functionality is not supported for EclipseLink.

<options>
<persistence.schemaUpdating>update</persistence.schemaUpdating>
</options>
<options>
<persistence.schemaUpdating>validate</persistence.schemaUpdating>
</options>
<options>
<persistence.schemaUpdating>none</persistence.schemaUpdating>
</options>