Спящий режим:«Поле 'id' не имеет значения по умолчанию»
-
03-07-2019 - |
Вопрос
Я столкнулся с, как мне кажется, простой проблемой с 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
).
Может ли кто-нибудь пролить свет?
РЕДАКТИРОВАТЬ 2: подтвержденный:возиться с@GeneratedValue(strategy = GenerationType.XXX)
не решает это
РЕШЕНО: воссоздание базы данных решило проблему
Решение
Иногда изменения, внесенные в модель или 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.внесите изменения и обновите его до Create, чтобы можно было создать таблицу.
<property name="hbm2ddl.auto">create</property>
Это сработало для меня.
Взгляни на GeneratedValue
стратегия.Обычно это выглядит примерно так:
@GeneratedValue(strategy=GenerationType.IDENTITY)
Еще один совет — проверить, используете ли вы допустимый тип для автоматически создаваемого поля.Помните, что это не работает со String, но работает с Long:
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Long id;
@Constraints.Required
public String contents;
Приведенный выше синтаксис работал для создания таблиц в MySQL с использованием Hibernate в качестве поставщика JPA 2.0.
У меня такая же проблема.Я нашел учебник Пример сопоставления Hibernate «один к одному» с использованием аннотации внешнего ключа и следовал этому шаг за шагом, как показано ниже:
Создайте таблицу базы данных с помощью этого скрипта:
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.
Я пришел сюда из-за сообщения об ошибке. Оказывается, у меня было две таблицы с одинаковым именем.
Просто добавьте ненулевое ограничение
У меня такая же проблема.Я только что добавил ограничение not-null в сопоставление XML. Это сработало
<set name="phone" cascade="all" lazy="false" >
<key column="id" not-null="true" />
<one-to-many class="com.practice.phone"/>
</set>
Удаление таблицы из базы данных вручную, а затем повторный запуск приложения помогли мне.Думаю, в моем случае таблица не была создана должным образом (с ограничениями).
У меня была эта проблема.Моя ошибка заключалась в том, что я установил вставляемые и обновляемые поля как ложные и пытался установить поле в запросе.В БД это поле установлено как NON NULL.
@ManyToOne
@JoinColumn(name="roles_id", referencedColumnName = "id", insertable = false, updatable = false, nullable=false)
@JsonBackReference
private Role role;
Позже я изменил его на - Insertable = true, updateable = true.
@ManyToOne
@JoinColumn(name="roles_id", referencedColumnName = "id", insertable = true, updatable = true, nullable=false)
@JsonBackReference
//@JsonIgnore
private Role role;
Позже это сработало отлично.
Проверьте, установлено ли значение по умолчанию для идентификатора столбца в конкретной таблице. Если нет, сделайте его по умолчанию.
У меня такая же проблема.Я использовал таблицу соединений, и все, что у меня было, — поле идентификатора строки и два внешних ключа.Я не знаю точной причины, но я сделал следующее
- MySQL обновлен до версии сообщества 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),
В моем случае после удаления атрибута не используется идентификатор контракта, проблема решена.
Это случилось со мной с @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
);
Я попробовал код, и в моем случае приведенный ниже код решает проблему.Я не правильно определил схему
@Entity
@Table(name="table"
,catalog="databasename"
)
Пожалуйста, попробуйте добавить ,catalog="databasename"
так же, как и я.
,catalog="databasename"
В моем случае я изменил эти оскорбительные таблицы и поля «ID», который я сделал, я сделал это Auto_Increment, мне все еще нужно выяснить, почему во время развертывания это не делало его "Auto_Increment", чтобы я должен был сделать это самостоятельно!
Как насчет этого:
<set name="fieldName" cascade="all">
<key column="id" not-null="true" />
<one-to-many class="com.yourClass"/>
</set>
Надеюсь, это вам поможет.
Возможно, это проблема со схемой таблицы. бросить стол и перезапустите приложение.
Попробуйте изменить Long
тип объекта для long
примитивный тип (если вам подходит использование примитивов).
У меня была та же проблема, и смена типа помогла мне.
У меня была такая проблема, я по ошибке разместил @Transient
аннотация над этим конкретным атрибутом.В моем случае эта ошибка имеет смысл.
Добавить метод hashCode()
в ваш класс Entity Bean и повторите его.