Thursday, July 4, 2024
HomeJavaSequence naming methods in Hibernate 6

Sequence naming methods in Hibernate 6


Hibernate 6 launched a brand new configuration parameter and an interface to outline the implicit naming technique for database sequences and tables used to generate main key values. Whenever you migrate an current software to Hibernate 6, you shortly acknowledge that change as a result of the default naming technique has modified. Attributable to that, Hibernate may strive utilizing a sequence that doesn’t exist in your database. However that’s not the one scenario by which you have to be accustomed to this new setting. It will also be useful to map a legacy database with unusually named sequences or if it is advisable to comply with some inside naming conventions.

Since Hibernate 6, you need to use the configuration property hibernate.id.db_structure_naming_strategy to outline which naming technique Hibernate shall use when you don’t explicitly outline a sequence title in your mapping.

<persistence>
    <persistence-unit title="my-persistence-unit">
        ...
        <properties>
            <property title="hibernate.id.db_structure_naming_strategy" worth="normal" />
			...
        </properties>
    </persistence-unit>
</persistence>

Naming methods supported by Hibernate 6

Earlier Hibernate variations offered 1 default conduct, and also you needed to specify the sequence title when you needed to make use of a unique one. With Hibernate 6, you’ll be able to select between 4 implicit naming methods for database sequences:

  • normal
    That is the brand new default in Hibernate 6.
    It concatenates the configured sequence suffix, which is _SEQ by default, to the title of the desk that’s mapped by the entity class.
  • legacy
    This naming technique gives you an identical conduct because the Hibernate variations >= 5.3 however <6 utilized by default. 
    The sequence title is dependent upon your entity mapping definition:
    • Hibernate makes use of the generator title when you referenced a generator with out defining a sequence title. This simplifies the mapping when you solely need to outline the sequence title and was an optimization launched in Hibernate 5.3.
    • In case your mapping doesn’t reference a generator, Hibernate makes use of its default sequence title hibernate_sequence.
  • single
    This naming technique gives you an identical conduct as Hibernate utilized in model <5.3 by default.
    It all the time makes use of the Hibernate’s default sequence title hibernate_sequence.
  • the totally certified class title of an ImplicitDatabaseObjectNamingStrategy implementation
    This allows you to present your personal naming technique. I’ll present you ways to try this on the finish of this text.

Let’s take a better take a look at all 4 naming methods.

ID_DB_STRUCTURE_NAMING_STRATEGY= normal

In distinction to earlier Hibernate variations, Hibernate 6 makes use of a separate database sequence for every entity class by default. The title of that sequence consists of the title of the database desk to which the entity class will get mapped and the postfix _SEQ.

Implicit desk mapping

In the event you don’t specify the title of the database desk, Hibernate makes use of its implicit naming technique. The default technique makes use of the straightforward class title of the entity class because the desk title.

@Entity
public class ChessPlayer {

	@Id
    @GeneratedValue(technique = GenerationType.SEQUENCE)
	personal Lengthy id;

    personal String firstName;
    
    personal String lastName;

    personal LocalDate birthDate;

    @Model
    personal int model;
	
	...
}

So, the ChessPlayer entity class will get mapped to the ChessPlayer desk. And when you’re utilizing Hibernate 6’s normal naming technique for database sequences, Hibernate makes use of the sequence ChessPlayer_SEQ to generate main key values.

ChessPlayer participant = new ChessPlayer();
participant.setFirstName("Thorben");
participant.setLastName("Janssen");
em.persist(participant);
16:15:04,917 DEBUG [org.hibernate.SQL] - 
    choose
        nextval('ChessPlayer_SEQ')
16:15:04,947 DEBUG [org.hibernate.SQL] - 
    insert 
    into
        ChessPlayer
        (birthDate, firstName, lastName, model, id) 
    values
        (?, ?, ?, ?, ?)

Customized desk mapping

You may customise the desk mapping by annotating your entity class with a @Desk annotation and setting the title of the database desk.

@Entity
@Desk(title="participant")
public class ChessPlayer {

	@Id
    @GeneratedValue(technique = GenerationType.SEQUENCE)
	personal Lengthy id;

	...
}

Let’s use that mapping with the earlier take a look at case. You may see within the log output that Hibernate now calls the database sequence player_SEQ to generate main key values. It additionally persists the ChessPlayer entity object to the participant desk.

16:17:04,094 DEBUG [org.hibernate.SQL] - 
    choose
        nextval('player_SEQ')
16:17:04,120 DEBUG [org.hibernate.SQL] - 
    insert 
    into
        participant
        (birthDate, firstName, lastName, model, id) 
    values
        (?, ?, ?, ?, ?)

ID_DB_STRUCTURE_NAMING_STRATEGY = legacy

The legacy naming technique will get you an identical technique as Hibernate utilized in variations >=5.3 and <6. You may activate it by setting the property hibernate.id.db_structure_naming_strategy in your persistence.xml configuration to legacy.

