Подтвердить что ты не робот

Как аннотировать поле автоинкремента MYSQL с аннотациями JPA

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

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

@Entity
public class Operator{

   @Id
   @GeneratedValue
   private Long id;

   private String username;

   private String password;


   private Integer active;

   //Getters and setters...
}

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

Вот несколько журналов:

Hibernate: insert into Operator (active, password, username, id) values (?, ?, ?, ?)
[email protected]: insert into Operator (active,password, username, id) values (0, 'pass', 'user', ** NOT SPECIFIED **)

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

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

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

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`)
)
4b9b3361

Ответ 1

Чтобы использовать столбец 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 insert, и это не так. Там должно быть какое-то несоответствие.

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

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

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

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

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

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

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

Ответ 2

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

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

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

Ответ 3

Для тех, кто читает это, кто использует 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), CRITICAL устанавливает атрибут 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 с помощью мастеров для создания Entities из DB, контроллеров от Entities и JSF от Entities, а мастера (очевидно) не знают, как обращаться с идентификатором на основе последовательности столбцы, поэтому вам придется вручную добавлять эти аннотации.

Ответ 4

Пожалуйста, убедитесь, что тип данных id длинный, а не 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))

Ответ 5

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

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

Ответ 6

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

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

Ответ 7

Поскольку вы определяете идентификатор в типе 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...
}

Ответ 8

Если вы используете 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")