为什么JPA实体管理器使用glassfish导致重复的键值错误?

时间:2012-10-04 01:28:13

标签: postgresql jpa glassfish java-ee-6

我目前每隔几秒钟从JMS客户端发送大约3条消息发送到MDB。 MDB正在使用JPA实体管理器将数据持久保存到PostgreSQL。这个工作正常大约一分钟左右。

然后问题变成了这个消息......

Caused by: javax.ejb.EJBException: Exception [EclipseLink-4002] (Eclipse Persistence
Services - 2.3.2.v20111125-r10461):org.eclipse.persistence.exceptions.DatabaseExcep
tion Internal Exception: org.postgresql.util.PSQLException: ERROR: duplicate key value
violates unique constraint "scan_pkey"
Detail: Key (id)=(984) already exists.
Error Code: 0
Call: INSERT INTO Scan (id, th, ag, dl) VALUES (?, ?, ?, ?
)
    bind => [11 parameters bound]

继承我的扫描实体。

@Entity
@SequenceGenerator(name="scanIdGen", initialValue=1000, sequenceName="scan_seq")
@Table(name="Scan")
public class Scan implements Serializable {
    @Id
    @Column(name="id")
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="scanIdGen")
    private Integer id;

    @Column(name="th")
    private Integer th;

    @Column(name="ag")
    private Integer ag;

    @Column(name="dl")
    private Integer dl;

    // ...
}

这是数据库架构。

CREATE SEQUENCE scan_seq START 1000;
CREATE TABLE Scan (
    id       INTEGER DEFAULT NEXTVAL('scan_seq') PRIMARY KEY    
    th       INTEGER DEFAULT NULL,
    ag       INTEGER DEFAULT NULL,
    dl       INTEGER DEFAULT NULL
);

另一个看似不那么大的问题是我的主键不是真正从1000开始,而是通常在950.不知道为什么。

任何帮助都非常感激。

1 个答案:

答案 0 :(得分:1)

猜测Glassfish / EclipseLink要求JPA标准规定的默认序列增量为50(出于某种疯狂的原因)。 PostgreSQL序列默认增量为1。

allocationSize中指定@SequenceGenerator为1,例如:

@SequenceGenerator(name="scanIdGen", sequenceName="scan_seq", allocationSize=1)

或使用IDENTITY生成策略。