Z
Z
Zaur Abdulgalimov2016-09-19 08:50:59
MySQL
Zaur Abdulgalimov, 2016-09-19 08:50:59

Where does the "Column 'id' cannot be null" error come from in Hibernate?

Good afternoon. Please help me solve the problem on the release... yes, the project is already running and there is a bug in the release :( Periodically there is an error like:

ERROR SqlExceptionHelper:logExceptions[131] - Column 'id' cannot be null
ERROR BatchingBatch:performExecution[124] - HHH000315: Exception executing batch [could not execute batch]
ERROR ?:[] - Column 'id' cannot be null
ERROR ?:[] - HHH000315: Exception executing batch [could not execute batch]

My id is not set manually anywhere, it is generated everywhere via auto_increment:
@Id
GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;

I understand that to solve the problem you need to see the code ... but maybe someone knows where the problem can grow from and where you need to dig in the first place ... I'm new to the java + hibernate world and therefore could mess up somewhere.
Thank you.
UPD
Added a class that works with the base. The bottom line is that when a command (request) comes to the server, one session is opened by the openRequestSession method , then all operations for creating an update are done in this session, and at the end of the request, the closeRequestSession method is done .
I do not use the insert and update methods: this is done using hibernate.
package ru.fp.qa.controller.db;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.query.NativeQuery;
import org.hibernate.query.Query;
import ru.flashpress.tbot.received.JUser;
import ru.fp.qa.constants.BuildTypes;
import ru.fp.qa.controller.core.Controller;
import ru.fp.qa.controller.importer.model.OldPollsModel;
import ru.fp.qa.controller.importer.model.OldUsersModel;
import ru.fp.qa.core.Conf;
import ru.fp.qa.model.callback.CallbackModel;
import ru.fp.qa.model.poll.*;
import ru.fp.qa.model.user.UState;
import ru.fp.qa.model.user.UserModel;

import java.io.File;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by sam on 29.08.16.
 */
public class DBController extends Controller
{
    private static final Logger log = LogManager.getLogger(DBController.class);

    public static DBController instance;
    private SessionFactory sessionFactory;

    public DBController()
    {
        instance = this;
        String cfgUrl = null;
        switch (Conf.build()) {
            case BuildTypes.DEVELOP:
                cfgUrl = Conf.getResourcePath("hb/dev.hibernate.cfg.xml");
                break;
            case BuildTypes.TEST:
                cfgUrl = Conf.getResourcePath("hb/test.hibernate.cfg.xml");
                break;
            case BuildTypes.RELEASE:
                cfgUrl = Conf.getResourcePath("hb/release.hibernate.cfg.xml");
                break;
        }
        //
        StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
                .configure(new File(cfgUrl))
                .build();
        try {
            sessionFactory = new MetadataSources( registry ).buildMetadata().buildSessionFactory();
        }
        catch (Exception e) {
            StandardServiceRegistryBuilder.destroy( registry );
            e.printStackTrace();
        }
        //
        openRequestSession();
        NativeQuery query = createNativeQuery("SET NAMES 'utf8mb4'");
        query.executeUpdate();
        closeRequestSession();
    }


    private Session _requestSession;
    private int openCount = 0;
    public void openRequestSession()
    {
        log.debug("count:"+openCount);
        try {
            if (openCount == 0) {
                _requestSession = sessionFactory.openSession();
                _requestSession.beginTransaction();
            }
            openCount++;
        } catch (Exception e) {
            log.error("open", e);
        }
    }
    public void closeRequestSession()
    {
        openCount--;
        log.debug("count:"+openCount);
        try {
            if (openCount == 0) {
                _requestSession.flush();
                _requestSession.getTransaction().commit();
                _requestSession.close();
                _requestSession.clear();
            }
        } catch (Exception e) {
            log.error("close", e);
        }
    }

    private NativeQuery createNativeQuery(String query)
    {
        try {
            return _requestSession.createNativeQuery(query);
        } catch (Exception e) {
            log.error(query, e);
            return null;
        }
    }

    private <R> NativeQuery<R> createNativeQuery(String query, Class<R> results)
    {
        try {
            return _requestSession.createNativeQuery(query, results);
        } catch (Exception e) {
            log.error(query+" / "+results, e);
            return null;
        }
    }
    private boolean _saveAndFlush(Object object)
    {
        try {
            _requestSession.save(object);
            _requestSession.flush();
            return true;
        } catch (Exception e) {
            log.error(object, e);
            _requestSession.getTransaction().rollback();
            _requestSession.getTransaction().begin();
            return false;
        }
    }
    private boolean _saveOrUpdateAndFlush(Object object)
    {
        try {
            _requestSession.saveOrUpdate(object);
            _requestSession.flush();
            return true;
        } catch (Exception e) {
            log.error(object, e);
            _requestSession.getTransaction().rollback();
            _requestSession.getTransaction().begin();
            return false;
        }
    }
    private void _removeAndFlush(Object object)
    {
        try {
            _requestSession.remove(object);
            _requestSession.flush();
        } catch (Exception e) {
            log.error(object, e);
            _requestSession.getTransaction().rollback();
            _requestSession.getTransaction().begin();
        }
    }

    private void _flush()
    {
        try {
            if (_requestSession.getTransaction().isActive()) _requestSession.flush();
        } catch (Exception e) {
            log.error("flush", e);
        }
    }


    // public api **********************************************************

    public boolean save(Object object)
    {
        return _saveAndFlush(object);
    }
    public boolean saveOrUpdate(Object object)
    {
        return _saveOrUpdateAndFlush(object);
    }

    // users ***************************************************************

    public UState createState(int action, UserModel userModel)
    {
        deleteState(userModel);
        //
        UState state = UState.create(action, userModel.getUid());
        this.save(state);
        return state;
    }
    public UState loadState(UserModel userModel)
    {
        String queryValue = "SELECT * FROM ustate WHERE (uid=" + userModel.getUid() + ");";
        Query<UState> query = createNativeQuery(queryValue, UState.class);
        List<UState> list = query.getResultList();
        if (!list.isEmpty()) {
            UState state = list.get(0);
            state.loadComplete();
            return state;
        } else {
            return null;
        }
    }
    public boolean deleteState(UserModel userModel)
    {
        NativeQuery query = createNativeQuery("DELETE FROM ustate WHERE uid = " + userModel.getUid() + ";");
        int res = query.executeUpdate();
        _flush();
        return res == 1;
    }

    public UserModel createUser(JUser user)
    {
        UserModel userModel = getUser(user.id);
        String fullName = null;
        if (user.firstName != null) fullName = user.firstName;
        if (user.lastName != null) {
            if (fullName == null) fullName = "";
            if (!fullName.isEmpty()) fullName += " ";
            fullName += user.lastName;
        }
        //
        if (userModel != null) {
            if (userModel.getName() != null) {
                if (!userModel.getName().equals(fullName)) userModel.setName(fullName);
            } else {
                if (fullName != null) userModel.setName(fullName);
            }
            //
            if (userModel.getLogin() != null) {
                if (!userModel.getLogin().equals(user.login)) userModel.setLogin(user.login);
            } else {
                if (user.login != null) userModel.setLogin(user.login);
            }
        } else {
            userModel = new UserModel(); //.create(user.id, user.firstName, user.login);
            userModel.setUid(user.id);
            userModel.setName(fullName);
            _saveAndFlush(userModel);
        }
        return userModel;
    }

    public UserModel getUser(int uid)
    {
        String queryValue = "SELECT * FROM user WHERE (uid=" + uid + ");";
        Query<UserModel> query = createNativeQuery(queryValue, UserModel.class);
        List<UserModel> list = query.getResultList();
        return !list.isEmpty() ? list.get(0) : null;
    }
    public UserModel getUserById(int id)
    {
        String queryValue = "SELECT * FROM user WHERE (id=" + id + ");";
        Query<UserModel> query = createNativeQuery(queryValue, UserModel.class);
        List<UserModel> list = query.getResultList();
        return !list.isEmpty() ? list.get(0) : null;
    }

    // дальше все в таком духе "создать Entity" и "найти Entity"
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
Vladimir Smirnov, 2016-09-19
@abdulgalimov

Check the child entity settings. The idea is something like this - ID generation is configured everywhere, but Hibernate does not always "know" that this generation should be used in a particular case. For example, you save a new user - the save passes. Then you add the role to the user's list of roles, save it, and an error occurs because the role list mapping does not specify CascadeType.PERSIST or CascadeType.ALL. If you didn't "tell" Hibernate to save child entities, but added a new object to the list, then there will be no attempt to create the added object in the database. If the problem is in child objects, then this may also explain the inconsistency of the error: if no child objects were added - everything is OK, if they were added - an error.
Check all @OneToMany links.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question