Generate ID based on number of rows in table in Spring - java

I am developing a spring 3 MVC application. I am using hibernate as the ORM. While defining the model, i have an ID field. I want to auto generate it in such a way that its value is the current number of rows in the table + 1. How can it be done?

AUTOINCREMENT column or a sequence will do the trick. In Hibernate simply annotate id with #GeneratedValue:
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int id;
Hibernate will automatically set the id to next available value.
See also
Hibernate Auto Increment ID

Related

Can i use UUID as datatype for id field in model/pojo class using hibernate search

I am trying to implement search functionality using hibernate search for my project which is in spring boot .
I used hibernate search annotations like #Indexed, #Field.
When i use datatype of id Field as Long then search is performed and list of results is returned but in my project UUID is used as datatype for id field which is also primary key .in the case of UUID the result is an empty list.
#Id
#GeneratedValue
private UUID id;
How can i perform search operation using UUID as datatype for id field?
Please use the following code
#Id
#Type(type = "uuid-char") // add column type
#GeneratedValue
#Column(name = "id")
You need to add #Type for the ID column if your using uuid as your data type
I hope it helps you
Thanks
Yes, you can use UUID as a document ID, and it should work out of the box.
If you're not getting any result:
Check you're using a recent version of Hibernate Search (5.11+) and Hibernate ORM (5.4+).
Check that you reindexed your data after changing the type of your ID.
When reindexing, check your logs for indexing failures and report them here.
Test with a very simple query, for example qb.all().createQuery(). If you get results with that query, the problem is with your initial query, not with your identifier.
You can apply #sridhar-karuppusamy's suggestion, but that should only be necessary if you want the database type to be VARCHAR instead of VARBINARY. And that is irrelevant to Hibernate Search.

Sequence "HIBERNATE_SEQUENCE" not found for h2 test with GenerationType.AUTO

I am trying to migrate one of our services to Spring Boot 2.0.3.
While most of the tests are fine, one of them fails with error:
Caused by: org.h2.jdbc.JdbcSQLException: Sequence "HIBERNATE_SEQUENCE" not found; SQL statement:
call next value for hibernate_sequence [90036-197]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:357)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.command.Parser.readSequence(Parser.java:5970)
at org.h2.command.Parser.readTerm(Parser.java:3131)
at org.h2.command.Parser.readFactor(Parser.java:2587)
This is really confusing because all teh entities rely on the same generation id mechanism:
#GeneratedValue(strategy = GenerationType.AUTO)
It's a repository test and the repository itself is very straight-forward:
#Repository
public interface OrderDetailsRepository extends JpaRepository<OrderDetails, Long> {
OrderDetails findFirstByOrderIdOrderByIdDesc(String orderId);
}
What can possible go wrong here?
PS: And, yes, there is both orderId and Id field present in the entity.
When you choose #GeneratedValue(strategy = GenerationType.AUTO) Hibernate selects a generation strategy based on the database-specific dialect.
The problem in your case is hibernate can't find the HIBERNATE_SEQUENCE and thus can't create a new object for the sequence. Try adding a sequence like this and it should solve the problem, but could lead to inconsistencies with the data...
CREATE TABLE CUSTOMER(
  id int primary key,
);
CREATE SEQUENCE HIBERNATE_SEQUENCE START WITH 1 INCREMENT BY 1;
I would suggest using the GenerationType.SEQUENCEand try to recreate your id pattern with your custom db sequence. You can read more about the GenerationType's
here
I encountered the same issue when written sample code for spring boot with h2. please find the details below of my findings.
In your entity class sequence is not given and check your table as well i.e. have you given AUTO_INCREMENT for primary key?
Please follow as below.
1. Check your ddl once and set auto_increment for primary key (see below for id)
CREATE TABLE EMPLOYEES (
id INT AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(250),
last_name VARCHAR(250),
email VARCHAR(250) DEFAULT NULL
);
Check your entity class and update primary key as below
public class Employee {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Please make a note that GenerationType is given IDENTITY you can give AUTO as well. Also if you are using h2 in-memory DB and table inserted few records while boot-start (if dml file available in resource) then hibernate insertion may give unique constraint because sequence 1,2,3..(depends on how many records inserted while startup) may have already used and as I said above hibernate will generate the sequence from 1 and will increment by 1 for every new insertion. So I would suggest don't insert records while boot startup better to insert programmatically.
For your learning you can use as given above but if it may use in production then better to implement your own logic to generate the sequence.
I had similar problem. If I understand things correctly It went down like this.
Before Spring upgrade I used AUTO - but it actually opted by default to IDENTITY strategy. I had auto incrementing PKs defined like this:
id BIGINT AUTO_INCREMENT PRIMARY KEY
Everything was fine.
With spring upgrade I had to specify H2 dialect:
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
I've read that if you use Hibernate as your persistence provider, it selects a generation strategy based on the database specific dialect. For H2 it probably opted for global sequence (that's what AUTO should mean according to JPA spec) - and it didn't find the sequence.
Solution is of course create the sequence (as suggested above) or manually override to originally auto selected IDENTITY.
CREATE SEQUENCE HIBERNATE_SEQUENCE START WITH 1 INCREMENT BY 1;
#GeneratedValue(strategy = GenerationType.IDENTITY)
I believe that root cause is that meaning of AUTO is/was not consistent/well defined/understood in time. Probably original 'auto' switch to IDENTITY was basically a bug.

