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")
The target database must support schemas, such as Postgres or HSQLDB.
Different Naming Strategies
Application
ApplicationInstance
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.
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>
Application
ApplicationInstance
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>
Application
ApplicationInstance
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>
Changing Specific Names
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.
Column Names
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 tonull/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.
Application
ApplicationInstance
Component
DataElement
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
.
Application
ApplicationInstance
Component
DataElement
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>
Application
ApplicationInstance
Component
DataElement
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.
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
:
Application
ApplicationInstance
Set the naming strategy for entity names in the data layer.
java_underscore
: packageName with underscores instead of dotselement
:{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
.
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.
Application
ApplicationInstance
This option can toggle automatic schema updating through a JPA implementation. Currently supported for Hibernate, OpenJPA and EclipseLink.
Value | Behavior |
---|---|
update | Automatically migrates the schema. (Currently the default behavior if no option is defined.) |
validate | Validates that the schema matches the data model when the application starts. (Since Expanders 5.15.2 ) |
none | Perform no action. |
The configuration of this functionality is applied in the persistence.xml
file.
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>