Меню

Hibernate ошибка повторяющееся значение ключа нарушает ограничение уникальности

I have two objects with one-to-many relationship between them that I implemented as follows:

@Entity
@Table(name = "details")
public class MainDetails {
     @Id
     @Column(name = "details_id")
     @GeneratedValue(strategy= GenerationType.AUTO)
     private Long id;

     // Some other fields here - omitted

     @OneToMany(fetch = FetchType.LAZY,
                mappedBy = "details",
                targetEntity = State.class,
                cascade = CascadeType.ALL)
     @OrderBy("timestamp DESC")
     private List<State> states;
}

And the second one:

@Entity
@Table(name = "state")
public class State {

     @Id
     @Column(name = "state_id")
     @GeneratedValue(strategy = GenerationType.AUTO)
     private Long id;

     @ManyToOne(fetch = FetchType.LAZY)
     @JoinColumn(name = "details_id")
     private MainDetails details;

     // Other fields omitted (including timestamp)

}

I call a save() method on the MainDetails object. The method looks like this:

public T save(T obj) { // The T in this case is MainDetails
  entityManager.persist(obj);
  entityManager.flush();
  return obj;
}

But then I get this exception:

Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "details_pkey" Detail: Key (details_id)=(8) already exists.

My persistence.xml looks like this:

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
         version="2.0">
  <persistence-unit name="my-persistence-unit">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <!-- Annotated entity classes -->
    <class>com.company.entity.MainDetails</class>
    <class>com.company.entity.State</class>

    <properties>
      <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL82Dialect" />
      <property name="hibernate.hbm2ddl.auto" value="create-drop" />
      <property name="hibernate.enable_lazy_load_no_trans" value="true"/>
    </properties>
  </persistence-unit>
</persistence>

My spring context looks like this:

@EnableJpaRepositories(basePackages = {"com.company.dao", "com.company.*.dao"})
@EnableTransactionManagement(proxyTargetClass = true)
@Import(BasicConfig.class)
public class DbConfig {

  @Value("${db.connection_string}")
  private String connectionString;

  @Value("${db.user_name}")
  private String dbUserName;

  @Value("${db.password}")
  private String dbPassword;

  @Bean
  public DataSource dataSource() {
    DriverManagerDataSource driver = new DriverManagerDataSource();
    driver.setDriverClassName("org.postgresql.Driver");
    driver.setUrl(connectionString);
    driver.setUsername(dbUserName);
    driver.setPassword(dbPassword);
    return driver;
  }

  @Bean
  public JpaVendorAdapter jpaVendorAdapter() {
    HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
    adapter.setShowSql(true);
    adapter.setGenerateDdl(true);
    adapter.setDatabase(Database.POSTGRESQL);
    return adapter;
  }

  @Bean
  public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws ClassNotFoundException {
    LocalContainerEntityManagerFactoryBean factoryBean = new  LocalContainerEntityManagerFactoryBean();
    factoryBean.setDataSource(dataSource());
    factoryBean.setPersistenceUnitName("my-persistence-unit");
    factoryBean.setJpaVendorAdapter(jpaVendorAdapter());

    return factoryBean;
  }

  @Bean
  public JpaTransactionManager transactionManager() throws ClassNotFoundException {
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());

    return transactionManager;
  }
}

I have two objects with one-to-many relationship between them that I implemented as follows:

@Entity
@Table(name = "details")
public class MainDetails {
     @Id
     @Column(name = "details_id")
     @GeneratedValue(strategy= GenerationType.AUTO)
     private Long id;

     // Some other fields here - omitted

     @OneToMany(fetch = FetchType.LAZY,
                mappedBy = "details",
                targetEntity = State.class,
                cascade = CascadeType.ALL)
     @OrderBy("timestamp DESC")
     private List<State> states;
}

And the second one:

@Entity
@Table(name = "state")
public class State {

     @Id
     @Column(name = "state_id")
     @GeneratedValue(strategy = GenerationType.AUTO)
     private Long id;

     @ManyToOne(fetch = FetchType.LAZY)
     @JoinColumn(name = "details_id")
     private MainDetails details;

     // Other fields omitted (including timestamp)

}

I call a save() method on the MainDetails object. The method looks like this:

