论坛首页 Java版

问题:getHibernateTemplate().delete执行后,数据库记录依然在

浏览 2275 次
该帖已经被评为隐藏帖
作者 正文
最后更新时间:2006-10-19 关键字: getHibernateTemplate 删除失败
问题描述:
简单的SSH结构,已经生成了HBM和POJO,单元测试中调用AbstractHibernateDao(extends HibernateDaoSupport)执行CRUD,目前Junit单元测试绿灯通过,但检查控制台发现没有delete脚本输出,再检查数据库,记录依然在。

PS:我怀疑是delete后,session没有flush,在AbstractHibernateDao执行delete时候加了flush还是没有成功;

public class AbstractHibernateDao extends HibernateDaoSupport implements IDao
{
    ......
    public void delete(Object obj)
    {
        getHibernateTemplate().delete(obj);
        //getHibernateTemplate().flush();
    }
}


public class DaoTest extends AppContextTestCase
{
    public void testCRUD() throws Exception
    {
        try
        {
            // insert
            String szId = dao.insert(bbVo);
            
            // get by id
            BeanTmpVO slVo = (BeanTmpVO)dao.get(BeanTmpVO.class, szId);
            assertEquals(bbVo.getCorpName(),slVo.getCorpName());
            assertEquals(bbVo.getCorpHab(),slVo.getCorpHab());
            
            // update
            slVo.setCorpHab("dollar");
            dao.update(slVo);
            BeanTmpVO sllVo = (BeanTmpVO)dao.get(BeanTmpVO.class, szId);
            assertEquals("dollar",sllVo.getCorpHab());
            
            // list
            List allVos = dao.getAll(BeanTmpVO.class);
            assertTrue(allVos.size()>0);
            
            // delete
            dao.delete(BeanTmpVO.class, szId);
            
        }
        catch (RuntimeException e)
        {
            fail("fail test");
        }
        
    }
}


public class AppContextTestCase extends TestCase
{
    protected void setUp() throws Exception
    {
        super.setUp();
        context = new FileSystemXmlApplicationContext(springConfigFile);
        sessionFactory = (SessionFactory) context.getBean("sessionFactory");
        Session session = SessionFactoryUtils.getSession(sessionFactory, true);
        TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
    }

    protected void tearDown() throws Exception
    {
        SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager
                .unbindResource(sessionFactory);
        SessionFactoryUtils.releaseSession(sessionHolder.getSession(), sessionFactory);
        context = null;
        super.tearDown();
    }
}


实在不明白为什么单元测试代码没有执行下来,到底什么原因
   
最后更新时间:2006-10-19
不是同一个session
   
0 请登录后投票
最后更新时间:2006-10-19
to楼上,我认为是同一个session,继承AppContextTestCase即为了保证单元测试代码能够确保使用的是同一个session(类似于OpenSessionInViewFilter的效果);

我感觉是hibernate没有将session跟db同步,广在内存缓存中delete了;

我把我的完整的AppContextTestCase展现出来:
public class AppContextTestCase extends TestCase
{
    // 判断是否需要Hold Session,为了测试关联对象的Lazy Load,必须将之设置为true
    boolean bHoldSession = false;
    
    // spring配置文件
    protected String[] springConfigFile =
    { "/web/WEB-INF/classes/context/applicationContext-base.xml",
            "/web/WEB-INF/classes/context/applicationContext-frk.xml" };
    
    //spring context
    protected ApplicationContext context = null;
    
    // hibernate session factory
    protected SessionFactory sessionFactory = null;

    /*
     * (non-Javadoc)
     * 
     * @see junit.framework.TestCase#setUp()
     */
    protected void setUp() throws Exception
    {
        super.setUp();
        context = new FileSystemXmlApplicationContext(springConfigFile);
        if (bHoldSession)
        {
            sessionFactory = (SessionFactory) context.getBean("sessionFactory");
            Session session = SessionFactoryUtils.getSession(sessionFactory, true);
            TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see junit.framework.TestCase#tearDown()
     */
    protected void tearDown() throws Exception
    {
        if (bHoldSession)
        {
            SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);
            SessionFactoryUtils.releaseSession(sessionHolder.getSession(), sessionFactory);
        }
        context = null;
        super.tearDown();
    }
}


感觉是需要在tearDown中先flush一下,我试验一下
   
0 请登录后投票
最后更新时间:2006-10-19
有没有用OpenSessionInView?用的话是哪种?
如果设置的是false的话,你传入的obj可能是你上一个session里的,而你dao中的delete方法是会新打开一个session的,不仅删不掉,应该会报错。
如果设置成true则应该没这个问题
   
0 请登录后投票
最后更新时间:2006-10-19
抱歉,没看清楚;应该是一个session;不过没看到你dao获取的代码部分
   
0 请登录后投票
最后更新时间:2006-10-19
ok,问题解决了,确实是session没有flush的问题。我修改了单元测试的父类中的tearDown方法,把代码贴出来,供遇到同类问题的朋友参考;

