Java JPA/Ebean-强制@Id严格递增+;1使用PostgreSQL
我有以下型号:Java JPA/Ebean-强制@Id严格递增+;1使用PostgreSQL,java,postgresql,jpa,ebean,Java,Postgresql,Jpa,Ebean,我有以下型号: public class Parameter extends Model { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) public long id; } save()创建的记录如下所示: play=> select id from parameter; id ---- 1 2 3 4 5 21 (6 rows) 有没有一种方法可以告诉JPA总是将id增
public class Parameter extends Model {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public long id;
}
save()
创建的记录如下所示:
play=> select id from parameter;
id
----
1
2
3
4
5
21
(6 rows)
有没有一种方法可以告诉JPA总是将
id
增加一个整数,而不是随机跳到21?您应该能够通过使用@TableGenerator
和allocationSize=1
来实现这一点。示例代码如下所示。您需要创建一个单独的表来存储主键、额外的工作,但比@GeneratedValue
更便于携带
@TableGenerator(name="MAIN_PK_GEN", table="pk_gen", pkColumnName="GEN_NAME", valueColumnName="GEN_VALUE", pkColumnValue="MAIN_PK_GEN", allocationSize=1)
@Id @GeneratedValue(strategy=GenerationType.TABLE, generator="MAIN_PK_GEN" )
@Basic(optional = false)
@Column(name = "PK")
private Integer pk;
(但是使用allocationSize=1
可能没有效率)
请参阅以获取逐步解释。您所观察到的(跳到21)可能是4.0.5之前的Ebean的实现细节。Ebean正在序列上使用“提前提取”机制。在4.0.5版本之后,默认情况下,Eben切换到使用Postgres序列(因此,默认情况下,Eben/Postgres在4.0.5版本之后不会出现这种情况)。参考:
所有这些-‘精确递增1’通常是您希望避免的,因为它会成为并发问题(避免使autoincrement ID成为事务性的,因为这会引入争用)。当您需要“精确递增一”语义(如支票号码等)时,您可以提前批量创建。如果您使用的是Oracle,请不要忘记添加allocationSize为1的SequenceGenerator:
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "mysequence")
@SequenceGenerator(name = "mysequence", sequenceName = "mysequence", allocationSize = 1)
private Long id;
简言之,没有办法做到这一点。Id字段只保证是唯一的。有没有办法确保所有Id都比以前的Id大?那也可以。@doque在Ebean方面,它使用的是底层的DB序列(或DB autoincrement,取决于DB),因此通常是的,您会发现分配的ID比以前的任何ID都大,但严格来说不一定是这样,Oracle RAC也可能不是这样(或类似的聚集的DB,其中ID块是跨DB节点分配的)。您可以检查基础数据库上的DOCs /行为,但您可能认为添加“创建时”的时间戳列(使用Ebean时使用CreateTimestamp)更安全/更好。摘要:DB序列(和自动增量)将是唯一的,可能有间隙,通常是但不是严格递增的(取决于DB实现,例如Oracle RAC之类的DB集群),通常最好添加一个额外的“whenCreated”时间戳列,以帮助在您不能或不想依赖“IDs严格递增”时提供查询顺序。