Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
hibernate会话中的持久化数据变得陈旧,有时hibernate会生成重复的ID_Hibernate_Session_Tomcat_Liferay - Fatal编程技术网

hibernate会话中的持久化数据变得陈旧,有时hibernate会生成重复的ID

hibernate会话中的持久化数据变得陈旧,有时hibernate会生成重复的ID,hibernate,session,tomcat,liferay,Hibernate,Session,Tomcat,Liferay,我正在为我的应用程序使用hibernate。有时hibernate会生成重复的ID,我使用的策略是增量,从表中执行max(ID)并添加一个。我不知道为什么会发生这种情况,而且是突然发生的,在那之后,所有后续的表插入操作请求都失败了。解决方法是重新启动tomact服务器 以下是申请的详细信息 1.3个部署在liferay-tomcat上的应用程序。每个应用程序都有自己的抽象-impls.jar。此jar包含使用Hibernate与oracle交互的类。我可以怀疑这是导致这个问题的一个可能的案例 2

我正在为我的应用程序使用hibernate。有时hibernate会生成重复的ID,我使用的策略是增量,从表中执行max(ID)并添加一个。我不知道为什么会发生这种情况,而且是突然发生的,在那之后,所有后续的表插入操作请求都失败了。解决方法是重新启动tomact服务器

以下是申请的详细信息

1.3个部署在liferay-tomcat上的应用程序。每个应用程序都有自己的抽象-impls.jar。此jar包含使用Hibernate与oracle交互的类。我可以怀疑这是导致这个问题的一个可能的案例

2.所有3个应用程序都有与hibernate相关的JAR

我做了以下测试,以确认问题是否由于多线程导致, 1)创建了一个3个线程,其中每个线程运行一个for循环20次以插入同一个表>我没有发现任何问题。一切都很顺利

下面是上面的示例代码

public class ThreadTest implements Runnable{
@Override
public void run() {
    // TODO Auto-generated method stub
    for(int i=0;i<20;i++){
        UserManagement userManagement = new UserManagementImpl(-1);
        Context context = new Context();
        context.setUserId("testUser");
        context.getUserContextMap().put("password", "shiva123");
        try{
        int sessionId = userManagement.login(context);
        System.out.println("thread<<"+Thread.currentThread().getName() + ">>    "+sessionId);
        }catch(Exception e){
            e.printStackTrace();
        }

    }
}

public static void main(String[] args) {
    Thread t1 = new Thread(new ThreadTest());
    Thread t2 = new Thread(new ThreadTest());
    Thread t3 = new Thread(new ThreadTest());
    t1.setName("t1");
    t2.setName("t2");
    t3.setName("t3");
    t1.start();
    t2.start();
    t3.start();
}
}

下面是保存实体的方法

private boolean save (Serializable object, Session session) throws EntityNotFoundException, InternalSystemException {
    logger.debug("save() - start"); 
    Transaction tx = null;
    boolean successful = false;
    boolean localInit = false;
    try {
        if (session == null) {
            session = createSession();
            tx = session.beginTransaction();
            //session.save(object);
            localInit = true;
        }
        session.save(object);
        logger.debug("**********************************");
        logger.debug("object: "+object);
        logger.debug("**********************************");
        if (localInit == true) {
            tx.commit();
        }
        successful = true;
    } catch(HibernateException ex) {
        logger.error("error in saving entity "+ ex);
        if (localInit == true && tx !=null)
            tx.rollback();
        ex.printStackTrace();
        throw new InternalSystemException("error in saving entity "+ ex);
    } catch(Exception ex) {
        logger.error("error in saving entity "+ex);
        if (localInit == true && tx !=null)
            tx.rollback();
        new InternalSystemException("error in saving entity "+ ex);
    }finally {
        if (localInit && session != null) {
            session.flush();
            session.clear();
            session.close();
        }
    }
    if (logger.isDebugEnabled()) {
        logger.debug("save() - end"); 
    }
    return successful;
}

错误不会总是发生,但一旦发生,同样的错误将继续发生,测试的oracle环境是oracle RACK

在这种情况下不应使用增量策略。它包括在内存中的计数器中加载最大值,然后在每次请求新ID时递增该值。由于部署了3个应用程序,因此有3个这样的计数器,每个计数器初始化为相同的初始值,因此它们将返回相同的ID

这显然是:

增量

生成long、short或int类型的标识符,这些标识符只有在没有其他进程将数据插入同一个表时才是唯一的。做 不在集群中使用

(重点不是我的)


序列生成器不会出现同样的问题。如果是这样,那么要么是配置中缺少了某些内容,要么是三个应用程序中的一个继续使用增量策略,要么是从外部插入ID,要么是数据库中序列的初始值错误。如果看不到代码、ID的最大值和序列的定义,很难说。

您是否有3个不同的Web应用程序,每个应用程序都使用增量策略插入到相同的表中?是的。。有3个web应用程序和相同的JAR,并且每个JAR都插入到相同的表格中,并复制到每个web应用程序的lib文件夹中。并采用增量策略。甚至我也尝试过使用序列。但问题依然存在。
private boolean save (Serializable object, Session session) throws EntityNotFoundException, InternalSystemException {
    logger.debug("save() - start"); 
    Transaction tx = null;
    boolean successful = false;
    boolean localInit = false;
    try {
        if (session == null) {
            session = createSession();
            tx = session.beginTransaction();
            //session.save(object);
            localInit = true;
        }
        session.save(object);
        logger.debug("**********************************");
        logger.debug("object: "+object);
        logger.debug("**********************************");
        if (localInit == true) {
            tx.commit();
        }
        successful = true;
    } catch(HibernateException ex) {
        logger.error("error in saving entity "+ ex);
        if (localInit == true && tx !=null)
            tx.rollback();
        ex.printStackTrace();
        throw new InternalSystemException("error in saving entity "+ ex);
    } catch(Exception ex) {
        logger.error("error in saving entity "+ex);
        if (localInit == true && tx !=null)
            tx.rollback();
        new InternalSystemException("error in saving entity "+ ex);
    }finally {
        if (localInit && session != null) {
            session.flush();
            session.clear();
            session.close();
        }
    }
    if (logger.isDebugEnabled()) {
        logger.debug("save() - end"); 
    }
    return successful;
}