• spring+hibernate--直接修改数据库,再通过hibernate查询数据不变


    这个问题已经很多天了,一直没有时间解决,不过还好是自己的项目,没什么影响。

    刚好今天没事,想好好解决一下这个问题。

    hibernate主要配置如下:

     1         <property name="hibernate.format_sql">true</property>
     2         <property name="connection.url">
     3             jdbc:mysql://localhost:3306/vipmf?autoReconnect=true&amp;useUnicode=true&amp;characterEncoding=utf-8
     4         </property>
     5         <property name="connection.username">root</property>
     6         <property name="connection.password">123456</property>
     7         <property name="connection.driver_class">
     8             com.mysql.jdbc.Driver
     9         </property>
    10         <property name="connection.autocommit">false</property>
    11         <property name="show_sql">true</property>
    12         <property name="hibernate.dialect">
    13             org.hibernate.dialect.MySQLDialect
    14         </property>
    15         <property name="hibernate.current_session_context_class">
    16             thread
    17         </property>
    18         <property name="hibernate.cache.use_query_cache">  
    19              false   
    20         </property>

    spring配置:

        <bean id="sessionFactory"
            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
            <property name="configLocations">
                <list>
                    <value>classpath:hibernate.cfg.xml</value>
                </list>
            </property>
        </bean>
        
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <!-- 为事务管理器注入sessionFactory" --> <property name="sessionFactory" ref="sessionFactory" /> </bean> <!-- 配置事务拦截器Bean --> <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor"> <!-- 为事务拦截器bean注入一个事物管理器 --> <property name="transactionManager" ref="transactionManager"></property> <property name="transactionAttributes"> <!-- 定义事务传播属性 --> <props> <prop key="*save">PROPAGATION_REQUIRED</prop> <prop key="*remove">PROPAGATION_REQUIRED</prop> </props> </property> </bean> <bean id="autoproxy" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="beanNames"> <list> <value>*Service</value> </list> </property> <property name="interceptorNames"> <list> <value>transactionInterceptor</value> </list> </property> </bean>

    先写一个测试类,直接使用hibernate:

    public class Test_Hibernate {
    
        public static void main(String[] args) {
            SessionFactory factory = new Configuration().configure().buildSessionFactory();
            Session session = factory.getCurrentSession();
            Transaction tr = session.beginTransaction();
    //        add(session);
    ////        delete(session, 3);
    //        tr.commit();
    //        factory.close();
            select(session);
            tr.commit();
    //        factory.close();
            session = factory.getCurrentSession();
            session.beginTransaction();
            select(session);
            session.getTransaction().commit();
            factory.close();
        }
        
        static void add(Session session) {
            Qsource qsource = new Qsource();
            qsource.setUrl("http://www.baidu.com");
            session.save(qsource);
        }
        
        static void delete(Session session, long id) {
            Kind kind = (Kind) session.get(Kind.class, id);
            session.delete(kind);
        }
        
        static void select(Session session) {
            List<Qsource> list = session.createQuery("from Qsource").list();
            System.out.println(list.size());
        }
        
    }

    程序中查询了两次,在第一次和第二次查询之间插入断点,第一次打印结果后,直接往数据库中插入一条记录,再继续执行,发现结果是正常的。
    再写一个spring,hibernate的测试类:

    public class SpringHibernate_test {
    
        public static void main(String[] args) throws Exception {
            ApplicationContext ac = new FileSystemXmlApplicationContext("classpath:*-context.xml");
    //        GrabService ms = (GrabService) ac.getBean("grabService");
    //        GrabParam p = new GrabParam();
    //        p.setSingleUrl("http://www.xxsy.net/books/486729/5340636.html");
    //        ms.findSection(p);
            QsourceService qs = (QsourceService) ac.getBean("qsourceService");
    //        Qsource q = new Qsource();
    //        q.setUrl("aaaaaaa");
    //        qs.save(q);
            System.out.println(qs.getAll().size());
            System.out.println(qs.getAll().size());
        }
        
    }

    打印第一次结果后,直接往数据库中插入数据,再继续执行程序,第二次打印的结果和第一次相同,这是为什么呢?

    先看一下hibernate的配置,

            <property name="hibernate.current_session_context_class">
                thread
            </property>

    这个配置是说把session绑定到本地线程,不需要手动关闭,事务提交时自动关闭。
    再看spring配置的事务,只有save和remove结尾的程序才使用事务,看来问题就是在这了。事务没有提交,session没有关闭,一级缓存没有清除。

    把配置改一下

    <!-- 定义事务传播属性 -->
                <props>
                    <prop key="*save">PROPAGATION_REQUIRED</prop>
                    <prop key="*remove">PROPAGATION_REQUIRED</prop>
                    <prop key="export">PROPAGATION_REQUIRED</prop>
                    <prop key="getAll">PROPAGATION_REQUIRED</prop>
                    <prop key="find*">PROPAGATION_REQUIRED</prop>
                    <prop key="list*">PROPAGATION_REQUIRED</prop>
                </props>

    再测,正常

    虽然问题解决了,但是还有一些疑惑,直接调用hibernate时,如果不使用事务,程序会抛异常,使用spring的声明式事务后,为什么就不会报错,需要看源代码解决

  • 相关阅读:
    七种常用的特征工程
    Linux发邮件
    git提交的问题
    怎么在工作中快速学习,获得晋升?——吴军得到直播实录
    曾李青总结的创业的观点
    python解析json数据
    【基础算法整理】
    【剑指offer】连续子数组的最大和
    【剑指offer】最小的K个数
    【剑指offer】数组中出现次数超过一半的数字
  • 原文地址:https://www.cnblogs.com/yinkh/p/3335387.html
Copyright © 2020-2023  润新知