Has Spring-boot changed the way auto-increment of ids works through @GeneratedValue?
Solution 1
Spring Boot 2.0 uses Hibernate 5.2 (https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Release-Notes).
Hibernate changes its GeneratedType.AUTO
strategy since 5.2. Any database that does not support sequences natively (e.g. MySQL), they use the TABLE generator instead of IDENTITY. (https://hibernate.atlassian.net/browse/HHH-11014)
That's why GeneratedType.AUTO
does not work as you expected.
Solution 2
You can use
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
to use MySQL autoincrement.
Solution 3
As Andrew has pointed out in the comment, if you don't want the id to be incremented while values are created in other tables, you can specify your ID like this:
@Id
@GeneratedValue(
strategy= GenerationType.AUTO,
generator="native"
)
@GenericGenerator(
name = "native",
strategy = "native"
)
private Long id;
Doing this will make each table has its unique id beginning with 1,2,3 ... and so on.
Solution 4
If you are in need for a quick, not future-proof solution to prevent this issue from happening:
spring.jpa.hibernate.use-new-id-generator-mappings=false
, as from the Spring Boot 2 docs:
spring.jpa.hibernate.use-new-id-generator-mappings= # Whether to use Hibernate's newer IdentifierGenerator for AUTO, TABLE and SEQUENCE.
This will prevent from using the new generators and keep the old functionality included in Spring boot 1.x.x.
Please note that this is probably not the best solution, but it is very helpful on short term
Admin
Updated on July 24, 2022Comments
-
Admin almost 2 years
Spring-Boot 2.0.0 seems to have modified the way Hibernate is auto configured.
Let's suppose two simple and independent JPA entities:
@Entity class Car { @Id @GeneratedValue private long id; //.... } @Entity class Airplane { @Id @GeneratedValue private long id; //.... }
Prior, using Spring-Boot 1.5.10, I was able to generate separate sequences of auto-increments, meaning that I can get a
Car
with 1 as primary key and anAirplane
with 1 as primary key too. No correlation between them, e.g no shared sequence.Now, with 2.0.0, when I sequentially create a very first
Car
then a very firstAirplane
, the car gets 1 as id and airplane gets 2.It seems that he has to deal with the
GeneratedType.AUTO
, that is the "used by default" specified within the@GeneratedValue
annotation source.
However, my reasoning seems to stop here sinceGeneratedType.AUTO
was also set as default with the 1.5.10.A simple workaround to fulfil my expectation is to specify the
IDENTITY
strategy type of generation like so:@Entity class Car { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; //.... } @Entity class Airplane { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; //.... }
I can't figure out an explanation of this behavior.
What has Spring-boot 2.0.0 changed, explaining this scenario?