Hibernate Sequence Generator Non Primary Key
- Hibernate Sequence Generator For Non Id Column
- Hibernate Sequence Generator Non Primary Key Definition
- Hibernate Generator Non Primary Key
- Hibernate Sequence Generator Non Primary Key For Sale
- Hibernate Id Sequence Generator
- Start Hibernate Sequence
We’ve already discussed a different kind of primary keys, either simple or composite primary keys have assigned an inline values in the executable applications that were made. by looking into @Id, @IdClass or @EmbeddedId examples you could see that. But what if we would have some generator to generate these primary values. This tutorial explains the ID generator concept in details. The Java Persistence API including the EclipseLink distribution provides several types of primary key generation annotations.
Jpa @generatedvalue for non primary key (11) Is it possible to use a DB sequence for some column that is not the identifier/is not part of a composite identifier? I'm using hibernate as jpa provider, and I have a table that has some columns that are generated values (using a sequence. Nov 24, 2017 I’m using hibernate as jpa provider, and I have a table that has some columns that are generated values (using a sequence), although they are not part of the identifier. What I want is to use a sequence to create a new value for an entity, where the column for the sequence is NOT (part of) the primary key.
@GeneratedValue
The @GeneratedValue consider the entry point for primary key generation, it provides the specification of generation strategies for the values of primary keys. The GeneratedValue annotation may be applied to a primary key property of field of an entity or mapped superclass in a conjunction with the Id annotation. The values that can be used with the @GeneratedValue are those values defined inside the enum GenerationType. GenerationType.java/core-keygen-windows-7-key-generator-v1-14.html.
- TABLE: Is a generator type value indicates that the must assign primary keys for the entity using a Database Table to ensure uniqueness.
- SEQUENCE & IDENTITY: Are a generator types that specify the use of a database sequence or identity column respectively.
- AUTO: Is a generator type indicates that the persistence provider should select an appropriate strategy for the particular database.
Anatomy of @GeneratedValue
- Target: Field and Method
- Uses:@GeneratedValue
- Argument:
- strategy(Optional): The primary key generation strategy that the persistence provider must use to generate the annotated entity primary key.
- generator (Optional): The name of the primary generator to use as specified in the SequenceGenerator or TableGenerator.
Let’s see the implementation of different strategies using the same entity. As you’ve noted before in the EclipseLink Tutorial, we’ve created a mapped superclass previously, so this tutorial should clarify all strategies using License class example.
License Entity
The following class shows you the License entity without using the @GeneratedValue.
- The License mapped superclass provide an identity named licenseId.
- The licenseId has no primary key generator
- In case we’ve not used a generator and not provided a primary key value, the JPA will consider the default value for int primitive types (the default value is zero) and the persist will success for the first time. But when it comes into the second persist the JPA will throw an exception indicate that (Duplicate entry ‘0’ for key primary key).
Primary Key Generation Using Sequence Generator
At this example, you would be seeing a database sequence for generating a primary keys.
Anatomy of @SequenceGenerator
The @SequenceGenerator annotation defines a primary key generator that may be referenced by name when a generator element is specified for the GeneratedValue annotation.A sequence generator may be specified on the entity class or on the primary key field or property.
- Target: Type, Method and Field
- Uses:@SequenceGenerator
- Argument:
- name (Required): A unique generator name that can be referenced by one or more classes to be the generator for primary key values.
- sequenceName (Optional): The name of the database sequence object from which to obtain primary key values.
- initialValue (Optional): The value from which the sequence object is to start generating.
- allocationSize (Optional): The amount to increment by when allocating sequence numbers from the sequence.
Database Sequence Creation
This sample of sequence creation should use the Oracle database, cause MySQL support auto increment which is not consider as a sequence. Figure 1.0 and 1.1 shows you the DriverLicense Table and sequence that created on the Oracle database. Note that the DriverLicense Table doesn’t consider any further relations as you’ve seen in the previous examples.
Figure 1.0
Figure 1.1
License Entity Uses a Sequence Generator
The following License entity does use the sequence generator for generating the primary keys for the entities that created from the License (in case the license isn’t mapped superclass) and from any entity belongs to the License inheritance. License.java
Hibernate Sequence Generator For Non Id Column
DriverLicense.java
- The License entity uses the @GeneratedValue for providing a both of generator type and name.
- The generator type is SEQUENCE and the name is LICENSE_SEQ.
- The License entity uses the @SequenceGenerator for providing the name of the sequence that’s would be consumed by the @GeneratedValue, the name of the database sequence and the allocation size.
Required Persistence Configuration
persistence.xml
Required Libraries
As you’ve noted in the persistence.xml above, the database that’s being used for achieving a sequence generator is an Oracle database, so that you’ve had installed a new library in your project classpath that’s JAR is called ojdbc14.jar. for installing a new library you have to follow the below steps:
- Right click on the project that you would be adding the JAR in its classpath.
- Select Java Build Path from the left pane.
- From the Java Build Path Area click on Add External JARs.
- Add the JAR by navigating into its JAR location.
Executable Application for Generating a Primary keys using Sequence Generator
JPAImpl.java
- The DriverLicense entity doesn’t provide a primary key as you’ve noted in the provided examples at the EclipseTutorial.
- The primary keys are generated automatically using a SequenceGenetator that defined in the License mapped superclass.
The Persisted Records Using Sequence Generator
Figure 1.2 shows you the records that persisted into the Oracle database using a sequence generator.
Figure 1.2
Primary Key Generation Using Table Generator
At this example, you would be seeing a database table for generating a primary keys.
Anatomy of @TableGenerator
The @TableGenerator annotation defines a primary key generator that may be referenced by name when a generator element is specified for the @GeneratedValue. A Table generator may be specified on the entity class or on the primary key field or property.
- Target: Type, Method and Field
- Uses:@TableGenerator
- Argument:
- name (Required): A unique generator name that can be referenced by one or more classes to be the generator for id values.
- table (Optional): Name of table that stores the generated for id values.
- catalog (Optional): The catalog of the table.
- schema (Optional): The schema of the table.
- pKColumnName (Optional): Name of the primary key column in the table.
- valueColumnName (Optional): Name of the column that stores the last value generated.
- pKColumnValue (Optional): The primary key value in the generator table that distinguishes this set of generated values from others that may be stored in the table.
- initialValue (Optional): The value used to initialize the column that stores the last value generated.
- allocationSize (Optional): The amount to increment by when allocating id numbers from the generator.
- uniqueConstraints (Optional): Unique constraints that are to be placed on the table.
Database Table Sequence Creation
MySQL database is capable to create table sequence, so at this section of primary key generation we would return back into the previous examples that already made using the MySQL database. Figure 1.0 and 1.1 shows you the Table sequence and DriverLicense Table that created on the MySQL database respectively.
Figure 1.0
Figure 1.1
- The Table sequence that created contains two columns one for sequence name and the other for sequence number.
- Nothing changed on drive licenses table.
License Entity Uses a Table Sequence Generator
The following License entity does use the Table sequence generator for generating the primary keys for the entities that created from the License (in case the license isn’t mapped superclass) and from any entity belongs to the License inheritance. License.java
DriverLicense.java
Required Persistence Configuration
- If you’ve never ever see the previous entities before and you would learn more about it, refer to the EclipseLink Tutorial.
- The DriverLicense is mentioned in the persistence.xml
- The License mapped superclass is mentioned in the persistence.xml
- No need to mention the generator of the primary keys.
Executable Application for Generating a Primary keys using Table Sequence Generator
JPAImpl.java
The Persisted Records Using Table Sequence Generator
Figure 1.2 shows you the records that persisted into the Oracle database using a Table sequence generator.
Figure 1.2
The impact of adding three records of driver license on the Table sequence is shown at the Figure 1.3
Figure 1.3
- If you’ve noted about the SEQ_NUMBER, it’s value is 3 cause this is the last number that has been generated.
IDENTITY & AUTO Generators
The IDENTITY value specify the use of an identify column, so if you’ve noted the License mapped superclass, you should be able see the licenseId as an identified property. The IDENTITY strategy is one of the most simple strategy that could be applied. Let’s look at the License entity if we’ve decided to use the IDENTITY strategy. License.java
- The primary key of the License entity should be annotated using @GeneratedValue, but this time with an IDENTITY as generator.
Also, your database engine should support the AUTO_INCREMENT principle. Figure 1.4 shows you the updated licenseId column.
Figure 1.4
- The licenseId primary key is updated to be Auto Increment.
That’s what you have to do if you’ve selected and Identity as a primary key generator. Now let’s execute the previous executable JPAImpl. The JPAImpl will execute smoothly without change, that’s because the IDENTITY needs no more that an auto incremental primary key column. See Figure 1.5 that shows you an additional records that persisted using IDENTITY.
Figure 1.5
AUTO value indicates that the persistence provider should pick an appropriate strategy for the particular database, in case we’ve used a MySQL and annotate the License entity using Auto, we almost probably getting such that exception.
It’s clear that the JPA select sequence as a primary key strategy for generating a primary keys. In general Auto generation may expect a database resource to exist, or it may attempt to create one. A vendor may provide dcoumention on how to create such resources in the event that it doesn’t support schema generation or cannot create schema resource at runtime.
Summary
This tutorial is intended to explain the different ways of generating a primary keys. We’ve already clarified the using of @GeneratedValue annotation and the different possible values that could occurred within it. The JPA provides a lot of generator that ranging from simple to complex. The most simple generators that could be used are IDENTITY and AUTO, meanwhile the most complex generators that are used a little more work to achieve are SEQUENCE and TABLE SEQUENCE.
Related posts:
Is it possible to use a DB sequence for some column that is not the identifier/is not part of a composite identifier?
I’m using hibernate as jpa provider, and I have a table that has some columns that are generated values (using a sequence), although they are not part of the identifier.
What I want is to use a sequence to create a new value for an entity, where the column for the sequence is NOT (part of) the primary key:
Then when I do this:
the id will be generated, but the mySequenceVal
property will be also generated by my JPA provider.
Just to make things clear: I want Hibernate to generate the value for the mySequencedValue
property. I know Hibernate can handle database-generated values, but I don’t want to use a trigger or any other thing other than Hibernate itself to generate the value for my property. If Hibernate can generate values for primary keys, why can’t it generate for a simple property?
Hibernate Sequence Generator Non Primary Key Definition
Looking for answers to this problem, I stumbled upon this link
https://amazingclever524.weebly.com/blog/download-mac-os-x-apple. It seems that Hibernate/JPA isn’t able to automatically create a value for your non-id-properties. The @GeneratedValue
annotation is only used in conjunction with @Id
to create auto-numbers.
The @GeneratedValue
annotation just tells Hibernate that the database is generating this value itself.
The solution (or work-around) suggested in that forum is to create a separate entity with a generated Id, something like this:
I found that @Column(columnDefinition='serial')
works perfect but only for PostgreSQL. For me this was perfect solution, because second entity is “ugly” option.
Hibernate definitely supports this. From the docs:
“Generated properties are properties which have their values generated by the database. Typically, Hibernate applications needed to refresh objects which contain any properties for which the database was generating values. Marking properties as generated, however, lets the application delegate this responsibility to Hibernate. Essentially, whenever Hibernate issues an SQL INSERT or UPDATE for an entity which has defined generated properties, it immediately issues a select afterwards to retrieve the generated values.”
For properties generated on insert only, your property mapping (.hbm.xml) would look like:
For properties generated on insert and update your property mapping (.hbm.xml) would look like:
Unfortunately, I don’t know JPA, so I don’t know if this feature is exposed via JPA (I suspect possibly not)
Alternatively, you should be able to exclude the property from inserts and updates, and then “manually” call session.refresh( obj ); after you have inserted/updated it to load the generated value from the database.
This is how you would exclude the property from being used in insert and update statements:
Again, I don’t know if JPA exposes these Hibernate features, but Hibernate does support them.
I know this is a very old question, but it’s showed firstly upon the results and jpa has changed a lot since the question.
The right way to do it now is with the @Generated
annotation. You can define the sequence, set the default in the column to that sequence and then map the column as:
Although this is an old thread I want to share my solution and hopefully get some feedback on this. Be warned that I only tested this solution with my local database in some JUnit testcase. So this is not a productive feature so far.
I solved that issue for my by introducing a custom annotation called Sequence with no property. It’s just a marker for fields that should be assigned a value from an incremented sequence.
Using this annotation i marked my entities.
To keep things database independent I introduced an entity called SequenceNumber which holds the sequence current value and the increment size. I chose the className as unique key so each entity class wil get its own sequence.
The last step and the most difficult is a PreInsertListener that handles the sequence number assignment. Note that I used spring as bean container.
As you can see from the above code the listener used one SequenceNumber instance per entity class and reserves a couple of sequence numbers defined by the incrementValue of the SequenceNumber entity. If it runs out of sequence numbers it loads the SequenceNumber entity for the target class and reserves incrementValue values for the next calls. This way I do not need to query the database each time a sequence value is needed.
Note the StatelessSession that is being opened for reserving the next set of sequence numbers. You cannot use the same session the target entity is currently persisted since this would lead to a ConcurrentModificationException in the EntityPersister.
Hope this helps someone.
I run in the same situation like you and I also didn’t find any serious answers if it is basically possible to generate non-id propertys with JPA or not.
My solution is to call the sequence with a native JPA query to set the property by hand before persisiting it.
This is not satisfying but it works as a workaround for the moment.
Mario
I fixed the generation of UUID (or sequences) with Hibernate using @PrePersist
annotation:
Hibernate Generator Non Primary Key
I’ve found this specific note in session 9.1.9 GeneratedValue Annotation from JPA specification:
“[43] Portable applications should not use the GeneratedValue annotation on other persistent fields or properties.”
So, I presume that it is not possible to auto generate value for non primary key values at least using simply JPA.
Hibernate Sequence Generator Non Primary Key For Sale
I’ve been in a situation like you (JPA/Hibernate sequence for non @Id field) and I ended up creating a trigger in my db schema that add a unique sequence number on insert. I just never got it to work with JPA/Hibernate
Hibernate Id Sequence Generator
“I don’t want to use a trigger or any other thing other than Hibernate itself to generate the value for my property”
In that case, how about creating an implementation of UserType which generates the required value, and configuring the metadata to use that UserType for persistence of the mySequenceVal property?
Start Hibernate Sequence
This is not the same as using a sequence. When using a sequence, you are not inserting or updating anything. You are simply retrieving the next sequence value. It looks like hibernate does not support it.
Tags: hibernate, jpa