简体   繁体   English

Hibernate PersistenceContext会话刷新

[英]Hibernate PersistenceContext session Flush

i want to know when does hibernate fulshes the context session when i call session= session.getCurrentSession() 我想知道当我调用session = session.getCurrentSession()时,休眠何时触发上下文会话

The thing is i have 2 methods in my dao calling getCurrentSession(), when i process the update making the call to getCurrentSession() the entitys are empty: 事情是,我在dao中有2个调用getCurrentSession()的方法,当我处理对getCurrentSession()的调用的更新时,实体为空:

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

How can i make this entitys persist from the select method to the update method? 我如何才能使这些实体从选择方法保留到更新方法?

Here are my methods: 这是我的方法:

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;
        } 
    }

And this is my interceptor: 这是我的拦截器:

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 will flush when you tell it to and when the current transaction is "closed" (usually when the DB connection is returned to the pool somehow). 当您告诉Hibernate和当前事务“关闭”时,Hibernate将刷新(通常在DB连接以某种方式返回到池时)。

So the answer to your question depends on which framework you use. 因此,问题的答案取决于您使用的框架。 With Spring, the session is flushed when the outermost @Transactional method returns. 使用Spring,最外面的@Transactional方法返回时,将刷新会话。

Your "solution" above will not work for long since it never closes the session. 您上面的“解决方案”将无法使用很长时间,因为它永远不会关闭会话。 While it returns a result, it will leak a database connection so after a few calls, you will run out of connections. 当它返回结果时,它将泄漏数据库连接,因此,在几次调用之后,您将耗尽连接。

Also your question doesn't really make sense. 同样,您的问题没有任何意义。 SELECT doesn't change objects, so they don't need to be "persisted" before you change them. SELECT不会更改对象,因此在您更改对象之前不需要对其进行“持久化”。

After changing them in updateConfigurations() , Hibernate can chose not to write them into the database immediately and just update the cache. updateConfigurations()更改它们之后,Hibernate可以选择不立即将它们写入数据库,而只是更新缓存。

Eventually, if you configured everything correctly, Spring will commit the transaction and that will flush the cache. 最终,如果您正确配置了所有内容,Spring将提交事务并刷新缓存。 But when you use Spring, you should never create open and close sessions because it will mess with what Spring is doing. 但是,当您使用Spring时,永远不要创建打开和关闭会话,因为这会干扰Spring的工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM