java - Hibernate PersistenceContext session 刷新

标签 java spring hibernate session

我想知道当我调用 session= session.getCurrentSession() 时,hibernate 何时完成上下文 session

问题是我的 dao 中有 2 个方法调用 getCurrentSession(),当我处理更新并调用 getCurrentSession() 时,实体为空:

SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];...)

如何使该实体从选择方法持续到更新方法?

这是我的方法:

public List<SystemConfiguration> getListConfigurations() {
    List<SystemConfiguration> lista = new ArrayList<SystemConfiguration>();
    Session session = null;
    Query query = null;

    String sql = "from SystemConfiguration where description = :desc";
    try {
        /* BEFORE
            session = SessionFactoryUtil.getInstance().getCurrentSession(); 
        @SuppressWarnings("unused")
        Transaction ta = session.beginTransaction(); */
            //FOLLOWING LINE SOLVED THE PROBLEM
            session = SessionFactoryUtil.getInstance().openSession();
        query = session.createQuery(sql);

        query.setString("desc", "configuracion");
        lista = query.list();

        return lista;
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}


public void updateConfigurations(List<SystemConfiguration> configs) throws Exception{
        Session sess = null;
        Transaction tx = null;
        try {
                    //BEFORE
            //sess = SessionFactoryUtil.getInstance().getCurrentSession();
                    //FOLLOWING LINE SOLVED THE PROBLEM
                 sess = SessionFactoryUtil.getInstance().openSession(new SystemConfigurationInterceptor());
            tx = sess.beginTransaction();
            for (SystemConfiguration sys : configs) {
                    sess.update(sys);   
            }
            tx.commit();
        } // try
        catch (Exception e) {
            e.printStackTrace();
            if (tx != null && tx.isActive()) {
                tx.rollback();
            } // if
            throw e;
        } 
    }

这是我的拦截器:

public class SystemConfigurationInterceptor extends EmptyInterceptor {
            private int updates;
        private int creates;
        private int loads;
        public void onDelete(Object entity,
                             Serializable id,
                             Object[] state,
                             String[] propertyNames,
                             Type[] types) {
            // do nothing
        }

        // This method is called when Entity object gets updated.
        public boolean onFlushDirty(Object entity,
                                    Serializable id,
                                    Object[] currentState,
                                    Object[] previousState,
                                    String[] propertyNames,
                                    Type[] types) {

            if ( entity instanceof SystemConfiguration ) {
                updates++;
                for ( int i=0; i < propertyNames.length; i++ ) {
                    if ( "updated_at".equals( propertyNames[i] ) ) {
                        currentState[i] =  new Timestamp(Calendar.getInstance().getTime().getTime());
                        return true;
                    }
                }
            }
            return false;
        }

        public boolean onLoad(Object entity,
                              Serializable id,
                              Object[] state,
                              String[] propertyNames,
                              Type[] types) {
            if ( entity instanceof SystemConfiguration ) {
                loads++;
            }
            return false;
        }

     // This method is called when Entity object gets created.
        public boolean onSave(Object entity,
                              Serializable id,
                              Object[] state,
                              String[] propertyNames,
                              Type[] types) {

            if ( entity instanceof SystemConfiguration ) {
                creates++;
                for ( int i=0; i<propertyNames.length; i++ ) {
                    if ( "updated_at".equals( propertyNames[i] ) ) {
                        state[i] = new Timestamp(Calendar.getInstance().getTime().getTime());
                        return true;
                    }
                }
            }
            return false;
        }

        public void afterTransactionCompletion(Transaction tx) {
            if ( tx.wasCommitted() ) {
                System.out.println("Creations: " + creates + ", Updates: " + updates +", Loads: " + loads);
            }
            updates=0;
            creates=0;
            loads=0;
        }

最佳答案

当您告诉 Hibernate 以及当前事务“关闭”时(通常是当数据库连接以某种方式返回到池中时),Hibernate 将会刷新。

所以你的问题的答案取决于你使用的框架。使用 Spring,当最外面的 @Transactional 方法返回时, session 将被刷新。

您上面的“解决方案”不会持续很长时间,因为它永远不会关闭 session 。当它返回结果时,它会泄漏数据库连接,因此在几次调用之后,您将耗尽连接。

而且你的问题根本没有意义。 SELECT 不会更改对象,因此在更改它们之前不需要“保留”它们。

updateConfigurations()中更改它们后,Hibernate可以选择不立即将它们写入数据库,而只是更新缓存。

最终,如果您正确配置了所有内容,Spring 将提交事务并刷新缓存。但是当您使用 Spring 时,您永远不应该创建打开和关闭 session ,因为这会扰乱 Spring 正在做的事情。

关于java - Hibernate PersistenceContext session 刷新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19127366/

相关文章:

spring - 从日志附加器类访问 spring bean

java - 使用Spring post方法时出现异常: org. springframework.web.HttpRequestMethodNotSupportedException

java - hibernate 生成器不会插入唯一标识符

java - Hibernate 中 CustomCollectionType 与 UserCollectionType 的预期用例是什么?

mysql - 组织.hibernate.InstantiationException : Cannot instantiate abstract class or interface + google cloud sql

java - AspectJ "around"和 "proceed"与 "before/after"

java - 识别能够更新 UI 组件的线程

java - X 射线跟踪未从 ec2 中出现,出现异常

java - 计算二维 int 数组最小值的程序

spring - 调试独立的 Spring Boot 应用程序 (Intellij IDEA)