Spring Hibernate Double ID Every Server Restart - spring

I have multiple entity and all their Id fields set with this. And I am using Spring Data JPA btw.
#Id
#GeneratedValue(strategy = GenerationType.TABLE)
When I restart Tomcat every time DB's ID column double itself like this. And entity doesnt matter. All table's ID like this. Not only this one.
As you see Id column change sequence itself. I delete all the DB and try again, but not working.

Related

Spring Data Hibernate Idenity strategy not generating values from 1, can someone explain me how this works?

I am trying to insert a record from my spring application, but whenever I try to insert a new record, ID generated is 6 digit value even if there are no records present in the database. Can someone help me on why is it working this way.
My Entity class code is:
#Entity
public class Customer {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer customerId; ... rest of code
Database table had one record previously and when I added a new record, generated value was as shown.(P.s. my database had records previously which I deleted and added a new record(rohan) manually using mysql and when another record was added, this value was generated.)
mysql database snapshot

Optimistic locking - session based locking

I have a question related to optimistic locking in Spring/Hibernate actually.
I have following scenario with typical REST application with SQL database.
User A enters page and reads data - version 0 of entity - GET request
User B enters page and reads data - version 0 of entity - GET request
User A saves data - version 1 of entity - PUT request
User B wants to save data (PUT request), but I should see optimistic lock exception
Now my question:
Where hibernate saves data about entity version? I understand the situation when everything is in the same transaction:
Load data
Someone changed entity in the different transaction
Save data
But in my situation version will vanish GET and PUT are in totally different transaction/threads etc.
In my opinion I should save somewhere version loaded by the user to have correlation between GET and PUT requests e.g. in HTTP session or just return version in the response and then send that version in the PUT request.
Can it be done in the better way? Like out of the box?
JPA/Hibernate have #Version column in entity definition to check optimistic or pessimistic lockings. JPA/Hibernate saves versions in the table. For example you have Country table in db:
CREATE TABLE country (
id BIGINT NOT NULL AUTO_INCREMENT,
version BIGINT DEFAULT 0,
...
);
And Country entity:
#Entity
#Table(name = "country")
public class Country implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false)
private Long id;
#Version
#Column(name = "version")
private Long version;
...
}
If you update the country entity instances with optimistic lock conflicts, you get OptimisticLockException in JPA. You don't need to manage the versions, JPA/Hibernate checks the versions of entity instances for you.
Update for different transactions:
In different transactions you can get OptimisticLockException too because JPA/Hibernate checks in every update the version columns with database table. As long as you save your changes (commit), another changes of entity versions will be checked, doesn't matter whether in the same transaction or different transaction. Better you can manage your transactions with #Transactional annotation in Spring framework.

Spring data. How can I update an entity, having the id modified?

Spring data jpa + postgres.
Have an entity
class Entity {
#Id
#GeneratedValue// generator from here https://stackoverflow.com/questions/60989691/how-to-manually-set-a-value-for-generatedvalue/61007375#61007375
private int id;
private String value;
}
And what I wish to do is to UPDATE an existing entity, setting a different id (be it a bad practice or not) value.
By default it of course is treated as a new entity and is attempted to be INSERTed.
Going by the flow of #Modifying seems to do the job right, but currently struggling to find if I can pass the whole entity instead of pinpointing every field:
update Entity e set e.id=?1, e.value=?2 where...
to
update Entity e set e=?1
So the questions here would be:
1. Is there a way to gracefully do an "UPDATE" with modified id in terms or regular spring-data-jpa flow?
2. If not, is there a way to provide the full entity to be consumed by the #Query?
Is there a way to gracefully do an "UPDATE" with modified id in terms or regular spring-data-jpa flow?
If you are using GenerationType.AUTO strategy for #GeneratedValue (AUTO is the default strategy), then you can set id of Entity to null before calling save. It will insert a new record with rest of the fields being the same as original. id of new record will be generated automatically by database engine.
If you are using GenerationType.AUTO strategy for #GeneratedValue
If not, is there a way to provide the full entity to be consumed by the #Query?
You can chose not use #Query. A far simpler approach can be using default save method provided by JPA repositories to directly pass an Entity object.

Spring Data CrudRepository custom ID generator

I am using spring boot(1.4),spring data and jpa. And using #Repository(CrudRepository)
One of my Table/Entity, the ID column, I want to generate customised string.
Start with some specific string plus creation data and time, and end with next value from db.
so here I can't use #TableGenerator, I need some native query like "select nextvalue "
Is there better way can achieve this.
Add a "normal" ID column using #Id and #GeneratedValue and then manually fill your special column after the entity has been stored the first time.

Postgresql and Spring Roo Binding serial type for ID

I am having trouble using the Postgresql serial type in Spring Roo. What I want is to have the an auto-incrementing id column which will work with the auto generated entity classes in Roo.
The Postgresql sequences, which are generated with the default way of doing things in Spring Roo, work fine within the spring application. But sometimes I have to manually insert rows in the database using sql. (the sequences dont seem to work properly when I do an INSERT INTO... statement). If I could use serial type, then manual INSERTS are easy.
For example I have an office entity and and employee entity. There is a many-to-one relationship between employees and offices.
Here is my class for the Office entity.
#RooJavaBean
#RooToString
#RooJpaActiveRecord
public class Office {
#Id
#Column(name="officeid", columnDefinition = "serial")
#Generated(GenerationTime.INSERT)
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long officeid;
/**
* Office Name
*/
#NotNull
#Size(max = 100)
private String name;
}
While this does work when my test inserts an office record, it fails when an employee record is inserted since the officeid foreign key value is null. (I guess it needs to flush between the office insert and the employee insert, but the auto-generate tests dont seem to do that.)
So what is the proper annotations to use to tell Roo (and hibernate/jpa) to use the serial data type, and also to work properly with inserts and relationships within the spring application?
Roo generates default JPA annotations, you must customize and setup them as needed. Note Roo guarantees your changes won't be modified.

Resources