Dynamic values for JPA id generation table using #TableGenerator

I have a Spring based application which uses JPA 2.1 for the persistence layer.
I use #TableGenerator and #GeneratedValue annotations to handle my primary key id generation.
These are the annotations:
#TableGenerator(name = "user_gen", table = "id_gen", pkColumnName = "gen_name", valueColumnName = "gen_val", allocationSize = 1)
…
#GeneratedValue(strategy = GenerationType.TABLE, generator = "user_gen")
I use this entity to insert records in my user table.
It was all working good.
Now I have a new problem. An external application needs to insert records in my user tables. This causes primary key violation at my end.
Is there any option in JPA which will make my id_gen table's gen_val value updated based on the max id of my user table?
[I could not find such a solution in my research]
Other thoughts to fix the issue are also welcome.
You might make it work with custom id generator where you would check for maximum id before each insert, but I wouldn't recommend it. In my opinion, this would be best handled on database level.
How is that application generating id's? They have to get it from somewhere, so why not why not handle id in that step. Best option would be if it can use the same id_gen mechanism for this. Several ideas:
After inserting the data, they could just call your stored procedure which would take care of synchronizing ids
They could call your stored procedure prior to insert, which would return them the id for the new row
They could call your stored procedure which would insert the data instead of them inserting it directly, and you would handle the id

how to implement auto increment in jpa

I am about learning JPA, and I want to know how can we tel the entity manager that the primary key field is generated using the database auto increment to the table?
I am using Mysql 5.5 and Oracle Enterprise For Eclipse(OEFE)
thanks for help
If you have a a id which needs to be auto incremented then ,
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;

postgresql - define serial data type in java project

I use play! framework 2.0 and postgresql.
in my db there is users table and every user ofcourse has a unique id.
so I defined it as serial.
my question is: how to represent a field which it's data type is serial
in my java project.
p.s. I understood play! framework uses Hibernate annotation
From the PostgreSQL documentation, the SERIAL type is equivalent to an ìnteger` with a sequence, so:
CREATE TABLE tablename (
colname SERIAL
);
is equivalent to specifying:
CREATE SEQUENCE tablename_colname_seq;
CREATE TABLE tablename (
colname integer DEFAULT nextval('tablename_colname_seq') NOT NULL
);
The #Id JPA annotation on the Long type will provide a sequence (equivalent to AUTO_INCREMENT in MySQL).
So, in you class, just use:
#Id
public Long id;
OK. I just added the annotation #Id

Categories