<persistence>
    <persistence-unit title="my-persistence-unit">
        ...
        <properties>
            <property title="hibernate.id.db_structure_naming_strategy" worth="legacy" />
			...
        </properties>
    </persistence-unit>
</persistence>

The conduct of this naming technique is dependent upon your entity mappings.

Mappings and not using a generator reference

Hibernate makes use of 1 default sequence for all main key attributes annotated with @GeneratedValue or @GeneratedValue(technique = GenerationType.SEQUENCE). The essential factor about these 2 mappings is that they don’t reference a generator.

@Entity
public class ChessPlayer {

	@Id
    @GeneratedValue(technique = GenerationType.SEQUENCE)
	personal Lengthy id;

    personal String firstName;
    
    personal String lastName;

    personal LocalDate birthDate;

    @Model
    personal int model;
	
	...
}

Whenever you persist this ChessPlayer entity utilizing the legacy naming technique, Hibernate makes use of the database sequence hibernate_sequence to generate main key values.

16:51:10,742 DEBUG [org.hibernate.SQL] - 
    choose
        nextval('hibernate_sequence')
16:51:10,771 DEBUG [org.hibernate.SQL] - 
    insert 
    into
        ChessPlayer
        (birthDate, firstName, lastName, model, id) 
    values
        (?, ?, ?, ?, ?)

Mappings with a generator reference however and not using a sequence title

In case your main key mapping references a generator that doesn’t exist or doesn’t outline a sequenceName, Hibernate makes use of the generator’s title because the sequence title. This Hibernate-specific optimization was launched in model 5.3 to simplify probably the most generally used mapping definition, which solely customizes the title of the database sequence.

@Entity
public class ChessPlayer {

	@Id
    @GeneratedValue(technique = GenerationType.SEQUENCE, generator="player_seq")
	personal Lengthy id;

    personal String firstName;
    
    personal String lastName;

    personal LocalDate birthDate;

    @Model
    personal int model;
	
	...
}

Whenever you persist an object of this entity class, Hibernate makes use of the database sequence player_seq to generate main key values.

16:51:50,304 DEBUG [org.hibernate.SQL] - 
    choose
        nextval('player_seq')
16:51:50,343 DEBUG [org.hibernate.SQL] - 
    insert 
    into
        ChessPlayer
        (birthDate, firstName, lastName, model, id) 
    values
        (?, ?, ?, ?, ?)

ID_DB_STRUCTURE_NAMING_STRATEGY = single

The naming technique single is a less complicated model of the legacy technique and will get you the default naming of Hibernate in variations <5.3. You may activate it by setting the property hibernate.id.db_structure_naming_strategy in your persistence.xml configuration to single.

<persistence>
    <persistence-unit title="my-persistence-unit">
        ...
        <properties>
            <property title="hibernate.id.db_structure_naming_strategy" worth="single" />
			...
        </properties>
    </persistence-unit>
</persistence>

This technique all the time makes use of the database sequence hibernate_sequence when you don’t specify a sequence title in your mapping definition.

@Entity
public class ChessPlayer {

	@Id
    @GeneratedValue(technique = GenerationType.SEQUENCE)
	personal Lengthy id;

    personal String firstName;
    
    personal String lastName;

    personal LocalDate birthDate;

    @Model
    personal int model;
	
	...
}

You may see that in Hibernate’s log output, when you persist an object of this ChessPlayer class utilizing the naming technique single.

16:57:15,706 DEBUG [org.hibernate.SQL] - 
    choose
        nextval('hibernate_sequence')
16:57:15,734 DEBUG [org.hibernate.SQL] - 
    insert 
    into
        ChessPlayer
        (birthDate, firstName, lastName, model, id) 
    values
        (?, ?, ?, ?, ?)

ID_DB_STRUCTURE_NAMING_STRATEGY = customized class

I confirmed you Hibernate’s 3 normal naming methods for database sequences within the earlier sections. You need to use the identical mechanism to supply your personal naming technique. You solely want to supply a customized implementation of the ImplicitDatabaseObjectNamingStrategy interface and configure it in your persistence.xml.

The implementation of the ImplicitDatabaseObjectNamingStrategy interface doesn’t must be complicated. The interface solely defines 2 strategies, which each return a QualifiedName object.

public class MyImplicitDatabaseObjectNamingStrategy implements ImplicitDatabaseObjectNamingStrategy {
	public static last String STRATEGY_NAME = "customized";

    @Override
    public QualifiedName determineSequenceName(Identifier catalogName, Identifier schemaName, Map<?, ?> configValues,
            ServiceRegistry serviceRegistry) {
        last JdbcEnvironment jdbcEnvironment = serviceRegistry.getService(JdbcEnvironment.class);

        String seqName = "seq_".concat(((String) configValues.get("jpa_entity_name")));

        return new QualifiedSequenceName(
                catalogName,
                schemaName,
                jdbcEnvironment.getIdentifierHelper().toIdentifier(seqName));
    }

