Hibernate Jpa - исключение нарушения ограничения на первичном ключе (последовательность) - PullRequest
0 голосов
/ 27 ноября 2018

Я использую Hibernate JPA в своем приложении.У меня есть таблица, которая имеет первичный ключ (последовательность).Служба вставляет записи в эту таблицу.

Версия: Oracle 12c

Диалект: org.hibernate.dialect.Oracle10gDialect

Проблема:

Мы столкнулись с проблемой (нарушение уникального ограничения на ключе SEQUENCE) во время нагрузочного тестирования.

Вопросы:

  1. Эта проблема не возникает все время.Но только во время нагрузочного теста.Может кто-нибудь проверить и помочь использовать потокобезопасный генератор?

  2. Это проблема определения последовательности на стороне БД или на стороне Java?

Последовательность БД:

CREATE SEQUENCE MY_SEQ    
START WITH 1
INCREMENT BY 1
NOMINVALUE
NOMAXVALUE
CACHE 30
NOORDER;

CREATE TABLE MY_TABLE    (  
    MY_PRIMARY_KEY INT default MY_SEQ.nextval NOT NULL,
    VALUE_COL VARCHAR2(10) NULL       
);

Объект:

public class MyTableEntity implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "MY_PRIMARY_KEY")
    @GenericGenerator(
        name = "mySequenceGenerator",
        strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
        parameters = {
                @Parameter(name = "sequence_name", value = "SEQUENCE MY_SEQ"),
                @Parameter(name = "increment_size", value = "1")
        }
    )
    @GeneratedValue(generator = "mySequenceGenerator")
    private long myPrimaryKey;

    @Column(name = "VALUE")
    private String value;

}

Ответы [ 2 ]

0 голосов
/ 25 декабря 2018

Oracle 10 Dialect

Для Oracle10gDialect используйте эту конфигурацию

@Id
@Column(name = "MY_PRIMARY_KEY")
@GeneratedValue(strategy=GenerationType.AUTO)
Long myPrimaryKey;

Hibernate создает таблицу и последовательность:

create table MY_TABLE (
MY_PRIMARY_KEY number(19,0) not null, 
VALUE varchar2(255 char), 
primary key (MY_PRIMARY_KEY))

create sequence hibernate_sequence 

Покапри его сохранении сначала получается новый идентификатор последовательности, а затем передается его в операторе INSERT

select hibernate_sequence.nextval from dual
insert into MY_TABLE (VALUE, MY_PRIMARY_KEY) values (?, ?)

Oracle 12 Dialect

Если вы используете Oracle 12 , который изначально поддерживаетIDENTITY column предпочтительно обновить до Oracle12cDialect (обратите внимание, что для этого требуется Hibernate 5.3)

Установите для strategy значение GenerationType.IDENTITY

@Id
@Column(name = "MY_PRIMARY_KEY", updatable = false, nullable = false)
@GeneratedValue(strategy=GenerationType.IDENTITY)
Long myPrimaryKey;

Создана следующая таблица - важная часть generated as identity, которая предоставляет уникальные значения.Обратите внимание, что явный sequence не требуется создавать, он управляется внутри.

create table MY_TABLE (
MY_PRIMARY_KEY number(19,0) generated as identity, 
VALUE varchar2(255 char), 
primary key (MY_PRIMARY_KEY))

При сохранении идентификатор не передается в INSERT , он присваивается Oracle и возвращаетсяк сеансу

insert into MY_TABLE (VALUE) values (?) RETURNING MY_PRIMARY_KEY INTO ? 

Обратите внимание, что в отличие от Oracle 10 вы сохраняете одну поездку в базу данных.

0 голосов
/ 28 ноября 2018

Изменить long на Long

Поскольку при использовании long он (по умолчанию) равен 0. Генератору не разрешено изменять существующие значения!

https://docs.oracle.com/javaee/7/api/javax/persistence/GeneratedValue.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...