Persistence update 4.3

Steve Jones edited this page Sep 28, 2017 · 2 revisions

Overview

There are two main drivers for the changes in 4.3.

The first is that we are using Hibernate specific approaches to persistence rather than the standard JPA APIs. We mainly use either QBE (query by example) or Hibernates criteria API for persistence, QBE is not part of JPA and JPA also now provides a type-safe criteria API based on a generated meta-model.

The second is that in order to move to more recent versions of Hibernate we must update our integration as the deprecated approach we were using has now been removed.

Hibernate integration

Bootstrap

The existing discovery mechanism for persistence is preserved with PersistenceContexts being used to collect information on entities and their persistence units.

A PersistenceContextConfiguration class is added to encapsulate information related to a persistence unit which includes:

  • The entities
  • Any auxiliary database objects
  • Context specific Hibernate properties

The PersistenceContextConfiguration is now used when registering a persistence context in place of the removed Ejb3Configuration.

JPA expects persistence units to be configured in the classpath via persistence.xml files. To avoid this required we implement the JPA SPI for persistence providers by extending Hibernates HibernatePersistenceProvider. The extended provider overides the default Hibernate behaviour and instead obtains configuration via the new PersistenceContexts#getConfiguration method.

To preserved support for auxiliary database objects we override EucalyptusEntityManagerFactoryBuilderImpl to include this information when constructing the Hibernate Configuration for each persistence unit.

For compatibility with existing schemas we add the property hibernate.discriminator.ignore_explicit_for_joined which enables legacy Hibernate behaviour for omitting discriminator columns.

Upgrade

Database upgrades now configures persistence using the new PersistenceContextConfiguration and also uses new PersistenceContexts functionality to obtain a Hibernate Configuration for use with schema upgrades.

Unit tests

Unit tests that require persistence are updated to use PersistenceContextConfiguration .

Type-safe criteria

Entities API update

The entities API is updated to support type-safe queries, counts, and bulk deletes. The main new items are:

  • EntityRestriction and EntityRestrictionBuilder can be used to replace example entities and for more complex single-entity restrictions
  • EntityCriteriaQuery and EntityCriteriaQueryJoin to select a unique or list of entities
  • EntityCriteriaDelete and EntityCriteriaDeleteJoin for bulk delete of an entity or entities

The EntityRestriction class hierarchy is:

The Entities and Transactions classes are updated to support type-safe queries:

  • Entities#criteriaQuery
  • Entities#count
  • Entities#delete
  • Entities#restriction
  • Transactions#findAll
  • Transactions#each
  • Transactions#one
  • Transactions#filter
  • Transactions#transform
  • Transactions#filteredTransform
  • Transactions#delete
  • Transactions#deleteAll

Entities and Transactions methods that are not type-safe have been deprecated.

Entity type-safe querySingle entity lookup:

UserEntity user = Entities.criteriaQuery( Entities.restriction( UserEntity.class ).equal( UserEntity_.userId, userId ) ).uniqueResult( )

Optional entity lookup:

Optional<UserEntity> userOption = Entities.criteriaQuery( UserEntity.class ).whereEqual( UserEntity_.userId, userId ).uniqueResultOption( )

Simple listing:

List<UserEntity> users = Entities.criteriaQuery( UserEntity.class ).list( );

Listing with restrictions:

Entities.criteriaQuery( 
    Entities.restriction( AccountEntity.class ).like( AccountEntity_.name, accountNameLike ).build( )
).list( )

Listing with simple joins:

List<UserEntity> users = Entities
    .criteriaQuery( UserEntity.class )
    .join( UserEntity_.groups ).whereEqual( GroupEntity_.userGroup, Boolean.TRUE )
    .join( GroupEntity_.account ).whereEqual( AccountEntity_.name, this.delegate.getName( ) )
    .list( );

Listing with disjunct criteria:

final List<CertificateEntity> entities = Entities.criteriaQuery( CertificateEntity.class ).where(
    Entities.restriction( CertificateEntity.class ).any(
        Entities.restriction( CertificateEntity.class ).isTrue( CertificateEntity_.revoked ).build( ),
        Entities.restriction( CertificateEntity.class ).isNull( CertificateEntity_.certificateHashId ).build( )
    )
).list( );

Entity type-safe countCount with join and criteria:

final long roles = Entities.count( RoleEntity.class )
    .join( RoleEntity_.account )
    .whereEqual( AccountEntity_.name, accountName )
    .uniqueResult( );

Entity type-safe bulk deletionEntity deletion with criteria:

Entities.delete(
    Entities.restriction( ReservedNameEntity.class ).before( ReservedNameEntity_.expiry, new Date( ) ).build( )
).delete( )

this example shows a bulk deletion with simple criteria.

Entity deletion with join:

Entities.delete( UserEntity.class )
    .join( UserEntity_.groups ).whereEqual( GroupEntity_.userGroup, Boolean.TRUE )
    .join( GroupEntity_.account ).whereEqual( AccountEntity_.name, accountName )
    .delete( );

this example uses the convenience whereEqual restriction.

Build changes

Classes are now output to the directories:

  • build/classes
  • build/test-classes

previously the main output was directly to the build directory .

We now allow for sources to be generated during the build and placed into build directories:

  • build/src/main/java
  • build/src/test/java

This is used for the JPA meta-model classes.

We also now support local properties files allowing customization for the build:

  • local.properties
  • local.module.properties

The local.properties file is for the main build, the module properties is for module specific settings. For example if you did not want to compile C code locally you could add:

module.skipNativeMake=true

to local.module.properties .

If you were having build issues due the environment when using more recent versions of ANT you could update local.module.properties to include:

groovyc.fork=true
groovyc.includeantruntime=false

The build files were also updated to use properties for various items that can now be overridden locally (e.g. javac.source and javac.target for source/target versions)

IDEA project support

To build an IDEA project with annotation processing enabled, the following gradle project can be used. Gradle is used to build the IDEA project, once built regular IDEA functionality is used for development:

the above files are copied to the clc directory, and you can then use gradle to build a project using:

# gradle idea

the clc.ipr project file is then opened using IDEA.

Further gradle IDEA tasks (docs.gradle.org) can be found in the documentation.

To manually enable annotation processing edit the project settings as follows:

Eclipse project support

Hibernate documentation covers annotation processor configuration (jboss.org).

References


category.confluence category.developer

Clone this wiki locally
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.