表格Section
:
secID INTEGER Primary Key
secname TEXT
主键SQLite将自动设置在insert
上:
INSERT INTO Section(secname) VALUES("Default");
Section
类:
@Entity
@Table(name="\"Section\"")
public class Section implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name="\"secID\"")
private int secID;
@Column(name="\"secname\"")
private String secname;
+ Getter and Setter
}
使用SQLite我已经插入了两行。当我使用Java持久性API插入时:
Section sec = new Section();
sec.setSecname("Test2");
tx.begin();
em.persist(sec);
tx.commit();
它会将secID
设置为0。然后,当我插入另一行时,我会收到一个错误,因为这一次secID
= 1已经存在,这是因为SQLite中之前的两次插入(自动递增主键会自动将secID
设置为1和2)。
如何使用Java持久性API避免此问题?
3条答案
按热度按时间dddzy1tm1#
在您的idMap上添加
@GeneratedValue(strategy = GenerationType.IDENTITY)
就可以了。c3frrgcw2#
I don't think your second insert is colliding with the two values (
secID
= 1 and 2) already in the table; I think it's colliding with the value you just inserted (secID
= 0).You aren't explicitly setting
secID
anywhere, which means it's 0. So it's inserting 0, over and over.Change the field
secID
in your class to be anInteger
and not anint
, and it should behave as the SQLite docs suggest , where, when "you try to insert a NULL into an INTEGER PRIMARY KEY column, the column will actually be filled with an integer that is one greater than the largest key already in the table." (Again, right now you are inserting 0, notnull
.)ws51t4hk3#
加上这个以防有人在2022年及以后跌跌撞撞地进入这个。
虽然@Predrag Maric给出的答案对我很有效,但在大多数博客文章或教程中,在配置JPA和SQLite Dialect方面缺少一个步骤。我找到了解决这个问题的方法。原来SQL方言有一个极其重要的缺失函数,那就是类
SQLIdentityColumnSupport
中的hasDataTypeInIdentityColumn()
。这是添加函数后的外观。can be found here类实现的参考。
在此之后,一旦添加
GenerationType.IDENTITY
作为策略,SQLite将最终处理自动递增的id,并且INSERT
和UPDATE
操作将正常工作。