0

I have a strange behavior of auto generation id on persisting inherited entities. I have a person entity with sequence generator which increments by 4 and it works fine. I have two other entities Client and Agent which inherit Person and use the person id as a pk. I have a Policy entity which contains 3 joined entities: 2 Clients and Agent. When I persist policy [entity manager]persist(policy) It calls

select nextval('sk_db.person_id_sequence')

For first Client, and increments id as suppose to do, but when persisting the other 2 entities: Client and Agent, it calls only:

select lastval()

and increments by 1 not by 4 as supposed to do. I cann't understand this behavior. What I missed here?

I use: JPA EclipseLink and Postgresql


@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;
    ...
}

Client and Agent class:

@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;
    ...
}

Policy class with joined relations:

@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;

My schema:

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),
  ..
)

after persisting policy:

em.persist(policy);

I receive in logs:

    [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, ....]

But the auto generated ids should be: 50, 54, 58.

In database sequence I see before insert:

current value: 46 next value: 50

After insert:

current value: 50 next value: 54

In the next persist I receive the following ids: 52, 51, 50.


SOLUTION:

Changing allocationSize to 1 is fixed, when setting this param indicates cache, how much times will be incremented the next value until it will take next value from database, In javaee api documentation this param means increment by, but it's work differently don't know why.

Ataman
  • 33
  • 2
  • 6

0 Answers0