我正在使用sqlite,JPA和eclipseLink开发一个简单的项目。
首先,我使用以下方法在我的数据库中创建Person
表:
CREATE TABLE Person (
idPerson INTEGER PRIMARY KEY AUTOINCREMENT,
firstname TEXT DEFAULT 'NULL',
birthdate DATETIME DEFAULT 'NULL'
)
然后添加一个新的测试条目(以生成sqlite_sequence
表)
INSERT INTO [Person] ([firstname], [birthdate]) VALUES ('Foo', '1145-11-12 00:00:00')
所有连续插入都是使用JPA完成的,在Person
类中,我对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;
第一个JPA插入是好的(也就是说,新插入的人有id = 2)但是后来我得到的是50而不是1的增量(所以第三个插入的人有id = 52,第四个102等等上)。
我读到“对此表进行修改可能会扰乱AUTOINCREMENT密钥生成算法” [ref]
我的问题是否与此相关,即使理论上我不修改该表? 有什么建议可以解决问题吗?
答案 0 :(得分:1)
您正在数据库中使用自动增量,这意味着数据库将在插入时为id分配值,但是您告诉JPA提供程序使用表生成。表生成要求JPA提供程序使用特殊表来跟踪序列值,查找并在将实体行插入数据库之前进行分配。这与您在数据库中设置的内容相冲突。
http://wiki.eclipse.org/EclipseLink/Examples/JPA/PrimaryKey解释相当好。您需要尝试使用@GeneratedValue(strategy = GenerationType.IDENTITY)而不是表生成,以便JPA的插入使用与JPA之外的插入相同的序列分配。
答案 1 :(得分:0)
最后,为了解决问题,我刚为TableGenerator
注释添加了两个可选元素(即initialValue
,allocationSize
)。
所以ID的新注释是这样的:
@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;
我认为它也没有初始值,但是像这样我也避免插入随机条目(因为在我创建sqlite_sequence
表时似乎已经自动生成了Person
表)