0

我对持久继承的实体有一个奇怪的自动生成 id 行为。我有一个带有序列生成器的人员实体,它以 4 递增,并且工作正常。我有另外两个实体 Client 和 Agent,它们继承 Person 并将人员 ID 用作 pk。我有一个包含 3 个连接实体的策略实体:2 个客户端和代理。当我坚持策略[entity manager]persist(policy)它调用

select nextval('sk_db.person_id_sequence')

对于第一个客户端,并按照假设增加 id,但是在持久化其他 2 个实体时:客户端和代理,它只调用:

select lastval()

并按预期增加 1 而不是 4。我无法理解这种行为。我在这里错过了什么?

我使用: JPA EclipseLinkPostgresql


@Entity
@Table(name = "Person", schema = Constraints.DB_SCHEMA)
public class TPerson implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @SequenceGenerator(name = "personIdGenerator", sequenceName = "person_id_sequence", initialValue = 6, allocationSize = 4)
    @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "personIdGenerator")
    protected long id;
    ...
}

客户端和代理类:

@Entity
@Table(name = "Client", schema = Constraints.DB_SCHEMA)
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorValue(value = "Client")
public class TClient extends TPerson implements Serializable {

    private static final long serialVersionUID = 1L;
    ...
}

具有联合关系的策略类:

@Entity
@Table(name = "Policy", schema = Constraints.DB_SCHEMA)
@DiscriminatorColumn(name = "classType")
public class TPolicy implements Serializable {

    private static final long serialVersionUID = 1L;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "policyOwnerId", referencedColumnName = "id", updatable = false, insertable = false)
    private TPerson policyOwner;

    @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH })
    @JoinColumn(name = "agentId", referencedColumnName = "id", updatable = false, insertable = false)
    private TAgent agent;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "transportOwnerId", referencedColumnName = "id", updatable = false, insertable = false)
    private TPerson transportOwner;

我的架构:

CREATE SEQUENCE sk_db.person_id_sequence INCREMENT BY 4 START 2 CYCLE;

create table if not exists SK_DB.Person 
(
  id bigserial PRIMARY KEY,
  ..
);

create table if not exists SK_DB.Client
(
  id bigserial REFERENCES SK_DB.Person(id),
  ..
)

create table if not exists SK_DB.Agent
(
  id bigserial REFERENCES SK_DB.Person(id),
  ..
)

坚持政策后:

em.persist(policy);

我在日志中收到:

    [EL Fine]: sql: ... --select nextval('sk_db.person_id_sequence')
    ..
    [EL Fine]: sql: ....--select lastval()
    [EL Fine]: sql: ....--INSERT INTO sk_db.Person (ID,....) VALUES (...)
    bind => [48, ....]
    [EL Fine]: sql: ....--select lastval()
    [EL Fine]: sql: ....--INSERT INTO sk_db.Person (ID,....) VALUES (...)
    bind => [49, ....]
    [EL Fine]: sql: ....--select lastval()
    [EL Fine]: sql: ....--INSERT INTO sk_db.Person (ID,....) VALUES (...)
    bind => [47, ....]

但是自动生成的 id 应该是: 50, 54, 58

在插入之前我看到的数据库序列中:

当前值:46 下一个值:50

插入后:

当前值:50 下一个值:54

在下一个持久化中,我收到以下 ID:52、51、50。


解决方案:

将 allocationSize 更改为 1 是固定的,当设置此参数表示缓存时,下一个值将增加多少次,直到它将从数据库中获取下一个值,在 javaee api 文档中,此参数表示递增,但它的工作方式不同不知道为什么。

4

0 回答 0