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
org.hibernate.AssertionFailure_Hibernate_Transactions - Fatal编程技术网

org.hibernate.AssertionFailure

org.hibernate.AssertionFailure,hibernate,transactions,Hibernate,Transactions,我的线程执行时,有时会出现这种奇怪的错误。这可能与什么有关 2011-Jun-25 09:05:22,339 ERROR AssertionFailure:45 - an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session) org.hibernate.AssertionFailure: nu

我的线程执行时,有时会出现这种奇怪的错误。这可能与什么有关

2011-Jun-25 09:05:22,339 ERROR AssertionFailure:45 - an assertion failure occured (this             may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)
org.hibernate.AssertionFailure: null id in com.inrev.bm.bean.IRKeyWordTweet entry (don't flush the Session after an exception occurs)
    at         org.hibernate.event.def.DefaultFlushEntityEventListener.checkId(DefaultFlushEntityEventListener.java:78)
at org.hibernate.event.def.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:187)
at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:143)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:219)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:99)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:49)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1028)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:366)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
at com.inrev.bm.streaming.IRKeyWordStreaminThread.run(IRKeyWordStreaminThread.java:119)
我的插入代码

    Transaction tx = null;
    Session session = sessionFactory.openSession();
    tx = session.beginTransaction();

    int count = 0;
    try
    {
        for (Iterator itrList = statusToInsert.iterator(); itrList.hasNext();) 
        {
            try 
            {
                IRecord record = (IRecord) itrList.next();
                session.save(record);
                count++;
                if ( count % 10 == 0 ) 
                { 
                    session.flush();
                    session.clear();
                    tx.commit();
                    tx = session.beginTransaction();
                }

            }
            catch (Exception e) 
            {
                tx.commit();
                session.close();
                session = sessionFactory.openSession();
                tx = session.beginTransaction();
                StringWriter sw = new StringWriter(); 
                PrintWriter pw = new PrintWriter(sw); 
                e.printStackTrace(pw); 
                log.error(sw.toString());
            }
        }
    }
    catch (Exception e) {
        StringWriter sw = new StringWriter(); 
        PrintWriter pw = new PrintWriter(sw); 
        e.printStackTrace(pw); 
        log.error(sw.toString());
    }
    finally {
        tx.commit();
        session.close();
    }
问候,


Rohit

问题在于,您的代码正在处理异常,在99.9%的情况下,这是一件非常糟糕的事情,并且发生了以下情况:

与会话的某个交互在try块中失败,并引发异常。发生这种情况时,会话将无效,并且不能用于任何内容,因为会话处于不一致状态。但是您的代码与catch块中的会话交互,从而触发断言


会话发生异常后,唯一安全的方法是回滚事务并关闭它。任何其他类型的交互都可能会生成另一个异常(在本例中为断言异常)。

一个未被干净处理的用例是某种轮询器。如果应用程序正在为大型后台作业设置一些“进行中状态”,提交,然后进行单独的线程/http请求/会话轮询,而异步后台线程抛出异常,则该异步线程需要负责捕获该异常,并将轮询器正在轮询的对象的状态标记为“失败”。在这种情况下,会话会因低级别的hibernate异常而失效。这似乎是捕获和处理异常的有效案例


是获得新课程的唯一解决办法吗?在诸如Seam之类的托管事务环境中执行此操作的干净/标准方法?

除了@Augustoanswer:

在文件
UserDAOImpl.java

@Override
public int addUser(User user) {

    // Maintain Hibernate session manually 
    Session openSession = sessionFactory.openSession();

    int retVal = 0;

    try {
        openSession.getTransaction().begin();
        openSession.persist(user);
        openSession.getTransaction().commit();
        retVal = 1;
    } catch (HibernateException e) {
        openSession.getTransaction().rollback();
        retVal = -1;
    } finally {
        openSession.close();
    }
    return retVal;
}

在此之前,日志中是否有异常?通常,由于约束冲突导致插入失败后会出现该异常。如果抛出的异常是侦听器抛出的已检查异常,这并不糟糕,在这种情况下,我希望将消息放在某个位置并处理下一个元素。这是批处理中非常常见的场景。Lluis,批处理是一个非常不同的野兽(在hibernate中)。对于批处理,最好使用。由于hibernate不会将对象与无状态会话关联,因此错误不会使会话无效。感谢@Augusto的解释。您能否举例说明最佳实践。我正在服务层中使用
@Transactional
,所以您将如何建议实现。