当Eclipselink用作ORM时,生成的JPA实体的id会生成一个旧的",使用过的数字,但是对于Hibernate,id是序列的正确下一个值。 在实体类中,我使用带有id字段
的这些注释@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "s_customer")
@SequenceGenerator(name = "s_customer", sequenceName = "S_CUSTOMER")
private Long id;
我使用 flyway 来设置和填充db:
public void migrate(JdbcTemplate jdbcTemplate) throws Exception {
jdbcTemplate.execute("create sequence S_CUSTOMER");
jdbcTemplate.execute("create table CUSTOMER (" +
"ID BIGINT PRIMARY KEY," +
"DISPLAY_NAME VARCHAR(3000)," +
"VERSION BIGINT" +
")");
}
public void migrate(JdbcTemplate jdbcTemplate) throws Exception {
for (int i = 0; i < 10000; i++) {
jdbcTemplate.update(
"insert into CUSTOMER (ID, DISPLAY_NAME, VERSION) " + "select nextval('S_CUSTOMER'), ?, ? ",
"SAP-SE", 0);
}
}
作为数据库,我使用PostgreSQL。
当我的应用程序要使用eclipselink持久保存一个新实体时,我收到一个错误,因为该实体得到了一个&#34; old&#34; ID:
Call: INSERT INTO CUSTOMER (ID, DISPLAY_NAME, VERSION) VALUES (?, ?, ?)
bind => [3 parameters bound]
Query: InsertObjectQuery(Customer(id=9959, displayName=Bäckerei Brötchen, version=1)); nested exception is javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.6.3.v20160428-59c81c5): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "customer_pkey"
Detail: Key (id)=(9959) already exists.
但是当我手动选择序列的当前值时,我得到值&#34; 10004&#34;。那么为什么eclipselink会返回已经使用过的序列值呢? hibernate也是如此。
答案 0 :(得分:0)
虽然这是一个老问题,但最近我遇到了同样的问题。
当你在数据库中创建序列时,allocationSize
(默认为50)应与子句INCREMENT
(默认为1)相同。
所以如果你想要一个它会递增的序列,让我们说100,你应该这样写:
CREATE SEQUENCE my_seq_id
INCREMENT 100
MINVALUE 1
MAXVALUE 9223372036854775807
START 1;
JPA实体应该是这样的:
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "my_seq_id")
@SequenceGenerator(name = "my_seq_id", sequenceName = "my_seq_id", allocationSize = 100)
private Long id;
答案 1 :(得分:0)
我已经具有与数据库序列中定义的相同的allocationSize,但是仍然偶尔会得到旧的序列值。