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: подтверждено: messing с @GeneratedValue(strategy = GenerationType.XXX)
не решает его
РЕШЕННО: воссоздание базы данных решило проблему
Ответы
Ответ 1
Иногда изменения, внесенные в модель или в ORM, могут не точно отразиться на базе данных даже после выполнения SchemaUpdate
.
Если на самом деле у ошибки нет разумного объяснения, попробуйте воссоздать базу данных (или, по крайней мере, создать новую), и подделать ее с помощью SchemaExport
.
Ответ 2
Если вы хотите, чтобы 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;
Здесь Entity
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;
}
}
Ответ 3
вы должны использовать обновление в свойстве hbm2ddl. внесите изменения и обновите их в Create, чтобы создать таблицу.
<property name="hbm2ddl.auto">create</property>
Это сработало для меня.
Ответ 4
Взгляните на стратегию GeneratedValue
. Обычно это выглядит примерно так:
@GeneratedValue(strategy=GenerationType.IDENTITY)
Ответ 5
Еще одно предложение - проверить, что вы используете допустимый тип для автоматически генерируемого поля. Помните, что он не работает со строкой, но работает с Long:
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Long id;
@Constraints.Required
public String contents;
Вышеупомянутый синтаксис работал для генерации таблиц в MySQL с использованием Hibernate в качестве поставщика JPA 2.0.
Ответ 6
У меня была та же проблема. Я нашел учебное пособие Пример сопоставления однопользовательской гибернации с использованием внешнего ключа Аннотации и последовал за ним шаг за шагом, как показано ниже:
Создайте таблицу базы данных с помощью этого script:
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
Ответ 7
Я пришел сюда из-за сообщения об ошибке, оказалось, что у меня две таблицы с тем же именем.
Ответ 8
Просто добавьте ограничение не-null
У меня была та же проблема. Я просто добавил ограничение null-null в xml-сопоставлении. Работал
<set name="phone" cascade="all" lazy="false" >
<key column="id" not-null="true" />
<one-to-many class="com.practice.phone"/>
</set>
Ответ 9
Удаление таблицы из базы данных вручную, а затем повторное выполнение приложения сработало для меня. Думаю, в моем случае таблица не была создана должным образом (с ограничениями).
Ответ 10
У меня была эта проблема. Моя ошибка заключалась в том, что я установил для вставляемых и обновляемых файлов значение false и пытался установить поле в запросе. Это поле установлено как NON NULL в БД.
@ManyToOne
@JoinColumn(name="roles_id", referencedColumnName = "id", insertable = false, updatable = false, nullable=false)
@JsonBackReference
private Role role;
Позже я изменил его на - вставляемый = true, обновляемый = true
@ManyToOne
@JoinColumn(name="roles_id", referencedColumnName = "id", insertable = true, updatable = true, nullable=false)
@JsonBackReference
//@JsonIgnore
private Role role;
Это сработало идеально позже.
Ответ 11
В дополнение к тому, что упоминалось выше, не забывайте при создании таблицы sql, чтобы сделать AUTO INCREMENT, как в этом примере
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
);
Ответ 12
Может быть, это проблема со схемой таблицы. бросьте стол и снова запустите приложение.
Ответ 13
Пожалуйста, проверьте, действительно ли значение по умолчанию для идентификатора столбца в таблице table.if не делает его по умолчанию
Ответ 14
У меня была та же проблема. Я использовал таблицу соединений и все, что у меня было с полем id строки и двумя внешними ключами. Я не знаю точно вызванного, но я сделал следующее
- Обновление MySQL до сообщества 5.5.13
- Переименуйте класс и таблицу
-
Убедитесь, что у меня есть методы hashcode и equals
@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;
Ответ 15
Такое же исключение было выбрано, если таблица БД имела старый неуправляемый столбец.
Например:
attribute_id NOT NULL BIGINT(20),
и attributeId NOT NULL BIGINT(20),
После удаления не использованного атрибута в моем случае contractId проблема была решена.
Ответ 16
У меня была эта проблема, по ошибке я поместил аннотацию @Transient
над этим конкретным атрибутом. В моем случае эта ошибка имеет смысл.
Ответ 17
Это случилось со мной с отношением @ManyToMany
. Я аннотировал одно из полей в отношении с @JoinTable
, я удалил это и использовал вместо этого атрибут mappedBy
в @ManyToMany.
Ответ 18
Я пробовал код, и в моем случае приведенный ниже код решает проблему. Я не правильно установил схему
@Entity
@Table(name="table"
,catalog="databasename"
)
Попробуйте добавить ,catalog="databasename"
же, как и я.
,catalog="databasename"
Ответ 19
В моем случае я изменил эти нарушающие таблицы и поле "id", о котором идет речь, я сделал это AUTO_INCREMENT, мне все равно нужно выяснить, почему во время развертывания он не делал его "AUTO_INCREMENT", так что я должен сделать это сам!
Ответ 20
Как насчет этого:
<set name="fieldName" cascade="all">
<key column="id" not-null="true" />
<one-to-many class="com.yourClass"/>
</set>
Надеюсь, это поможет вам.
Ответ 21
Попробуйте изменить тип объекта Long
тип long
примитива (если вам подходит использование примитивов).
У меня была та же проблема, и смена типа помогла мне.
Ответ 22
"Поле 'id' не имеет значения по умолчанию", потому что вы не объявили GenerationType.IDENTITY
в GeneratedValue
Annotation.
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
Ответ 23
Эта проблема связана с тем, что иногда вам необходимо снова обновить/создать базу данных, а иногда, если вы добавили поле в таблицу db, но не в класс сущностей, тогда он не может вставить нулевое значение или ноль, поэтому возникла эта ошибка.
Так что проверьте обе стороны. DB и класс сущности.
Ответ 24
Добавьте метод hashCode()
в свой объект Bean Класс и повторите попытку