Hibernate: "поле ' id' не имеет значения по умолчанию"
я столкнулся с тем, что я думаю, это простая проблема с Hibernate, но не могу ее решить (форумы Hibernate, которые недоступны, конечно, не помогают).
у меня есть простой класс, который я хотел бы сохранить, но продолжаю получать:
SEVERE: Field 'id' doesn't have a default value
Exception in thread "main" org.hibernate.exception.GenericJDBCException: could not insert: [hibtest.model.Mensagem]
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
[ a bunch more ]
Caused by: java.sql.SQLException: Field 'id' doesn't have a default value
[ a bunch more ]
соответствующий код для сохраненного класса:
package hibtest.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Mensagem {
protected Long id;
protected Mensagem() { }
@Id
@GeneratedValue
public Long getId() {
return id;
}
public Mensagem setId(Long id) {
this.id = id;
return this;
}
}
и фактический запущенный код просто:
SessionFactory factory = new AnnotationConfiguration()
.configure()
.buildSessionFactory();
{
Session session = factory.openSession();
Transaction tx = session.beginTransaction();
Mensagem msg = new Mensagem("YARR!");
session.save(msg);
tx.commit();
session.close();
}
я попробовал некоторые "стратегии" в пределах GeneratedValue
аннотация, но это просто не работает. Инициализация id
не помогло! (например,Long id = 20L
).
может ли кто-нибудь пролить свет?
EDIT 2: подтверждается: баловаться с@GeneratedValue(strategy = GenerationType.XXX)
не решает ее
решила: воссоздание базы данных решило проблему
17 ответов:
иногда изменения, внесенные в модель или в ORM, могут не отражать точно в базе данных даже после выполнения
SchemaUpdate
.Если ошибка на самом деле не имеет разумного объяснения, попробуйте воссоздать базу данных (или, по крайней мере, создать новую) и построить ее с помощью
SchemaExport
.
Если вы хотите, чтобы MySQL автоматически создавал первичные ключи, вы должны сообщить об этом при создании таблицы. Вы не должны делать это в Oracle.
на первичном ключе вы должны включить
AUTO_INCREMENT
. См. пример ниже.CREATE TABLE `supplier` ( `ID` int(11) NOT NULL **AUTO_INCREMENT**, `FIRSTNAME` varchar(60) NOT NULL, `SECONDNAME` varchar(100) NOT NULL, `PROPERTYNUM` varchar(50) DEFAULT NULL, `STREETNAME` varchar(50) DEFAULT NULL, `CITY` varchar(50) DEFAULT NULL, `COUNTY` varchar(50) DEFAULT NULL, `COUNTRY` varchar(50) DEFAULT NULL, `POSTCODE` varchar(50) DEFAULT NULL, `HomePHONENUM` bigint(20) DEFAULT NULL, `WorkPHONENUM` bigint(20) DEFAULT NULL, `MobilePHONENUM` bigint(20) DEFAULT NULL, `EMAIL` varchar(100) DEFAULT NULL, PRIMARY KEY (`ID`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
вот сущность
package com.keyes.jpa; import java.io.Serializable; import javax.persistence.*; import java.math.BigInteger; /** * The persistent class for the parkingsupplier database table. * */ @Entity @Table(name = "supplier") public class supplier implements Serializable { private static final long serialVersionUID = 1L; @Id **@GeneratedValue(strategy = GenerationType.IDENTITY)** @Column(name = "ID") private long id; @Column(name = "CITY") private String city; @Column(name = "COUNTRY") private String country; @Column(name = "COUNTY") private String county; @Column(name = "EMAIL") private String email; @Column(name = "FIRSTNAME") private String firstname; @Column(name = "HomePHONENUM") private BigInteger homePHONENUM; @Column(name = "MobilePHONENUM") private BigInteger mobilePHONENUM; @Column(name = "POSTCODE") private String postcode; @Column(name = "PROPERTYNUM") private String propertynum; @Column(name = "SECONDNAME") private String secondname; @Column(name = "STREETNAME") private String streetname; @Column(name = "WorkPHONENUM") private BigInteger workPHONENUM; public supplier() { } public long getId() { return this.id; } public void setId(long id) { this.id = id; } public String getCity() { return this.city; } public void setCity(String city) { this.city = city; } public String getCountry() { return this.country; } public void setCountry(String country) { this.country = country; } public String getCounty() { return this.county; } public void setCounty(String county) { this.county = county; } public String getEmail() { return this.email; } public void setEmail(String email) { this.email = email; } public String getFirstname() { return this.firstname; } public void setFirstname(String firstname) { this.firstname = firstname; } public BigInteger getHomePHONENUM() { return this.homePHONENUM; } public void setHomePHONENUM(BigInteger homePHONENUM) { this.homePHONENUM = homePHONENUM; } public BigInteger getMobilePHONENUM() { return this.mobilePHONENUM; } public void setMobilePHONENUM(BigInteger mobilePHONENUM) { this.mobilePHONENUM = mobilePHONENUM; } public String getPostcode() { return this.postcode; } public void setPostcode(String postcode) { this.postcode = postcode; } public String getPropertynum() { return this.propertynum; } public void setPropertynum(String propertynum) { this.propertynum = propertynum; } public String getSecondname() { return this.secondname; } public void setSecondname(String secondname) { this.secondname = secondname; } public String getStreetname() { return this.streetname; } public void setStreetname(String streetname) { this.streetname = streetname; } public BigInteger getWorkPHONENUM() { return this.workPHONENUM; } public void setWorkPHONENUM(BigInteger workPHONENUM) { this.workPHONENUM = workPHONENUM; } }
вы должны использовать обновление в свойстве hbm2ddl. внесите изменения и обновите его для создания, чтобы он мог создать таблицу.
<property name="hbm2ddl.auto">create</property>
это сработало для меня.
другое предложение, чтобы проверить, что вы используете допустимый тип Для автоматически сгенерированного поля. Помните, что он не работает со строкой, но он работает с Long:
@Id @GeneratedValue(strategy=GenerationType.AUTO) public Long id; @Constraints.Required public String contents;
приведенный выше синтаксис работал для генерации таблиц в MySQL, используя Hibernate в качестве поставщика JPA 2.0.
у меня была та же проблема. Я нашел учебник спящий режим один к одному Пример отображения с помощью аннотации внешнего ключа и следовал за ним шаг за шагом, как показано ниже:
создать таблицы базы данных с помощью этого скрипта:
create table ADDRESS ( id INT(11) NOT NULL AUTO_INCREMENT, street VARCHAR(250) NOT NULL, city VARCHAR(100) NOT NULL, country VARCHAR(100) NOT NULL, PRIMARY KEY (id) ); create table STUDENT ( id INT(11) NOT NULL AUTO_INCREMENT, name VARCHAR(100) NOT NULL, entering_date DATE NOT NULL, nationality TEXT NOT NULL, code VARCHAR(30) NOT NULL, address_id INT(11) NOT NULL, PRIMARY KEY (id), CONSTRAINT student_address FOREIGN KEY (address_id) REFERENCES ADDRESS (id) );
вот сущности с приведенными выше таблицами
@Entity @Table(name = "STUDENT") public class Student implements Serializable { private static final long serialVersionUID = 6832006422622219737L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; } @Entity @Table(name = "ADDRESS") public class Address { @Id @GeneratedValue @Column(name = "ID") private long id; }
проблема была решена.
обратите внимание: первичный ключ должен быть установлен в AUTO_INCREMENT
просто добавьте не-нулевое ограничение
У меня была та же проблема. Я просто добавил не-нулевое ограничение в xml-сопоставлении. Он работал
<set name="phone" cascade="all" lazy="false" > <key column="id" not-null="true" /> <one-to-many class="com.practice.phone"/> </set>
удаление таблицы из базы данных вручную, а затем повторный запуск приложения работал для меня. В моем случае таблица не была создана должным образом (с ограничениями), я думаю.
пожалуйста, проверьте, является ли значение по умолчанию для идентификатора столбца в конкретной таблице.если не сделать это по умолчанию
У меня была та же проблема. Я использовал объединенную таблицу и все, что у меня было с полем идентификатора строки и двумя внешними ключами. Я не знаю точную причину, но я сделал следующее
- обновлен MySQL до community 5.5.13
- переименовать класс и таблица
убедитесь, что у меня был хэш-код и равные методы
@Entity @Table(name = "USERGROUP") public class UserGroupBean implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy=GenerationType.AUTO) @Column(name = "USERGROUP_ID") private Long usergroup_id; @Column(name = "USER_ID") private Long user_id; @Column(name = "GROUP_ID") private Long group_id;
то же самое исключение было вызвано, если таблица БД имела старый неизмененный столбец.
например:
attribute_id NOT NULL BIGINT(20),
иattributeId NOT NULL BIGINT(20),
после удаления не используется атрибут, в моем случае contractId, проблема была решена.
У меня была эта проблема, по ошибке у меня есть место
@Transient
аннотация над этим конкретным атрибутом. В моем случае эта ошибка имеет смысла.
Это случилось со мной с
@ManyToMany
отношения. Я аннотировал одно из полей в отношениях с@JoinTable
, Я удалил это и использовалmappedBy
атрибут на @ManyToMany вместо этого.
В дополнение к тому, что сказано выше, Не забудьте при создании таблицы SQL, чтобы сделать АВТОМАТИЧЕСКОЕ УВЕЛИЧЕНИЕ как в этом примере
CREATE TABLE MY_SQL_TABLE ( USER_ID INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, FNAME VARCHAR(50) NOT NULL, LNAME VARCHAR(20) NOT NULL, EMAIL VARCHAR(50) NOT NULL );