Как аннотировать поле автоинкремента MYSQL с помощью JPA-аннотаций - PullRequest
94 голосов
/ 05 ноября 2010

Непосредственно, проблема заключается в сохранении Оператора объекта в БД MySQL. Перед сохранением я пытаюсь выбрать из этой таблицы, и она работает, так что подключение к БД.

Вот мой объект Operator:

@Entity
public class Operator{

   @Id
   @GeneratedValue
   private Long id;

   private String username;

   private String password;


   private Integer active;

   //Getters and setters...
}

Для сохранения я использую метод JPA EntityManager persist.

Вот какой-то журнал:

Hibernate: insert into Operator (active, password, username, id) values (?, ?, ?, ?)
com.mysql.jdbc.JDBC4PreparedStatement@15724a0: insert into Operator (active,password, username, id) values (0, 'pass', 'user', ** NOT SPECIFIED **)

На мой взгляд, проблема в конфигурации с автоматическим приращением, но я не могу понять, где.

Пробовал некоторые трюки, которые я видел здесь: Hibernate не учитывает поле первичного ключа автоинкремента MySQL Но ничего из этого не сработало

Если понадобятся другие файлы конфигурации, я предоставлю их.

DDL:

CREATE TABLE `operator` ( 
`id` INT(10) NOT NULL AUTO_INCREMENT,
`first_name` VARCHAR(40) NOT NULL,
`last_name` VARCHAR(40) NOT NULL,
`username` VARCHAR(50) NOT NULL,
`password` VARCHAR(50) NOT NULL,
`active` INT(1) NOT NULL,
PRIMARY KEY (`id`)
)

Ответы [ 8 ]

127 голосов
/ 05 ноября 2010

Чтобы использовать столбец MySQL AUTO_INCREMENT, вы должны использовать стратегию IDENTITY:

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

Что вы получите при использовании AUTO с MySQL:

@Id @GeneratedValue(strategy=GenerationType.AUTO)
private Long id;

Что на самом деле эквивалентно

@Id @GeneratedValue
private Long id;

Другими словами, ваше отображение должно работать.Но Hibernate должен опустить столбец id в операторе вставки SQL, а это не так.Где-то должно быть какое-то несоответствие.

Вы указали диалект MySQL в своей конфигурации Hibernate (вероятно, MySQL5InnoDBDialect или MySQL5Dialect в зависимости от используемого вами движка)?

Кроме того, кто создал таблицу?Можете ли вы показать соответствующий DDL?

Продолжение: Я не могу воспроизвести вашу проблему.Используя код вашего объекта и вашего DDL, Hibernate генерирует следующий (ожидаемый) SQL с MySQL:

insert 
into
    Operator
    (active, password, username) 
values
    (?, ?, ?)

Обратите внимание, что столбец idотсутствует в приведенном выше заявлении, как и ожидалось.

Подводя итог, ваш код, определение таблицы и диалект являются правильными и связными, он должен работать.Если это не для вас, возможно, что-то не синхронизировано (выполните чистую сборку, дважды проверьте каталог сборки и т. Д.) Или что-то еще просто не так (проверьте журналы на наличие каких-либо подозрительных).

Относительнодиалект, разница only между MySQL5Dialect или MySQL5InnoDBDialect заключается в том, что последний добавляет ENGINE=InnoDB к объектам таблицы при генерации DDL.Использование одного или другого не меняет сгенерированный SQL.

30 голосов
/ 13 апреля 2016

Используя MySQL, у меня работал только этот подход:

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

Другие 2 подхода, изложенные Паскалем в его ответе, не сработали для меня.

12 голосов
/ 04 мая 2012

Для тех, кто читает это и использует EclipseLink для JPA 2.0, вот две аннотации, которые мне пришлось использовать для получения JPA для сохранения данных, где «MySequenceGenerator» - это любое имя, которое вы хотите дать генератору, «myschema» - это имя схемы в вашей базе данных, которая содержит объект последовательности, а «mysequence» - это имя объекта последовательности в базе данных.

@GeneratedValue(strategy= GenerationType.SEQUENCE, generator="MySequenceGenerator")
@SequenceGenerator(allocationSize=1, schema="myschema",  name="MySequenceGenerator", sequenceName = "mysequence")

Для тех, кто использует EclipseLink (и, возможно, другие провайдеры JPA), КРИТИЧЕСКИ устанавливайте атрибут allocSize, чтобы он соответствовал значению INCREMENT, определенному для вашей последовательности в базе данных. Если вы этого не сделаете, вы получите общий сбой персистентности и потратить много времени, пытаясь выследить его, как я. Вот справочная страница, которая помогла мне преодолеть эту проблему:

http://wiki.eclipse.org/EclipseLink/Examples/JPA/PrimaryKey#Using_Sequence_Objects

Также, чтобы дать контекст, вот что мы используем:

Java 7 Glassfish 3.1 PostgreSQL 9.1 PrimeFaces 3.2 / JSF 2.1

Кроме того, ради лени, я построил это в Netbeans с мастерами для генерации сущностей из БД, контроллеров из сущностей и JSF из сущностей, а мастера (очевидно) не знают, как обращаться с ID на основе последовательности столбцы, поэтому вам придется вручную добавлять эти аннотации.

5 голосов
/ 15 ноября 2017

Пожалуйста, убедитесь, что id типа данных Long вместо String, если это будет строка, тогда аннотация @GeneratedValue не будет работать и создание sql для

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

create table VMS_AUDIT_RECORDS (id **varchar(255)** not null auto_increment primary key (id))

это должно быть

create table VMS_AUDIT_RECORDS (id **bigint** not null auto_increment primary key (id))
1 голос
/ 28 марта 2019

Если вы используете Mysql с Hibernate v3, то можно использовать GenerationType.AUTO, потому что внутри он будет использовать GenerationType.IDENTITY, что является наиболее оптимальным для MySQL.

Однако в Hibernate v5 он изменился,GenerationType.AUTO будет использовать GenerationType.TABLE, который генерирует много запросов для вставки.

Вы можете избежать этого, используя GenerationType.IDENTITY (если MySQL является единственной базой данных, которую вы используете) или с этими обозначениями (если у вас естьнесколько баз данных):

@GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
@GenericGenerator(name = "native", strategy = "native")
0 голосов
/ 17 января 2019

Поскольку вы определяете id в типе int при создании базы данных, вы должны использовать тот же тип данных и в классе модели. И так как вы определили идентификатор для автоматического приращения в базе данных, вы должны упомянуть его в классе модели, передав значение GenerationType.AUTO в атрибут 'стратегии' в аннотации @GeneratedValue. Тогда код становится таким, как показано ниже.

@Entity
public class Operator{

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private int id;

  private String username;

  private String password;

  private Integer active;

  //Getters and setters...
}
0 голосов
/ 12 сентября 2018

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

identity поддерживает столбцы идентификаторов в DB2, MySQL, MS SQL Server, Sybase и HypersonicSQL.Возвращаемый идентификатор имеет тип long, short или int.

Дополнительная информация: http://docs.jboss.org/hibernate/orm/3.5/reference/en/html/mapping.html#mapping-declaration-id

0 голосов
/ 17 марта 2018

Я перепробовал все, но все еще не смог этого сделать, я использую mysql, jpa с hibernate, я решил свою проблему, присвоив значение id 0 в конструкторе. Ниже приведен код объявления моего идентификатора

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