@SequenceGenerator’s initValue and allocationSize are ignored and generators are not assigned to @Id fields (H2, HIbernate, Spring)
I use JPA in a Spring application configured to use an embedded H2 database.
I have a user entity defined like this:
@Entity
@SequenceGenerator(name = "myseq", sequenceName = "MY_SEQ", initialValue = 1000, allocationSize = 1)
public class User {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "myseq")
private Long id;
@Column(name = "USERNAME")
private String userName;
@Column(name = "PASSWORD_ENCODED")
private String passwordEncoded;
@ManyToMany
@JoinTable(name = "USER_ROLES", joinColumns = @JoinColumn(name = "USER_ID", referencedColumnName = "ID"), inverseJoinColumns = @JoinColumn(name = "ROLE_ID", referencedColumnName = "ID" ))
private Set<Role> roles;
}
getters
}
The context is defined as follows:
@Configuration
@EnableWebMvc
@EnableWebSecurity
@EnableAutoConfiguration
@EnableJpaRepositories(basePackages = "my.package")
@EntityScan(basePackages = "my.package")
@ComponentScan(basePackages = "my.package" )
public class AuthenticationWebAppContext extends WebSecurityConfigurerAdapter {
}
As you can see from the generated logs, the MY_SEQ was generated. However, initialValue and allocationSize are completely ignored, and the sequence does not have the id field assigned to USER
17:22:29.236 [main] DEBUG org.hibernate.SQL - create sequence my_seq start with 1 increment by 1 17:22:29.237 [main] DEBUG org.hibernate.SQL - create table role (id bigint generated by default as identity, name varchar(255), primary key (id)) 17:22:29.248 [main] DEBUG org.hibernate.SQL - create table user (id bigint not null, password_encoded varchar(255), username varchar(255), primary key (id))
So, when a row insert is attempted by data.sql file, I got the following error:
Caused by: org.h2.jdbc.JdbcSQLException: NULL not allowed for column "ID"; SQL statement:
INSERT INTO user (USERNAME, PASSWORD_ENCODED) VALUES ('user1', '<some_giberish>') [23502-194]
What am I missing?
Solution
Your JPA
settings are correct, but you must remember that when using the Hibernate or JPA API.
This
does not happen when you perform the insert “manually” in the data.sql
file. You have to manually invoke the sequence there:
INSERT INTO user (ID, USERNAME, PASSWORD_ENCODED)
VALUES (NEXTVAL('my_seq')'user1', '<some_giberish>')
Edit
This property: spring.jpa.hibernate.use-new-id-generator-mappings
or hibernate.id.new_generator_mappings=true
(if you do not use spring boot) will allow initialValue
Feature support.