Pergunta

Eu estou enfrentando o que eu acho que é um problema simples com Hibernate, mas não pode resolvê-lo (fóruns Hibernate sendo inacessível certamente não ajuda).

Eu tenho uma classe simples que eu gostaria de persistir, mas continuo recebendo:

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 ]

O código relevante para a classe persistente é a seguinte:

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;
    }
}

E o código de funcionamento real é simplesmente:

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();
}

Eu tentei algumas "estratégias" dentro da anotação GeneratedValue mas ele simplesmente não parece trabalho. Inicializar id também não ajuda! (Por exemplo Long id = 20L).

Alguém poderia lançar alguma luz?

EDIT 2: confirmada: mexer with@GeneratedValue(strategy = GenerationType.XXX) não resolvê-lo

RESOLVIDO: recriar o banco de dados resolveu o problema

Foi útil?

Solução

Às vezes as alterações feitas ao modelo ou ao ORM podem não refletir com precisão no banco de dados, mesmo depois de uma execução de SchemaUpdate.

Se o erro realmente parece que falta uma explicação sensata, tente recriar o banco de dados (ou pelo menos criar uma nova) e andaimes com SchemaExport.

Outras dicas

Se você quiser que o MySQL automaticamente produzir chaves primárias, em seguida, você tem que dizer isso ao criar a tabela. Você não tem que fazer isso em Oracle.

na chave primária você tem que incluir AUTO_INCREMENT. Veja o exemplo abaixo.

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;  

Aqui está a Entidade

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;
  }

}

você deve estar usando atualização em sua propriedade hbm2ddl. fazer as mudanças e atualizar-lo para criar de modo que possa criar a tabela.

<property name="hbm2ddl.auto">create</property>

Ela trabalhou para mim.

Dê uma olhada na estratégia da GeneratedValue. Ele normalmente é algo como:

@GeneratedValue(strategy=GenerationType.IDENTITY)

Outra sugestão é verificar se você usar um tipo válido para o campo gerado automaticamente. Lembre-se que ele não funciona com String, mas funciona com Long:

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

@Constraints.Required
public String contents;

A sintaxe acima funcionou para gerar tabelas no MySQL usando Hibernate como provedor JPA 2.0.

Eu tive o mesmo problema. Achei o tutorial Hibernate One-To-One Exemplo Mapping usando a chave Foreign Anotação e seguiu passo a passo como abaixo:

Crie a tabela de banco de dados com este 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)   
);

Aqui está as entidades com as tabelas acima

@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;
}

O problema foi resolvido.

Aviso: A chave primária deve ser definida como AUTO_INCREMENT

Eu vim aqui por causa da mensagem de erro, Acontece que eu tinha duas tabelas com o mesmo nome.

Basta adicionar não-nula restrição

Eu tive o mesmo problema. Acabei de adicionar restrição de não nulo no mapeamento XML. Funcionou

<set name="phone" cascade="all" lazy="false" > 
   <key column="id" not-null="true" />
   <one-to-many class="com.practice.phone"/>
</set>

Deixar cair a tabela do banco de dados manualmente e, em seguida, re-executar o aplicativo funcionou para mim. No meu caso a tabela não foi criado corretamente (com restrições), eu acho.

Eu tive esse problema. Meu erro foi que eu tinha definido os fileds inserível e atualizáveis ??como falso e estava tentando definir o campo no pedido. Este campo é definido como não NULL no DB.

@ManyToOne
@JoinColumn(name="roles_id",  referencedColumnName = "id", insertable = false, updatable = false, nullable=false)
@JsonBackReference
private Role role;

Mais tarde eu mudei para - inserível = true, atualizável = true

@ManyToOne
@JoinColumn(name="roles_id",  referencedColumnName = "id", insertable = true, updatable = true, nullable=false)
@JsonBackReference
//@JsonIgnore
private Role role;

Ele funcionou perfeitamente depois.

Por favor, verifique se o valor padrão para o ID de coluna em particular table.if não fazê-lo como padrão

Eu tive o mesmo problema. Eu estava usando uma tabela associativa e tudo que eu tive com um campo de linha id e duas chaves estrangeiras. Eu não sei exatamente o causou, mas eu fiz o seguinte

  1. MySQL atualizado para comunidade 5.5.13
  2. Mudar o nome da classe e tabela
  3. Certifique-se de que eu tinha hashcode e iguala métodos

    @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;
    

A mesma exceção foi lançada se uma tabela DB tinha uma coluna unremoved de idade.

Por exemplo: attribute_id NOT NULL BIGINT(20), e attributeId NOT NULL BIGINT(20),

Depois de remover o atributo não é usado, no meu caso, contractId , o problema foi resolvido.

Isto aconteceu-me com uma relação @ManyToMany. Eu tinha anotado um dos campos no relacionamento com @JoinTable, eu removi que e usado o atributo mappedBy em @ManyToMany vez.

Além do que foi mencionado acima, não se esqueça ao criar a tabela sql para fazer o AUTO INCREMENT como neste exemplo

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
);

Eu tentei o código e no meu caso o código abaixo resolver a questão. Eu não tinha resolvido o esquema corretamente

@Entity
    @Table(name="table"
         ,catalog="databasename"
      )

Por favor, tente adicionar ,catalog="databasename" o mesmo que eu fiz.

,catalog="databasename"

No meu caso, Eu alterei que ofender tabelas e o campo "id" em questão eu fiz isso AUTO_INCREMENT, eu ainda preciso descobrir por que em tempo de implantação não foi tornando-se "AUTO_INCREMENT" para que eu tenho que fazer isso por mim!

O que sobre isso:

<set name="fieldName" cascade="all"> 
   <key column="id" not-null="true" />
   <one-to-many class="com.yourClass"/>
</set>

Espero que ajude você.

Talvez que é o problema com o esquema da tabela. remover a tabela e execute novamente o aplicativo.

Tente mudar tipo Long objeto para long tipo primitivo (se estiver usando primitivas é ok para você).

Eu tive o mesmo problema e alterar o tipo de me ajudou.

Eu tive este problema, por engano eu tinha colocado anotação @Transient acima desse atributo particular. No meu caso esse erro faz sentido.

Adicionar um hashCode() método para seu bean de entidade de classe e tentar novamente

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top