How to achieve Batch Inserts with Spring data and SQLite? - java

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
);

Related

problem to get auto-incremented primary key with hibernate / postgres

Using hibernate 5.4, postgres 10 with IntelIiJ Ultimate, impossible to get auto-incremented primary key
with this following code, the sequence "warehouses_id_seq" is created but the primary key is not incremented
#Entity
#Table(name = "warehouses")
#SequenceGenerator(name = "SEQUENCE_WAREHOUSE", sequenceName = "warehouses_id_seq", allocationSize = 1)
public class Warehouse implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQUENCE_WAREHOUSE")
#Column(name = "id")
private Integer id;
I added below line to fix the problem:
#ColumnDefault("nextval('public.warehouses_id_seq')");
But I'm quite desapointed, I expected Hibernate to do it automaticaly with the SequenceGenerator...

Not able to save data using OneToOne mapping

I am trying to save data in two table using OneToOne mapping.I have followed
this,this,this,this and few more online resources to accomplish this, but it is throwing
ORA-02291: integrity constraint (TableName.TEST_ID) violated - parent key not found
Creating a table where column TESTID is foreign key. In the parent table TESTID is primary key.That primary key is generated using sequence generator
CREATE TABLE EW_TEST_REFTABLE (
ID int NOT NULL PRIMARY KEY,
TESTNAME VARCHAR2(20) NOT NULL,
TESTID int,
CONSTRAINT test_id FOREIGN KEY(TESTID)
REFERENCES EW_TESTDATA(TESTID)
);
Ew_testdataEntity.java (Entity class of parent table)
#Entity
#Table(name = "EW_TESTDATA")
public class Ew_testdata {
#Id
#SequenceGenerator(name = "sube_seq",
sequenceName = "EW_TESTDATA_SEQ",
allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sube_seq")
#Column(name = "TESTID")
private int testid;
#Column(name = "TESTNAME")
private String testname;
// Ew_test_reftable is another entity class.In that table the column
// TESTID (foreign key) must be same as the primary key of this
// entity/table(EW_TESTDATA)
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "TESTID",unique = true)
private Ew_test_reftable ewtestreftable;
//Constructor
// getter & setter
}
Ew_test_reftable.java
#Entity
#Table(name = "EW_TEST_REFTABLE")
public class Ew_test_reftable {
#Id
#SequenceGenerator(name = "subf_seq", sequenceName = "EW_REF_SEQ", allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "subf_seq")
#Column(name = "ID")
private int id;
#Column(name = "TESTNAME")
private String testname;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "TESTID")
private int testid;
//Constructor,getter & setter
}
Service to save data using Jpa
#Override
public Ew_testdata ew_testdata(String name) {
Ew_test_reftable ew_test_reftable = new Ew_test_reftable();
ew_test_reftable.setTestname("test");
Ew_testdata ew_testdata = new Ew_testdata();
ew_testdata.setTestname(name);
ew_testdata.setEwtestreftable(ew_test_reftable);
iew_tEst.ewTestdata(ew_testdata);
return null;
}
The problem seems to be similar to few other problem described in SO but still i am not able to figure out where I am making mistake
Your entity and table structure looks opposite, and that making so much confusion to understand.
Now, referring to exception
ORA-02291: integrity constraint (TableName.TEST_ID) violated - parent key not found
This mean, you don't have reference of parent id in child table when adding new row to child table.
In Ew_test_reftable class, you have
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "TESTID")
private int testid;
If I understand correctly, testid is your foreign key in EW_TEST_REFTABLE, then why are you using GenerationType.IDENTITY ? This will create new sequence id and may not match with parent key and result in error/exception.
As per my understanding of your design,
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "TESTID")
private int testid;
change to
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "TESTID",unique = true)
private Ew_testdata ew_testdata;
And similar to above code should be removed from Ew_testdata entity (There might be slight change here and there)

H2 in-memory database and custom #GenericGenerator strategy

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")

Set id from sequence vs manualy insert using JPA Hibernate

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?

Define primary and foreign keys in same object which use the sequence generators

I have created Address object which has a ID (AddressPK) which get generated by a sequence. The address object also has a foreign key to Client object via the ID of the client object (ClientPK). The ClientPK also generated via a sequence. However, it complains at the time I try to deploy the ear to web logic server saying that only one generated element can exist for an entity. The class snippets as follows. Anyone can help how to define a foreign key using an object that also uses a sequence generator in addition to the object primary key?
public class Address implements Serializable{
#EmbeddedId
private AddressPK id;
#Embedded
private ClientPK clientId;
...
}
#Embeddable
public class AddressPK implements Serializable {
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator="RoidSequenceGenerator")
#SequenceGenerator(name="RoidSequenceGenerator",sequenceName="roid_sequence", allocationSize=1)
#Column(name = "a_roid")
private long value;
...
}
#Embeddable
public class ClientPK implements Serializable {
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator="RoidSequenceGenerator")
#SequenceGenerator(name="RoidSequenceGenerator",sequenceName="roid_sequence", allocationSize=1)
#Column(name = "c_roid")
private long value;
...
}
I think you do not understand what is the Primary Key and what the difference from the Foreign Key. Primary key (PK) can be generated for each database entity. And there is a restriction in JPA that generated value must be only one. Foreign Key (FK) in the other hand is a link to the PK of another entity. So you need to create another entity with generated PK and have a link to it with OneToMany, ManyToMany or another kind of association. For example:
#TableGenerator(name = "entities_id_generator", table = "SEQUENCE",
pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue =
"ENTITY_SEQ", initialValue = 0, allocationSize = 1)
public class DBObject1 implements Serializable {
#Id
#GeneratedValue(generator = "entities_id_generator", strategy = GenerationType.TABLE)
private Long id;
#ManyToOne
#JoinColumn(name = "source_id")
private DBObject2 source;
}
#TableGenerator(name = "entities_id_generator", table = "SEQUENCE",
pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue =
"ENTITY_SEQ", initialValue = 0, allocationSize = 1)
public class DBObject2 implements Serializable {
#Id
#GeneratedValue(generator = "entities_id_generator", strategy = GenerationType.TABLE)
private Long id;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "source")
private List<DBObject1> objects;
}
In example above the virtual FK for entity DBObject1 will be stored in column source_id. It is virtual because there will not be any physical FK in database table. But JPA will link these objects if you ask.

Categories