A
A
Andrey Kovalchuk2016-04-04 07:55:54
Java
Andrey Kovalchuk, 2016-04-04 07:55:54

How to fix Null id generated?

Good afternoon. I have the following problem:

org.hibernate.id.IdentifierGenerationException: null id generated for:class Notebook.Enities.Telephone

The essence is clear, debug confirms: in id we have null for telephone.
GitHub : Notebook MySQL
DBMS . Field Id : Id int(11) not null;
Note.java class
@Component
public class Note {
    private int id;
    private Description descriptionId;
    private Human humanId;
    private Telephone telephoneId;
    private Group group;

    public Note (){

    }

    public Note(int id, Description descriptionId, Human humanId, Telephone telephoneId, Group group) {
        this.id = id;
        this.descriptionId = descriptionId;
        this.humanId = humanId;
        this.telephoneId = telephoneId;
        this.group = group;
    }

/************сеттеры и геттеры*****************/

Telephone.java class
@Component
public class Telephone {

    private Integer id;
    private String telephone;
    private String descripton;
    private Note note;

    public Note getNote() {
        return note;
    }

    public void setNote(Note note) {
        this.note = note;
    }

    public Telephone(int id, String telephone, String descripton) {
        this.id = id;
        this.telephone = telephone;
        this.descripton = descripton;
    }

    public Telephone() {
    }

    public Telephone(String telephone) {
        this.telephone = telephone;
    }
/*******************геттеры и сэттеры*************/

Action Executor: NotebookFacade.java
package Notebook.Objects;


import Notebook.DAO.interfaces.getNoteDAO;
import Notebook.Enities.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
@Scope("singleton")
public class NotebookFacade {

    @Autowired
    private getNoteDAO getNoteDAO;

    @Autowired
    private SearchCriteria searchCriteria;

    private List<Note> notes;


    public void createNote(Human human, Telephone telephone, Group group, Description description){
        Note note = new Note();
        note.setTelephoneId(telephone);
            telephone.setNote(note);
        note.setHumanId(human);
            human.setNote(note);
        note.setGroup(group);
        note.setDescriptionId(description);
            description.setNote(note);
        getNoteDAO.addNotes(note);
        System.out.println("Add work!");
    }

   

}

And the performer himself, who swears.
package Notebook.DAO.impl;

import Notebook.DAO.interfaces.getNoteDAO;
import Notebook.Enities.*;
import Notebook.Utils.HibernateUtil;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.*;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * Created by Ковальчук on 30.03.2016.
 */
@Component
public class GetNoteDAOImpl implements getNoteDAO {

    @Autowired
    private SessionFactory sessionFactory;
    private ProjectionList noteProjectionList;



     /******************************      Методы получения       *********************************/

       /****************************** Методы удаления, изменения записей *********************************/
    @Transactional
    @Override
    public void addNotes(Note note) {
        Session session = HibernateUtil.getSessionFactory().openSession();
        session.beginTransaction();
        session.save(note);
        session.getTransaction().commit();
        System.out.println("This function is worked");
        session.close();
    }


    @Transactional
    @Override
    public void deleteNotes(Note note) {
            Session session = HibernateUtil.getSessionFactory().openSession();
            session.beginTransaction();
            session.delete(note.getId());
            session.flush();
            session.getTransaction().commit();
    }
   
}

telephone.hbm.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>

    <class name="Notebook.Enities.Telephone" table="telephone" schema="notebase">
        <id name="id" type="java.lang.Integer">
            <column name="Id"/>
            <generator class="foreign">
                <param name="property">note</param>
            </generator>
        </id>
        <one-to-one name="note" class="Notebook.Enities.Note" constrained="true"/>
        <property name="telephone" column="Telephone"/>
        <property name="descripton" column="Descripton"/>
    </class>
</hibernate-mapping>

Note.hbm.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>