public T save(T obj) { // The T in this case is MainDetails
  entityManager.persist(obj);
  entityManager.flush();
  return obj;
}

But then I get this exception:

Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "details_pkey" Detail: Key (details_id)=(8) already exists.

My persistence.xml looks like this:

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
         version="2.0">
  <persistence-unit name="my-persistence-unit">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <!-- Annotated entity classes -->
    <class>com.company.entity.MainDetails</class>
    <class>com.company.entity.State</class>

    <properties>
      <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL82Dialect" />
      <property name="hibernate.hbm2ddl.auto" value="create-drop" />
      <property name="hibernate.enable_lazy_load_no_trans" value="true"/>
    </properties>
  </persistence-unit>
</persistence>

My spring context looks like this:

@EnableJpaRepositories(basePackages = {"com.company.dao", "com.company.*.dao"})
@EnableTransactionManagement(proxyTargetClass = true)
@Import(BasicConfig.class)
public class DbConfig {

  @Value("${db.connection_string}")
  private String connectionString;

  @Value("${db.user_name}")
  private String dbUserName;

  @Value("${db.password}")
  private String dbPassword;

  @Bean
  public DataSource dataSource() {
    DriverManagerDataSource driver = new DriverManagerDataSource();
    driver.setDriverClassName("org.postgresql.Driver");
    driver.setUrl(connectionString);
    driver.setUsername(dbUserName);
    driver.setPassword(dbPassword);
    return driver;
  }

  @Bean
  public JpaVendorAdapter jpaVendorAdapter() {
    HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
    adapter.setShowSql(true);
    adapter.setGenerateDdl(true);
    adapter.setDatabase(Database.POSTGRESQL);
    return adapter;
  }

  @Bean
  public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws ClassNotFoundException {
    LocalContainerEntityManagerFactoryBean factoryBean = new  LocalContainerEntityManagerFactoryBean();
    factoryBean.setDataSource(dataSource());
    factoryBean.setPersistenceUnitName("my-persistence-unit");
    factoryBean.setJpaVendorAdapter(jpaVendorAdapter());

    return factoryBean;
  }

  @Bean
  public JpaTransactionManager transactionManager() throws ClassNotFoundException {
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());

    return transactionManager;
  }
}

I have the following problem

@Entity
@Table(name="tb_pessoa", schema="public")
@Inheritance(strategy = InheritanceType.JOINED)
public class Pessoa implements Serializable {
   private static final long serialVersionUID = 1L;

   @Id
   @SequenceGenerator(name = "tb_pessoa_id_seq", sequenceName = "tb_pessoa_id_seq", schema="public")
   @GeneratedValue(strategy = GenerationType.AUTO, generator = "tb_pessoa_id_seq")
   @Column(name = "id", nullable = false)
   private Integer id;

   ...

@Entity  
@Table(name="tb_pessoafisica", schema="public")
@PessoaFisicaAnnotation
@PrimaryKeyJoinColumn(name = "id")
public class PessoaFisica extends Pessoa implements Serializable {
   private static final long serialVersionUID = 1L;

   @Column(name = "email")
   private String email;

   ...

Assuming the Pessoa table has records with id 1 to 500. When I run the code below:

PessoaFisica pessoaFisica = new PessoaFisica();
pessoaFisica.setEmail("teste@123.com");

...

em.persist(pessoa);

It’s happening the following error:

17:26:13,613 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http--10.36.1.49-8180-1) ERROR: duplicate key value violates unique constraint "tb_pessoa_pkey"
    Detalhe: Key (id)=(438) already exists.
17:26:13,614 WARN  [com.arjuna.ats.arjuna] (http--10.36.1.49-8180-1) ARJUNA012125: TwoPhaseCoordinator.beforeCompletion - failed for SynchronizationImple< 0:ffff7f000101:-7f6ae4e3:558080ed:4f, org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization@331af73a >: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: ERROR: duplicate key value violates unique constraint "tb_pessoa_pkey"
  Detalhe: Key (id)=(438) already exists.

why is trying to use the id 438 and not 501???

Does anyone know what might be happening?

thank you very much

CREATE TABLE tb_pessoa
(
    id integer NOT NULL,
    CONSTRAINT tb_pessoa_pkey PRIMARY KEY (id)
)

CREATE TABLE tb_pessoafisica
(
    email character varying(64) NOT NULL,
    CONSTRAINT tb_pessoafisica_pkey PRIMARY KEY (id),
    CONSTRAINT fkee8c050f70415778 FOREIGN KEY (id)
        REFERENCES tb_pessoa (id) MATCH SIMPLE
)

CREATE SEQUENCE tb_pessoa_id_seq
  INCREMENT 1
  MINVALUE 1
  MAXVALUE 9223372036854775807
  START 500
  CACHE 1;

Log Hibernate:

07:50:52,463 INFO  [stdout] (http--10.36.1.49-8180-2) Hibernate: 
07:50:52,463 INFO  [stdout] (http--10.36.1.49-8180-2)     select
07:50:52,464 INFO  [stdout] (http--10.36.1.49-8180-2)         nextval ('public.tb_pessoa_id_seq')
07:50:52,497 INFO  [stdout] (http--10.36.1.49-8180-2) Hibernate: 
07:50:52,498 INFO  [stdout] (http--10.36.1.49-8180-2)     insert 
07:50:52,499 INFO  [stdout] (http--10.36.1.49-8180-2)     into
07:50:52,499 INFO  [stdout] (http--10.36.1.49-8180-2)         public.tb_pessoa
07:50:52,500 INFO  [stdout] (http--10.36.1.49-8180-2)         (id) 
07:50:52,500 INFO  [stdout] (http--10.36.1.49-8180-2)     values
07:50:52,501 INFO  [stdout] (http--10.36.1.49-8180-2)         (?)
07:50:52,519 WARN  [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http--10.36.1.49-8180-2) SQL Error: 0, SQLState: 23505
07:50:52,521 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http--10.36.1.49-8180-2) ERROR: duplicate key value violates unique constraint "tb_pessoa_pkey"
    Detalhe: Key (id)=(438) already exists.

I have the following problem

@Entity
@Table(name="tb_pessoa", schema="public")
@Inheritance(strategy = InheritanceType.JOINED)
public class Pessoa implements Serializable {
   private static final long serialVersionUID = 1L;

   @Id
   @SequenceGenerator(name = "tb_pessoa_id_seq", sequenceName = "tb_pessoa_id_seq", schema="public")
   @GeneratedValue(strategy = GenerationType.AUTO, generator = "tb_pessoa_id_seq")
   @Column(name = "id", nullable = false)
   private Integer id;

   ...

@Entity  
@Table(name="tb_pessoafisica", schema="public")
@PessoaFisicaAnnotation
@PrimaryKeyJoinColumn(name = "id")
public class PessoaFisica extends Pessoa implements Serializable {
   private static final long serialVersionUID = 1L;

   @Column(name = "email")
   private String email;

   ...

Assuming the Pessoa table has records with id 1 to 500. When I run the code below:

PessoaFisica pessoaFisica = new PessoaFisica();
pessoaFisica.setEmail("teste@123.com");

...

em.persist(pessoa);

It’s happening the following error:

17:26:13,613 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http--10.36.1.49-8180-1) ERROR: duplicate key value violates unique constraint "tb_pessoa_pkey"
    Detalhe: Key (id)=(438) already exists.
17:26:13,614 WARN  [com.arjuna.ats.arjuna] (http--10.36.1.49-8180-1) ARJUNA012125: TwoPhaseCoordinator.beforeCompletion - failed for SynchronizationImple< 0:ffff7f000101:-7f6ae4e3:558080ed:4f, org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization@331af73a >: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: ERROR: duplicate key value violates unique constraint "tb_pessoa_pkey"
  Detalhe: Key (id)=(438) already exists.

why is trying to use the id 438 and not 501???

Does anyone know what might be happening?

thank you very much

CREATE TABLE tb_pessoa
(
    id integer NOT NULL,
    CONSTRAINT tb_pessoa_pkey PRIMARY KEY (id)
)

CREATE TABLE tb_pessoafisica
(
    email character varying(64) NOT NULL,
    CONSTRAINT tb_pessoafisica_pkey PRIMARY KEY (id),
    CONSTRAINT fkee8c050f70415778 FOREIGN KEY (id)
        REFERENCES tb_pessoa (id) MATCH SIMPLE
)

CREATE SEQUENCE tb_pessoa_id_seq
  INCREMENT 1
  MINVALUE 1
  MAXVALUE 9223372036854775807
  START 500
  CACHE 1;

Log Hibernate:

07:50:52,463 INFO  [stdout] (http--10.36.1.49-8180-2) Hibernate: 
07:50:52,463 INFO  [stdout] (http--10.36.1.49-8180-2)     select
07:50:52,464 INFO  [stdout] (http--10.36.1.49-8180-2)         nextval ('public.tb_pessoa_id_seq')
07:50:52,497 INFO  [stdout] (http--10.36.1.49-8180-2) Hibernate: 
07:50:52,498 INFO  [stdout] (http--10.36.1.49-8180-2)     insert 
07:50:52,499 INFO  [stdout] (http--10.36.1.49-8180-2)     into
07:50:52,499 INFO  [stdout] (http--10.36.1.49-8180-2)         public.tb_pessoa
07:50:52,500 INFO  [stdout] (http--10.36.1.49-8180-2)         (id) 
07:50:52,500 INFO  [stdout] (http--10.36.1.49-8180-2)     values
07:50:52,501 INFO  [stdout] (http--10.36.1.49-8180-2)         (?)
07:50:52,519 WARN  [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http--10.36.1.49-8180-2) SQL Error: 0, SQLState: 23505
07:50:52,521 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http--10.36.1.49-8180-2) ERROR: duplicate key value violates unique constraint "tb_pessoa_pkey"
    Detalhe: Key (id)=(438) already exists.

Есть таблица в БД PostgreSql. У этой таблицы есть ограничение на уникальность для id. Сохраняю сущности в БД посредством Hibernate.

Код Entity:

@Entity
@Table(name = "cinema_movie")
public class Cinema_Movie {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(name = "cinema_id")
    private String cinemaId;

    @Column(name = "movie_id")
    private String movieId;

Геттеры и сеттеры, плюс конструктор прилагаются. Не писал для сокращения кода.

Код сохранения в БД:

public void save() {
        CinemaMovie cinema_movie = new CinameMovie();
        cinema_movie.setCinemaId("random");
        cinema_movie.setMovieId("random")
        session = HibernateSessionFactoryUtil.getSessionFactory().openSession();
        session.save(cinema_movie); 
    }

Ну и в HibernateSessionFactoryUtil ничего особенного нет:

public static SessionFactory getSessionFactory() {
        logger.debug("Start method getSessionFactory() at HibernateSessionFactoryUtil.class");
        if (sessionFactory == null) {
            try {
                Configuration configuration = new Configuration().configure();
                configuration.addAnnotatedClass(Cinema_Movie.class);
                StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
                sessionFactory = configuration.buildSessionFactory(builder.build());

            } catch (Exception e) {
                logger.error("Error at method getSessionFactory() at HibernateSessionFactoryUtil.class: ", e);
            }
        }
        logger.debug("End of method getSessionFactory() at HibernateSessionFactoryUtil.class");
        return sessionFactory;
    }

И соответственно, метод save() вызывается переодически в разное время в программе. Изменения в БД в данную таблицу вносились руками, удалялись некоторые записи, т.к. программа только на стадии разработки.

Вопрос в следующем:

Как происходит генерация уникальных значений в Hibernate, и почему переодически я получаю ошибку:

ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - ОШИБКА: повторяющееся значение ключа нарушает ограничение уникальности

?

А так же, как избежать данной ошибки, т.е. чтобы Hibernate точно гененрировал уникальные ID, которых еще нет в БД? Только дополнительной проверкой? Или сделать другой primary key, который самому генерировать? Или же есть какая то возможность исключения такой ошибки с помощью инструментов Hibernate?

#java #postgresql #hibernate #spring-boot #jpa

#java #postgresql #впасть в спящий режим #пружинный ботинок #jpa

Вопрос:

Повторяющееся значение ключа нарушает ограничение уникальности после сохранения объекта @ManyToOne

Я попытался сохранить объект A, у которого есть другой объект B с уникальным именем поля с помощью spring-data. Если B уже существует в БД, то будет выдано исключение «дублирующее значение ключа нарушает уникальное ограничение «b_name_key». Подробно: Ключ (b_name)=(someName) уже существует.

 create table b
(
  b_id         serial primary key,
  b_name varchar(3) not null unique
);

create table a
(
  a_id            serial primary key,
  b_id      int references b (b_id) not null,
);


@Entity
@Getter
@Setter
public class B implements java.io.Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long b_id;
    @Column(name = "b_name", unique = true)
    private String bName;

    public B(String bName) {
        this.bName = bName;
    }

    public B() {}

    @Override
    public String toString() {
        return "...";
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        B b = (B) o;
        return Objects.equals(bName, b.bName);
    }

    @Override
    public int hashCode() {
        return Objects.hash(bName);
    }
}

@Entity
@Getter
@Setter
public class a implements java.io.Serializable{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long a_id;

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "b_id")
    private B b;


    public a() {
    }

    public a(B b  ) {
        this.b = b;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        a a = (a) o;
        return Objects.equals(b, a.b)
    }

    @Override
    public int hashCode() {
        return Objects.hash(b);
    }
}


@Repository
public interface ARepository extends JpaRepository<Metastasis, Long> {}

@Controller
public class AController {

    private final ARepository aRepository;

    public AController(ARepository aRepository) {
        this.aRepository = aRepository;
    }

    @GetMapping("/test")
    public String showaddUserForm() {
        B b = new B("SomeName");
        A a = new A(b);
        aRepository.save(a);
        return "index";
    }
}

@SpringBootApplication
@EnableJpaRepositories(basePackages = "...repositories")
@EnableTransactionManagement
@EntityScan(basePackages = "....entities")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
 

Я получаю org.postgresql.util.PSQLException: ОШИБКА: повторяющееся значение ключа нарушает уникальное ограничение «b_name_key»
Подробно: ключ (b_name) = (SomeName) уже существует.

Ответ №1:

Это нормально. Поскольку a объект является новым, операция сохранения будет каскадно передана b объекту, который также является новым, и завершится неудачей, поскольку в базе данных уже есть запись с этим ключом.

Попробуйте что-то вроде:

 // find for B
B b = bRepository.findById(..);
// if not found, create one
if (b == null) {
   b = new B("SomeName");
} 
A a = new A(b);
aRepository.save(a);
 

Комментарии:

1. Почему спящий режим не может справиться с этим сам?

Есть таблица в БД PostgreSql. У этой таблицы есть ограничение на уникальность для id. Сохраняю сущности в БД посредством Hibernate.

Код Entity:

@Entity
@Table(name = "cinema_movie")
public class Cinema_Movie {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(name = "cinema_id")
    private String cinemaId;

    @Column(name = "movie_id")
    private String movieId;

Геттеры и сеттеры, плюс конструктор прилагаются. Не писал для сокращения кода.

Код сохранения в БД:

public void save() {
        CinemaMovie cinema_movie = new CinameMovie();
        cinema_movie.setCinemaId("random");
        cinema_movie.setMovieId("random")
        session = HibernateSessionFactoryUtil.getSessionFactory().openSession();
        session.save(cinema_movie); 
    }

Ну и в HibernateSessionFactoryUtil ничего особенного нет:

public static SessionFactory getSessionFactory() {
        logger.debug("Start method getSessionFactory() at HibernateSessionFactoryUtil.class");
        if (sessionFactory == null) {
            try {
                Configuration configuration = new Configuration().configure();
                configuration.addAnnotatedClass(Cinema_Movie.class);
                StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
                sessionFactory = configuration.buildSessionFactory(builder.build());

            } catch (Exception e) {
                logger.error("Error at method getSessionFactory() at HibernateSessionFactoryUtil.class: ", e);
            }
        }
        logger.debug("End of method getSessionFactory() at HibernateSessionFactoryUtil.class");
        return sessionFactory;
    }

И соответственно, метод save() вызывается переодически в разное время в программе. Изменения в БД в данную таблицу вносились руками, удалялись некоторые записи, т.к. программа только на стадии разработки.

Вопрос в следующем:

Как происходит генерация уникальных значений в Hibernate, и почему переодически я получаю ошибку:

ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - ОШИБКА: повторяющееся значение ключа нарушает ограничение уникальности

?

А так же, как избежать данной ошибки, т.е. чтобы Hibernate точно гененрировал уникальные ID, которых еще нет в БД? Только дополнительной проверкой? Или сделать другой primary key, который самому генерировать? Или же есть какая то возможность исключения такой ошибки с помощью инструментов Hibernate?

Приложение на основе My Spring Data (JPA / Hibernate) при увеличении нагрузки при сохранении новых сущностей в Postgres вызывает следующее исключение: org.postgresql.util.PSQLException: ОШИБКА: повторяющееся значение ключа нарушает уникальное ограничение «hibernate_sequences_pkey»

Стратегия для id определяется следующим образом:

@Id
@GeneratedValue(strategy = GenerationType.TABLE)
@Column(name = "ID")
public Long getId() {
    return id;
}

Я знаю, что эта стратегия не является идеальным решением для Postgres, но является ли это причиной исключения выше?

Нагрузка создается с использованием маршрута Apache Camel с разделителем, выполняющим вставки параллельно в нескольких потоках.

2 ответа

Лучший ответ

После некоторых тестов действительно кажется, что проблема вызвана strategy = GenerationType.TABLE. После изменения на strategy = GenerationType.SEQUENCE проблемы, описанные выше с дублированием ключей, исчезли.

@Id
@SequenceGenerator(name = Consts.VEHICLE_ATTR_ID_SEQ,
        sequenceName = Consts.VEHICLE_ATTR_ID_SEQ,
        allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE,
        generator = Consts.VEHICLE_ATTR_ID_SEQ)
@Column(name = "ID", updatable = false)
public Long getId() {
    return id;
} 


4

Adam Boczek
7 Дек 2017 в 08:30

При переходе с Hibernate 4 на 5.3.1 (Wildfly 14.0.1) я также столкнулся с проблемой, связанной с сообщением об ошибке «повторяющееся значение ключа нарушает уникальное ограничение» hibernate_sequences_pkey. После исследования исходного кода Hibernate 5.3.1 я смог избавиться ошибки с помощью strategy = GenerationType.TABLE (я также знаю, что эта стратегия не является идеальным решением). Основная проблема была в классе TableGenerator. Для решения проблемы вы должны дополнительно использовать аннотацию GenericGenerator, например:

@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = TableGenerator.DEF_TABLE)
@GenericGenerator(name = TableGenerator.DEF_TABLE, strategy
        = "org.hibernate.id.enhanced.TableGenerator", parameters = {
        @Parameter(name = TableGenerator.CONFIG_PREFER_SEGMENT_PER_ENTITY, value = "true")})
@Column(name="id")
private Integer id;

Установка для параметра TableGenerator.CONFIG_PREFER_SEGMENT_PER_ENTITY истинного значения (поскольку по умолчанию он имеет ложное значение, и в этом случае Hibernate будет использовать имя сегмента «по умолчанию» в таблице hibernate_sequences вместо имен таблиц).Вы также должны установить для свойства hibernate.model.generator_name_as_sequence_name значение false, чтобы иметь только одну таблицу hibernate_sequences, иначе Hibernate будет использовать имена генераторов в качестве имен для таблиц последовательностей (согласно https://github.com/hibernate/hibernate-orm/commit/9a75fa8d979185b6014a814bf3ffd09e32143939#diff-936141a440957cd8a9c4a93a744e92a0 меняется). Дополнительно (но не обязательно) вы также можете установить для свойства hibernate.id.generator.stored_last_used значение false (https://github.com/hibernate/hibernate-orm/commit/9af565510064635dba7e48087ab4e8f5ef439f0d, потому что:

Чтобы соответствовать спецификациям JPA, значение, хранимое Hibernate 5.3 в таблице, используемой javax.persistence.TableGenerator — последнее сгенерированное значение. В предыдущих версиях Hibernate вместо этого сохранялось следующее значение. используемый.

Для обратной совместимости новый параметр, hibernate.id.generator.stored_last_used, было введено, что дает возможность вернуться к прежнему режиму гибернации. Существующие приложения, переходящие на версию 5.3 и использующие @TableGenerator, имеют установить hibernate.id.generator.stored_last_used на false


0

Dmitrii
14 Апр 2020 в 10:43

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

А вот еще интересные материалы:

  • Яшка сломя голову остановился исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного где ошибка
  • Hi press ошибка кариер перевод
  • Hi press ошибка кариер не заводится