您的位置:首页 > 编程语言 > Java开发

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

2013-09-23 18:06 513 查看
这个问题已经很多天了,一直没有时间解决,不过还好是自己的项目,没什么影响。

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

hibernate主要配置如下:

<property name="hibernate.format_sql">true</property>
<property name="connection.url">
jdbc:mysql://localhost:3306/vipmf?autoReconnect=true&useUnicode=true&characterEncoding=utf-8
</property>
<property name="connection.username">root</property>
<property name="connection.password">123456</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="connection.autocommit">false</property>
<property name="show_sql">true</property>
<property name="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="hibernate.current_session_context_class">
thread
</property>
<property name="hibernate.cache.use_query_cache">
false
</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的声明式事务后,为什么就不会报错,需要看源代码解决
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