Spring JPA - последовательность кэширования дает неожиданное поведение.Использование размера выделения = 1 нормально - PullRequest
0 голосов
/ 20 февраля 2019

Приложение My Spring Boot использует 2 класса сущностей.Класс сущности 1 использует идентификатор технического ключа, который использует последовательность.Сущность содержит список других сущностей, поэтому один ко многим.Дочерний объект использует ту же последовательность.

Используя размер 20 для последовательного выделения (кэширования), я вижу, что получаю EntityExistsException:

javax.persistence.EntityExistsException: другой объект с таким же значением идентификатора уже был связанс сеансом: [nl.xyz.app1.entity.ChildFields # 123456]

Объектами являются:

@Entity
@Table(name = "CHILD_FIELDS")
public class ChildFields implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "my_entity_seq_gen")
    @SequenceGenerator(name = "my_entity_seq_gen", sequenceName = "MYSEQ_S01")
    @Column(name = "CF_ID", unique = true, nullable = false)
    private Long id;

    @Column(name = "CF_DETAILS_ID")
    private Long detailsId;

И

@Entity
@Table(name = "PARENTS_OBJECT")
public class ParentObject implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "my_entity_seq_gen")
    @SequenceGenerator(name = "my_entity_seq_gen", sequenceName = "MYSEQ_S01")
    @Column(name = "PF_ID", unique = true, nullable = false)
    private Long id;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinColumn(name = "CF_DETAILS_ID")
    private List<ChildFields> children;

КогдаЯ использую последовательность размещения 1, тогда все в порядке!Почему это?

@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "my_entity_seq_gen" )
@SequenceGenerator(name = "my_entity_seq_gen", sequenceName = "MYSEQ_S01", allocationSize=1)

И т.д.

1 Ответ

0 голосов
/ 23 февраля 2019

Будьте осторожны при использовании JPA в сочетании с последовательностями БД.Решением является использование allocSize, равного 1. Я протестировал это как с Oracle, так и с Progress.

Вы можете найти хорошее объяснение через этот пост . Puspender Tanwar , дает подробное объяснение!

Проблема решена путем изменения значения Sequence IncrementBy на значение, которое я установил в allocSize of JPA.

СОЗДАЙТЕ ПОСЛЕДОВАТЕЛЬНОСТЬ "APPS". "LINE_LOCQTY_JPA_ID_SQ" MINVALUE 1 MAXVALUE 999999999999999999999999999 УВЕЛИЧЕНИЕ НА 20 НАЧАЛЕЙ С 7641 КЭШ 20 НИКР. NOORDER;

Последовательность 1 для последующего значения (для 1-й последовательности): Объяснение для проблемы 1 (последующее объяснение): Объяснение для проблемы 1: последующее объяснение для проблемы (объяснение для проблемы 1): Объяснение для 1-й последовательности (последующее значение) для 1-й последовательности (последующее значение) для 1-й последовательности (для 1-й последовательности): Объяснение для 1-й последовательности (последующее значение) для 1-й последовательности (последующее значение) для 1-й последовательности (последующее значение) для 1-й последовательности (последующее значение) для последующего вопроса для проблемы (объяснение для проблемы)*

  1. Когда JPA требуется значение Id, оно попадает в последовательность DB и запрашивает уникальное значение, Sequence возвращает 7641.
  2. Теперь JPA имеет начальную точку для идентификатора и основана на allocSize= 20, JPA сама создает следующие 20 значений и генерирует от 7641 до 7660 уникальных идентификаторов.
  3. Теперь, когда все эти идентификаторы используются, JPA запрашивает последовательность DB для следующего уникального значения.И поскольку последнее возвращенное значение было 7641, последовательность возвращает 7642 (поскольку значение INCREMENTBY было равно 1).
  4. JPA получает 7642 и создает в кэше следующие 20 значений.
  5. Время, когда JPA пытаетсяприсваивая эти значения идентификатору, он обнаруживает, что 7642 уже был назначен объекту сущности (на шаге 2).

Как INCREMENTBY 20 решил проблему: когда идентификаторы используются на шаге 3, JPA спрашиваетдля следующего значения последовательности.Последнее возвращаемое значение было 7641, поэтому на этот раз он увеличит его на 20 и вернет 7661. JPA создает значения от 7661 до 7680 и использует их.И, следовательно, нет уникальной проблемы нарушения ключа.

...