JPA автоматически генерирует идентификаторы унаследованных объектов, не увеличенных, как определено в генераторе последовательности в суперклассе
У меня странное поведение автоматической генерации идентификатора на сохраняющихся унаследованных объектах. У меня есть объект лица с генератором последовательности, который увеличивается на 4, и он работает нормально. У меня есть две другие сущности Клиент и Агент, которые наследуют Person и используют идентификатор человека в качестве ПК. У меня есть объект политики, который содержит 3 присоединенных объекта: 2 клиента и агент. Когда я сохраняю политику [менеджер сущностей] сохраняю (политика) Это вызывает
select nextval('sk_db.person_id_sequence')
Для первого Клиента и увеличивает id, как предполагается, но при сохранении двух других сущностей: Клиента и Агента, он вызывает только:
select lastval()
и увеличивает на 1, а не на 4, как предполагается. Я не могу понять это поведение. Что я здесь пропустил?
Я использую:JPA EclipseLink и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;
...
}
Класс клиента и агента:
@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, ....]
Но автоматически генерируемые идентификаторы должны быть: 50, 54, 58.
В последовательности базы данных я вижу перед вставкой:
текущее значение: 46 следующее значение: 50
После вставки:
текущее значение: 50 следующее значение: 54
В следующем случае я получаю следующие идентификаторы: 52, 51, 50.
РЕШЕНИЕ:
Исправлено изменение allocSize в 1, когда установка этого параметра указывает на кеш, сколько раз будет увеличиваться следующее значение до тех пор, пока оно не получит следующее значение из базы данных. В документации Java API это параметр означает увеличение на, но это работает иначе, не знаю Зачем.