I have entity where id generated using sequence
#Id
#SequenceGenerator(name = "ENTITY_SEQ", sequenceName = "ENTITY_SEQ", allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ENTITY_SEQ")
#Column(name = "ID", unique = true, nullable = false)
public Long getId() {
return id;
}
And it work OK. But when i cretate test and set id manualy, sequence rewrite value and set it's own value. Is any posibility to change priority of setting value to ID?
Related
I am trying to perform Batch Insert with spring data jpa and Hibernate but the problem is Hibernate only supports batch inserts when the generated value strategy is SEQUENCE but somehow sqlite does not support this strategy so I resort to Identity which works fine but does not support batching with hibernate. Is there any solution or workaround for this.
Entity
#Entity
#Table(name = "party")
public class PartyEntity implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "party_id", nullable = false)
private Long id;
#Column(name = "party_name", unique = true)
#NonNull
private String name;
#Column(name = "party_phone_number", unique = true)
private Long number;
}
SQLite do have this table called 'sqlite_sequence' which I try to use with #SequenceGenerator but hibernate tries to create this table which we cannot as this is a reserved table. And same goes for #TableGenerator.
Annotation for sequence used
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "party_seq")
#SequenceGenerator(name = "party_seq", sequenceName = "sqlite_sequence", allocationSize = 1)
Annotation for table used
#GeneratedValue(strategy = GenerationType.TABLE, generator = "sqlite_generator")
#TableGenerator(name = "sqlite_generator", table = "sqlite_sequence", pkColumnName = "name",
valueColumnName = "seq", pkColumnValue = "party", initialValue = 1, allocationSize = 1)
DDL script for the table
CREATE TABLE party (
party_id INTEGER PRIMARY KEY ASC AUTOINCREMENT,
party_name VARCHAR (256) UNIQUE
NOT NULL,
party_phone_number INTEGER (10) UNIQUE
);
I can not figure out how to set the initial value for the #GenerateValue #Id.
I have tried using GenerationType.SEQUENCE but that is not allowed in MySQL. How can I set the initial value to be used for the #GenerateValue?
Using both AUTO and TABLE I can still not get the initial value to start at anything but 1
Thank you
Code using AUTO
#Entity
#Data
#SequenceGenerator(name = "port_gen", sequenceName = "port_gen", initialValue = 4700)
public class AppiumPort {
#Id
#GeneratedValue(strategy = GenerationType.AUTO, generator = "port_gen")
private Long port;
public AppiumPort() {
}
}
Code using TABLE
#Entity
#Data
public class AppiumPort {
#TableGenerator(name = "Address_Gen", table = "ID_GEN", pkColumnName = "GEN_NAME", valueColumnName = "GEN_VAL", pkColumnValue = "Addr_Gen", initialValue = 10000, allocationSize = 100)
#Id
#GeneratedValue(strategy = GenerationType.TABLE, generator = "Address_Gen")
private int port;
public AppiumPort() {
}
}
** UPDATE **
The problem was related to not setting hibernate.id.new_generator_mappings=true;
https://docs.jboss.org/hibernate/stable/annotations/reference/en/html/ch01.html
Application.properties for Sring Boot:
spring.jpa.properties.hibernate.id.new_generator_mappings=true
You could try and use the #TableGenerator (JPA has a #TableGenerator annotation in which you can set an initial value). The initialValue can be used to seed the values
Example here : http://www.java2s.com/Code/Java/JPA/SetInitialValueOfTableGenerator.htm
this worked for me:
#Id
#GenericGenerator(
name = "customers-sequence-generator",
strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
parameters = {
#Parameter(name = "sequence_name", value = "customers_sequence"),
#Parameter(name = "initial_value", value = "1000"),
#Parameter(name = "increment_size", value = "1")
})
#GeneratedValue(generator = "customers-sequence-generator")
#Column(nullable=false, updatable=false)
#JsonProperty("id")
private long id;
I've tried to use custom id-generator as in Bypass GeneratedValue in Hibernate (merge data not in db?) and it works fine while working with Postgres DB. My code is equals to the code in example.
But while running test with H2 in-memory database I faced the problem, that id is not generated automaticaly.
Without custom generator
#Column(name = "id", nullable = false)
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Generated create table script
create table db.schema.entity (id bigserial not null...
With custom generator
#Column(name = "id", nullable = false)
#Id
#GeneratedValue(generator = "idGenerator", strategy = GenerationType.IDENTITY)
#GenericGenerator(name="idGenerator", strategy = "...UseIdOrGenerate")
private Long id;
Generated create table script
create table db.schema.entity (id int8 not null...
As a result tests don't work.
Solved by changing #Column
#Column(name = "id", nullable = false, columnDefinition = "bigserial")
Today I got very strange behavior. I have declared a model with a primary key that uses #SequenceGenerator:
#SequenceGenerator(name="EMP_SEQ_GEN", sequenceName="EMP_SEQ")
#Id
#GeneratedValue(generator="EMP_SEQ_GEN_GEN")
#Column(name = "EMP_ID", unique = true, nullable = false, precision = 22, scale = 0)
public Long getEmpId() {
return this.empId;
}
It works locally but it doesn't work on the server. I have connected to the same database from both environments.
I think your #GeneratedValue should look like #GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "EMP_SEQ_GEN").
Is it possible to use 2 sequence generators in Hibernate Entity Class. I want to use two sequence generator for my case one for the primary key and other for a simple field. How can i achieve the same?
#Data
#Table(name="a_b")
#SequenceGenerator(name = "a1_seq", sequenceName = "a1_seq", allocationSize = 1)
#SequenceGenerator(name = "b1_seq", sequenceName = "b1_seq", allocationSize = 1)
public class ABC {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "a1_seq")
private Integer id;
#Column(name = "c")
private String c;
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "b1")
#Column(name = "b)
private Integer b;
}
You should have only one SequenceGenerator for the Primary Key:
#Id
#Column(name = "id")
#SequenceGenerator(name = "a1_seq", sequenceName = "a1_seq", allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "a1_seq")
private Integer id;
and for the foreign key you could have:
#Column(name = "b, columnDefinition="serial")
private Integer b;
which should work for PostgreSQL.
Define your #SequenceGenerator at column level rather than at class level. So you can create two separate sequenceGenerator - a1_seq and b1 for two different columns.
#Data
#Table(name="a_b")
public class ABC {
#Id
#Column(name = "id")
#SequenceGenerator(name = "a1_seq", sequenceName = "a1_seq", allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "a1_seq")
private Integer id;
#Column(name = "c")
private String c;
#SequenceGenerator(name = "b1_seq", sequenceName = "b1_seq", allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "b1")
#Column(name = "b)
private Integer b;
}
This should work. I have not tested it but since SequenceGenerator is allowed at field level, it should work.
Trick is to add #Id annotation to both Sequence Generators. You can achieve this by using #IdClass().
#Entity
#Table(name = "table_name")
#IdClass(DBSequenceId.class)
public class DBSequence implements Serializable {
#Id
#SequenceGenerator(name = "yourName1", sequenceName = "yourSeqName1", allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "yourName1")
#Column(name = "first_seq", updatable = false)
protected int firstSeq;
#Id
#SequenceGenerator(name = "yourName2", sequenceName = "yourSeqName2", allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "yourName2")
#Column(name = "second_seq", updatable = false)
protected int secondSeq;
}
class DBSequenceId implements Serializable {
private int firstSeq;
private int secondSeq;
//Setters and getters are omitted
}
Tested on MariaDB