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