问题
I'm working on a simple project using sqlite, JPA and eclipseLink.
First I create my Person
table in my database with this:
CREATE TABLE Person (
idPerson INTEGER PRIMARY KEY AUTOINCREMENT,
firstname TEXT DEFAULT 'NULL',
birthdate DATETIME DEFAULT 'NULL'
)
and then add a new test entry (in order to generate the sqlite_sequence
table)
INSERT INTO [Person] ([firstname], [birthdate]) VALUES ('Foo', '1145-11-12 00:00:00')
All the successive insertion are done using JPA, where in the Person
class I use this notation for the person id:
@GeneratedValue(generator="sqlite_person")
@TableGenerator(name="sqlite_person", table="sqlite_sequence",
pkColumnName="name", valueColumnName="seq",
pkColumnValue="Person")
@Column(name="idPerson")
private int id;
The first JPA insertion is ok (that is, new new inserted person has id = 2) but then I get an increment of 50 instead of only 1 (so the third inserted person has id = 52, the fourth 102 and so on).
I read that "making modifications to this table will likely perturb the AUTOINCREMENT key generation algorithm" [ref]
Is my problem related to this, even if in theory I'm not modifying that table? Any kind of suggestion in order to resolve the problem?
回答1:
You are using Autoincrement in the database, which means the database will assign a value to the id when it is inserted, but then you tell the JPA provider to use Table generation. Table generation requires that the JPA provider use a special table to keep track of sequence values, looking it up and assigning it before inserting the entity row in the database. This conflicts with what you set up in the database.
http://wiki.eclipse.org/EclipseLink/Examples/JPA/PrimaryKey explains sequencing fairly well. You will need to try using @GeneratedValue(strategy=GenerationType.IDENTITY) instead of table generation so that inserts by JPA use the same sequence allocation as inserts outside of JPA.
回答2:
At the end, in order to solve the problem, I just added two optional elements for the TableGenerator
annotation (i.e. initialValue
, allocationSize
).
So the new annotation for the ID is like this:
@GeneratedValue(generator="sqlite_person")
@TableGenerator(name="sqlite_person", table="sqlite_sequence",
pkColumnName="name", valueColumnName="seq",
pkColumnValue="Person",
initialValue=1, allocationSize=1)
@Column(name="idPerson")
private int id;
I think it works also without the initial value, but like this I also avoid to insert random entries (because it seems that the sqlite_sequence
table is automatically generated already when I create the Person
table)
来源:https://stackoverflow.com/questions/20573547/wrong-autoincrement-value-in-sqlite-using-jpa