    protected void tearDown() throws Exception
    {
        if (bHoldSession)
        {
            SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);
            sessionHolder.getSession().flush();
            SessionFactoryUtils.releaseSession(sessionHolder.getSession(), sessionFactory);
        }
        context = null;
        super.tearDown();
    }
   
0 请登录后投票
最后更新时间:2006-10-19
okokok 写道
有没有用OpenSessionInView?用的话是哪种?
如果设置的是false的话,你传入的obj可能是你上一个session里的,而你dao中的delete方法是会新打开一个session的,不仅删不掉,应该会报错。
如果设置成true则应该没这个问题


你说的是对的!

·如果bHoldSession设置为false,对于级联对象删除的时候,肯定会报告lazyinitialexception;
·如果设置为true,单元测试都能通过,但delete不生效,console没有delete脚本,导致他的原因是session最后没有flush。所以我在tearDown中增加了sessionHolder.getSession().flush()即OK了;

谢谢okokok!
   
0 请登录后投票
最后更新时间:2007-08-20
spring配置xml 代码
  1. <bean id="BaseManage"  parent="hotel_txProxyTemplate">  
  2.     <property name="target">  
  3.         <bean class="springTest.BaseManage">  
  4.             <property name="dao">  
  5.                 <ref bean="ADao" />  
  6.             </property>  
  7.             <property name="a1dao">  
  8.                 <ref bean="A1DAO" />  
  9.             </property>  
  10.         </bean>  
  11.     </property>  
  12. </bean>  
  13. <bean id="hotel_transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">  
  14.     <property name="sessionFactory">  
  15.         <ref local="sessionFactory" />  
  16.     </property>  
  17. </bean>  
  18.   
  19. <bean id="hotel_txProxyTemplate" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">  
  20.     <property name="transactionManager">  
  21.         <ref bean="hotel_transactionManager" />  
  22.     </property>  
  23.     <property name="transactionAttributes">  
  24.         <props>  
  25.             <prop key="save*">PROPAGATION_REQUIRED</prop>  
  26.             <prop key="new*">PROPAGATION_REQUIRED</prop>  
  27.             <prop key="remove*">PROPAGATION_REQUIRED</prop>  
  28.             <prop key="delete*">PROPAGATION_REQUIRED</prop>  
  29.             <prop key="del*">PROPAGATION_REQUIRED</prop>  
  30.             <prop key="modify*">PROPAGATION_REQUIRED</prop>  
  31.             <prop key="update*">PROPAGATION_REQUIRED</prop>  
  32.             <prop key="change*">PROPAGATION_REQUIRED</prop>  
  33.             <prop key="annual*">PROPAGATION_REQUIRED</prop>  
  34.             <prop key="merge*">PROPAGATION_REQUIRED</prop>  
  35.             <prop key="stat*">PROPAGATION_REQUIRED</prop>  
  36.             <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>  
  37.         </props>  
  38.     </property>  
  39. </bean>   
测试类
  1. BaseManage mag=null;   
  2. public void setUp() {   
  3.     super.setUp();   
  4.     mag = (BaseManage)super.ctx.getBean("BaseManage");   
  5. }   
  6. public void testB() {   
  7.     int i = 1000;   
  8.     while (i > 0) {   
  9.         A a = new A();   
  10.         AId aid = new AId();   
  11.         aid.setA1("11");   
  12.         aid.setA3("11");   
  13.         aid.setA4("11");   
  14.         a.setId(aid);   
  15.         mag.newA(a);   
  16.         mag.del(a);   
  17.            
  18.         i--;   
  19.     }   
  20. }  
manage
  1. private ADaoIF dao = null;   
  2.   
  3. public void del(A a) {   
  4.     dao.del(a);   
  5. };  
dao
  1.     public void del(A a) {   
  2.         super.getHibernateTemplate().delete(a);   
  3. //      super.getSession().flush();   
  4.     }  

 

对于楼主的问题我现在也是出现这个问题,数据库并没有删除掉数据。我这里有几个问题想请问各位网友。

1、我的spring 的事务配置没有错吧。

2、为什么同样是使用spring 的 HibernateTemplate ,save不需要commit,而del需要commit。或者说是flush(概念不太清楚)。

3、使用spring 的 HibernateTemplate 的del方法,与直接使用Hibernate serssion 的del方法,效率是一样的吗? (猜想在spring封装了hibernate 方法会比慢吧?)

4、在网络上看到使用spring 的 HibernateTemplate 有封装了session.flush(应该没记错),那为什么数据还是del不了(存在)。

   
0 请登录后投票
论坛首页 Java版

跳转论坛:
JavaEye推荐