Как предоставить начальное значение или увеличить идентификатор с JPA GenerationType.AUTO - PullRequest
0 голосов
/ 04 апреля 2019

Я использую следующий код для определения MyEntity,

@Entity
@Table(name = "MY_TABLE")
public class MyEntity {

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name = "MY_TABLE_ID")
private Integer myTableId;

@Column(name = "MY_TABLE_NM")
private String myTableName;

//Getters Setters
}

Для первых POST после запуска моего приложения я создаю MyEntity все работает нормально, MY_TABLE_ID начинается с 1 иработает как положено.

Моя проблема в том, что если кто-то вставляет данные вручную, прежде чем я сделаю POST, тогда я получаю исключение дубликата ключа , так как myTableId вводится как 1, который уже присутствует.

Моя главная проблема в том, что я не могу создать database sequence для использования GenerationType.SEQUENCE сейчас, чтобы решить эту проблему, поскольку база данных не может быть изменена сейчас.Я пробовал различные комбинации GenerationType, TableGenerator, но я не могу успешно справиться с этим.

Установка initialValue на большее число, чтобы избежать дублирования значений, может временно решить мою проблему, но я не могусделайте это тоже.

Если кто-то может помочь мне с initialValue с AUTO или дать мне какое-нибудь другое лучшее решение без изменений базы данных, это будет здорово :) 10 *

Ответы [ 4 ]

1 голос
/ 04 апреля 2019

Вы также можете реализовать свой собственный генератор, если вам нужно больше контроля.Смотрите этот интерфейс IdentifierGenerator .Таким образом, вы можете получить количество записей, например, через @ NamedQuery .Затем вы можете сгенерировать идентификатор самостоятельно.

public class MyEntityKeyGenerator implements IdentifierGenerator {
@Override
public Serializable generate(SessionImplementor session, Object object) {
    // SELECT count(ent) from MyEntity ent;
    Long count = (Long) session.getNamedQuery("count-query").uniqueResult();
    // calc and return id value
   }
}

Сущность:

class MyEntity {
@Id
@GenericGenerator(name = "my_generator",
        strategy = "org.common.MyEntityKeyGenerator")
@GeneratedValue(generator = "my_generator")
private Long id;...

Только не забывайте про замок.

1 голос
/ 05 апреля 2019

Поскольку MY_TABLE_ID - столбец идентификаторов, будут работать следующие аннотации.

@Entity
@Table(name = "MY_TABLE")
public class MyEntity {

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY) <-- IDENTITYinstead of AUTO
@Column(name = "MY_TABLE_ID")
private Integer myTableId;

@Column(name = "MY_TABLE_NM")
private String myTableName;

//Getters Setters
}

Столбец идентификации автоматически назначит значение, как только транзакция будет совершена. Вы не должны устанавливать какие-либо значения для столбца идентификаторов, так как это задание базы данных для назначения значений. Поэтому вам также не нужно думать о каких-либо начальных значениях (полностью забудьте их для столбцов идентификаторов)

0 голосов
/ 08 апреля 2019

Я пробовал различные варианты ответов, представленных здесь, и для похожих вопросов на stackoverflow и других форумах,

У меня было несколько ограничений,

  1. Не удалось создать последовательность базы данных, поскольку изменения в моей базе данных были заморожены.
  2. Я не хотел вводить новый Custom класс IdGenerator, потому что это могло бы привести в замешательство других людей, работающих со мной.

Это было решено с помощью следующего изменения:

Добавление GenericGenerator со стратегией increment помогло мне, я внес следующие изменения в свой код.

@Entity
@Table(name = "MY_TABLE")
public class MyEntity {

@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator="seq")
@GenericGenerator(name = "seq", strategy="increment")
@Column(name = "MY_TABLE_ID")
private Integer myTableId;

@Column(name = "MY_TABLE_NM")
private String myTableName;

//Getters Setters
}

Это помогло мне, потому что, От Документы Hiberbate

прибавка

IdentifierGenerator, который возвращает long, построенный путем подсчета от максимального значения первичного ключа при запуске. Не безопасно для использования в Кластер!

Поскольку он увеличивал уже существующий myTableId, даже если он был вставлен вручную , это решило мою проблему.

0 голосов
/ 04 апреля 2019

Я использую тип идентификации Identity, что в основном означает, что db заботится о генерации Id.

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@MappedSuperclass
@EntityListeners(EntityListener.class)
@EqualsAndHashCode(of = {"id", "createdAt"})
public abstract  class AbstractEntity<ID extends Serializable> implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private ID id;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "CREATED_AT", updatable = false)
    private Date createdAt;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "UPDATED_AT")
    private Date updatedAt;

}

Вы также можете использовать, Генерация последовательности:

@Entity
@SequenceGenerator(name="seq", initialValue=1, allocationSize=100)
public class EntityWithSequenceId {
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="seq")
    @Id long id;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...