    <class name="Notebook.Enities.Note" table="note" schema="notebase">
        <id name="id" type="java.lang.Integer">
            <column name="Id" not-null="true"/>
            <generator class="identity"/>
        </id>
        <one-to-one class="Notebook.Enities.Telephone" name="telephoneId"  cascade="save-update"/>
        <one-to-one class="Notebook.Enities.Description" name="descriptionId" cascade="save-update"/>
        <one-to-one class="Notebook.Enities.Human" name="humanId" cascade="save-update"/>
        <many-to-one class="Notebook.Enities.Group" name="group" fetch="join" lazy="false">
            <column name="Group" not-null="true"/>
        </many-to-one>
    </class>
</hibernate-mapping>

Dumps: Phone
DROP TABLE IF EXISTS `telephone`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `telephone` (
  `Id` bigint(20) NOT NULL AUTO_INCREMENT,
  `Telephone` varchar(15) NOT NULL,
  `Descripton` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='Human telephone';

note
CREATE TABLE `note` (
  `Id` int(11) NOT NULL AUTO_INCREMENT,
  `Description_id` int(11) NOT NULL,
  `Human_id` int(20) DEFAULT NULL,
  `Telephone_id` bigint(20) NOT NULL,
  `Group` int(20) DEFAULT NULL,
  PRIMARY KEY (`Id`),
  KEY `fk_human_idx` (`Human_id`),
  KEY `fk_description_idx` (`Description_id`),
  KEY `fk_group_idx` (`Group`),
  KEY `fk_telephone_idx` (`Telephone_id`),
  CONSTRAINT `fk_description` FOREIGN KEY (`Description_id`) REFERENCES `description` (`Id`) ON UPDATE CASCADE,
  CONSTRAINT `fk_group` FOREIGN KEY (`Group`) REFERENCES `group` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `fk_human` FOREIGN KEY (`Human_id`) REFERENCES `human` (`id`) ON UPDATE CASCADE,
  CONSTRAINT `fk_telephone` FOREIGN KEY (`Telephone_id`) REFERENCES `telephone` (`Id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

The files are a little trimmed (removed the rest of the functionality, uncomplicated).
Please help fix the error.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
V
Vladimir Smirnov, 2016-04-04
@mrkovalchuk

You have nowhere defined a strategy for generating primary keys, neither at the DBMS level, nor at the level of your business logic. To generate an ID, I can recommend using the tools available in MySQL. To do this, define the primary key field in the database as:
and in the entity mappings, specify the following:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
protected Long id;

With this approach, the value of the primary key is created directly at the moment the record is inserted into the table. When executing the INSERT command, the value of the ID field is not specified, and MySQL itself will substitute the value, using a sequence to generate it (a specific DBMS object that sequentially generates numbers, usually starting from 1).
I strongly do not recommend using primitives to determine the ID in the entity (private int id in Note), because when creating a new instance of the class, the default value of 0 will be assigned, which leads to confusion - the primary key has not yet been generated, but it already has some value.
Usually, the entity class that describes the identifier is moved to the parent class, and all project entities are inherited from it, due to which it becomes possible not to describe the ID field repeatedly in all heirs, getting rid of code duplication. But, first get the current structure working, and then refactor the class hierarchy. Here is an example of a parent class definition:
import javax.persistence.*;
import java.io.Serializable;

@MappedSuperclass
public abstract class Identifier implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID")
    protected Long id;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        Identifier that = (Identifier) o;

        if (getId() != null) {
            return getId().equals(that.getId());
        } else {
            return super.equals(o);
        }
    }

    public int hashCode() {
        return getId() != null ? getId().hashCode() : super.hashCode();
    }
}

DB entity mappings are usually defined using JPA annotations, as follows:
import javax.persistence.*;

@Entity()
@Table(name = "note")
public class Note extends Identifier {
//fields, getters, setters
}

M
Maxim Moseychuk, 2016-04-04
@fshp

Null and 0 are different things.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question