    @Override
    public QualifiedName determineTableName(Identifier catalogName, Identifier schemaName, Map<?, ?> configValues,
            ServiceRegistry serviceRegistry) {
        last JdbcEnvironment jdbcEnvironment = serviceRegistry.getService(JdbcEnvironment.class);

        return new QualifiedNameParser.NameParts(
                catalogName,
                schemaName,
                jdbcEnvironment.getIdentifierHelper().toIdentifier(DEF_TABLE));
    }

}

The determineSequenceName methodology returns the title of the database sequence Hibernate shall use. The determineTableName methodology returns the title of the database desk that Hibernate shall use to simulate a sequence.

I don’t get into any particulars about implementing the determineTableName methodology on this article. You may customise it in the identical manner because the title decision for database sequences. However the simulation of a sequence causes a number of scalability points, and all fashionable databases help sequences or autoincremented columns. This mechanism is, due to this fact, not virtually related. Please follow the default implementation that returns Hibernate’s default desk title and use a sequence or autoincremented column to generate your main key values.

The implementation of the determineSequenceName strategies relies upon solely in your desk mannequin and software necessities. The Map<?, ?> configValues methodology parameter incorporates a number of mapping details about the entity class and database desk that you need to use to generate your sequence title. On this instance, I carried out a easy naming technique that makes use of seq_ because the prefix for all sequence names and concatenates it with the logical title of my entity class.

The logical title of the entity class is both the straightforward class title of your entity class or the title you outlined in your @Entity annotation.

@Entity(title="Participant")
public class ChessPlayer {

	@Id
    @GeneratedValue(technique = GenerationType.SEQUENCE)
	personal Lengthy id;

    personal String firstName;
    
    personal String lastName;

    personal LocalDate birthDate;

    @Model
    personal int model;
	
	...
}

After implementing the ImplicitDatabaseObjectNamingStrategy interface, it is advisable to reference it in your configuration. You try this by setting the configuration property hibernate.id.db_structure_naming_strategy to your interface implementation’s totally certified class title.

<persistence>
    <persistence-unit title="my-persistence-unit">
        ...
        <properties>
            <property title="hibernate.id.db_structure_naming_strategy" worth="com.thorben.janssen.pattern.mannequin.MyImplicitDatabaseObjectNamingStrategy" />
			...
        </properties>
    </persistence-unit>
</persistence>

Whenever you use the identical take a look at case as within the earlier examples to persist a ChessPlayer entity object, you’ll be able to see that Hibernate now makes use of the database sequence seq_Player to generate main key values.

17:06:51,325 DEBUG [org.hibernate.SQL] - 
    choose
        nextval('seq_Player')
17:06:51,352 DEBUG [org.hibernate.SQL] - 
    insert 
    into
        Participant
        (birthDate, firstName, lastName, model, id) 
    values
        (?, ?, ?, ?, ?)

Fixing migration points in Hibernate 6

Whenever you’re migrating an current software to Hibernate 6, the default naming technique modifications from single, when you’ve been utilizing Hibernate <5.3, or legacy, when you’ve been utilizing Hibernate >=5.3, to normal. And as I described earlier, this modifications the title of the sequence Hibernate makes use of to generate your main key values.

In the event you’re operating into that drawback, you’ll be able to repair it by explicitly defining the sequence title in your mapping, migrating your database schema, or configuring the previous naming technique in your persistence.xml.

<persistence>
    <persistence-unit title="my-persistence-unit">
        ...
        <properties>
            <property title="hibernate.id.db_structure_naming_strategy" worth="single" />
			...
        </properties>
    </persistence-unit>
</persistence>

Conclusion

The ImplicitDatabaseObjectNamingStrategy interface and the configuration property hibernate.id.db_structure_naming_strategy introduce a brand new implicit naming technique in Hibernate 6. It defines how Hibernate determines the title of a database sequence or the database desk used to simulate a sequence when you don’t specify their title in your entity mapping definition.

Most builders might want to use this configuration when migrating their software to Hibernate 6 as a result of Hibernate’s default implicit naming technique has modified. As a substitute of utilizing 1 default sequence for all entity lessons that don’t specify a sequence, Hibernate now generates an entity-specific default title. You may inform Hibernate to make use of the previous naming technique by setting the configuration property hibernate.id.db_structure_naming_strategy to single when you’re migrating from a Hibernate model <5.3, or to legacy when you’re migrating from a Hibernate model >=5.3.

You can even present your personal naming technique for database sequences. To do this, it is advisable to implement the ImplicitDatabaseObjectNamingStrategy interface and supply the fully-qualified class title as the worth of the configuration property hibernate.id.db_structure_naming_strategy.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments