Можно ли иметь автоинкрементный номер без идентификации? - PullRequest
1 голос
/ 13 февраля 2020

Я продолжаю гуглить и нахожу, что единственный способ - использовать

@Id
@GeneratedValue(strategy = GenerationType.Identity)

Но у меня уже есть первичный ключ, мне просто нужно другое поле, которое автоматически увеличивается. Кодировать вручную очень сложно.

Ответы [ 2 ]

0 голосов
/ 14 февраля 2020

Я вижу следующие опции:

1) Вы можете использовать аннотацию @ Generated .

Таблица должна быть объявлена ​​следующим образом:

create sequence TST_DATA_SEQ increment by 1 start with 1;

create table TST_DATA (
   ...
   dat_auto integer default nextval('TST_DATA_SEQ'),
   ...
);

и соответствующий столбец в сущности:

   @Generated(value = GenerationTime.INSERT)
   @Column(name = "dat_auto", insertable = false, updatable = false)
   private Long auto;

Обратите внимание, что в соответствии с документацией :

Свойства, отмеченные как сгенерированные, должны дополнительно быть не вставляемым и не обновляемым.

Итак, hibernate сделает дополнительный запрос для заполнения поля auto после сброса.

   Data data = new Data();
   // filling fields except data.auto
   session.persist(data);
   session.flush();
insert into TST_DATA (dat_name, dat_id) 
values (?, ?)

Hibernate: /* get generated state com.example.hibernate.Data */
  select data_.dat_auto as dat_auto_0_ 
  from TST_DATA data_ 
  where data_.dat_id=?

2) Вы можно использовать аннотацию @ GeneratorType .

У вас должна быть реализация hibernate ValueGenerator. Простой пример, который вы можете увидеть ниже.

import java.math.BigInteger;
import org.hibernate.Session;
import org.hibernate.tuple.ValueGenerator;

public class MyGenerator implements ValueGenerator<Long> 
{
   public Long generateValue(Session session, Object owner)
   {
      return (
         (BigInteger) session
            .createNativeQuery("select nextval('TST_DATA_SEQ')")
            .getSingleResult()
         ).longValue();
   }
}

И затем вы можете использовать его следующим образом:

   @GeneratorType(type = MyGenerator.class, when = GenerationTime.INSERT)
   @Column(name = "dat_auto")
   private Long auto;

В этом случае вы не должны предоставлять значение по умолчанию для объявления столбца как был необходим в n1. и соответствующее поле сущности не должно иметь @Column(... insertable = false, updatable = false). Каждый раз, когда эта сущность будет сохранена, hibernate генерирует запрос:

select nextval('TST_DATA_SEQ')

и заполняет это значение в поле auto.

0 голосов
/ 13 февраля 2020

Возможно, вы можете попробовать:

@GeneratedValue(GenerationType.strategy=SEQUENCE, generator="internal_seq")
@SequenceGenerator(name="internal_seq", sequenceName="internal_seq", allocationSize=1)
@Column(name="internalID")
public Long internalID;
...