Hibernate ORM (JPA)

3. Compatibility matrix

Matrix hibernate

It can be found at the release page, eg:

https://hibernate.org/orm/releases/6.4/


Hibernate | Java    | Jakarta Persistence

[6.2,6.4] | [11,21] | 3.1

 5.6      | [ 8,17] | 3.0



Matrix spring - hibernate

https://github.com/ghusta/matrice-versions-spring-hibernate


4. Sequences

4.1. Hibernate >=6 (<table>_<field>_seq or <table>_seq)

Hibernate >=6 uses, by default, the sequence w/ either name (field based) <table>_<field>_seq or (table based) <table>_seq.

Eg: For an entity w/ a generated primary key "id":

    @Id

    @GeneratedValue(strategy = GenerationType.SEQUENCE)

    private Long id;

This liquibase script creates a sequence for the table 'mytable' and field 'id':

# H2 sequence data type is BIGINT [https://www.h2database.com/html/commands.html#create_sequence]

databaseChangeLog:

  - changeSet:

      id: "002"

      author: thatsme

      failOnError: true

      comment: "Create default sequence for table 'mytable', field 'id'"

      changes:

        - createSequence:

            sequenceName: mytable_id_seq

            incrementBy: 1

            cycle: false

            cacheSize: 1

            minValue: 1

            maxValue: 9223372036854775807

            startValue: 1


4.2. Hibernate <6 (hibernate_sequence)

Hibernate <6 uses, by default, the sequence "hibernate_sequence", which in PostgreSQL is auto-generated as:

CREATE SEQUENCE public.hibernate_sequence

INCREMENT BY 1

NO MINVALUE

MAXVALUE 9223372036854775807

START 1

CACHE 1

CYCLE;


Note: PostgreSQL NO MINVALUE defaults are 1 for ASC, data type min for DESC

This liquibase script creates it (tested fine with PostgreSQL and H2):

# H2 sequence data type is BIGINT [https://www.h2database.com/html/commands.html#create_sequence]

databaseChangeLog:


  - changeSet:

      id: "002"

      author: thatsme

      failOnError: true

      comment: "Create hibernate_sequence"

      changes:

      changes:

        - createSequence:

            sequenceName: hibernate_sequence

            incrementBy: 1

            cycle: true

            cacheSize: 1

            #minValue: (int)-2147483648 (long)-9223372036854775808

            minValue: 1

            #maxValue: (int)2147483647 (long)9223372036854775807

            maxValue: 9223372036854775807

            startValue: 1


6. Soft Delete

6.1. Using Hibernate >= 6.4.0 (soft delete)

Hibernate supports both: entity soft delelete and collection soft delete, see: https://docs.jboss.org/hibernate/orm/6.4/userguide/html_single/Hibernate_User_Guide.html

The @SoftDelete annotation may also be placed at the package level, in which case it applies to all entities and collections defined within the package. 

@Entity

@SoftDeletes(columnName="active", converter=YesNoConverter.class, strategy=ACTIVE)

class Account {

        ...

}


Indicator column

The column where the indicator value is stored is defined using @SoftDelete#columnName attribute.

The default column name depends on the strategy being used:

ACTIVE: The default column name is active.

DELETED: The default column name is deleted.


Indicator conversion

The conversion is defined using a Jakarta Persistence AttributeConverter. The domain-type is always boolean. The relational-type can be any type, as defined by the converter; generally BOOLEAN, BIT, INTEGER or CHAR.

An explicit conversion can be specified using @SoftDelete#converter:

NumericBooleanConverter    Defines conversion using 0 for false and 1 for true

YesNoConverter    Defines conversion using 'N' for false and 'Y' for true

TrueFalseConverter    Defines conversion using 'F' for false and 'T' for true


If an explicit converter is not specified, Hibernate will follow the same resolution steps defined in Boolean to determine the proper database type -

boolean (and bit)  -  the underlying type is boolean / bit and no conversion is applied

numeric - the underlying type is integer and values are converted according to NumericBooleanConverter

character - the underlying type is char and values are converted according to TrueFalseConverter


6.2. Using Hibernate < 6.4.0 (soft delete)

It was possible to hack together support for soft deletes in previous versions using a combination of filters, @Where and custom delete event handling. However, that approach was tedious and did not work in all cases. @SoftDelete should be highly preferred.

See article: https://www.baeldung.com/spring-jpa-soft-delete


8. Second-Level Cache

8.1. Enable Second-Level Cache (Redis)

Not straight forward, we'll see.