Откуда ошибка «Column 'id' cannot be null» в Hibernate?

Добрый день. Помогите плиз решить проблему на релизе... да проект уже запущен и бага в релизе :( Периодически возникает ошибка вида:
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]


У меня ни где id не задается вручную, везде генерится через auto_increment:
@Id
GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;


Я понимаю что для решения проблемы нужно видеть код... но может кто нибудь знает откуда могут расти проблему и где нужно копать в первую очередь ... Я новичок в мире java+hibernate и поэтому мог напутать где нибудь.

Спасибо.

UPD

Добавил класс который работает с базой. Суть в том, что когда приходит команда(запрос) к серверу - открывается одна сессия методом openRequestSession, далее все операции создания обновления делаются в этой сессии, и в конце запроса делается метод closeRequestSession.

Я не использую методы insert и update: это делается средствами 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"
}
  • Вопрос задан
  • 2914 просмотров
Решения вопроса 1
@bobzer
Java EE Developer
Проверьте настройки дочерних сущностей. Мысль примерно такая - генерация ID настроена везде, но Hibernate не всегда "знает" о том, что в конкретном случае надо использовать эту генерацию. Например, вы сохраняете нового пользователя - сохранение проходит. Затем вы добавляете роль в список ролей пользователя, сохраняете - и возникает ошибка потому, что в маппинге списка ролей не указано CascadeType.PERSIST или CascadeType.ALL. Если вы не "сказали" Hibernate-у сохранять дочерние сущности, но добавили новый объект в список, то не будет попытки создать добавленный объект в БД. Если дело именно в дочерних объектах, то этим может объясняться и непостоянство возникновения ошибки: не добавляли дочерних объектов - всё ОК, добавили - ошибка.

Проверьте все связи @OneToMany.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы