Announcement Announcement Module
Collapse
No announcement yet.
getHibernateTemplate().delete errors Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • getHibernateTemplate().delete errors

    Hi

    I search the forums and example code on how to use getHibernateTemplate().delete(entity);, but could not find it. So here goes:

    I'm using LocalSessionFactoryBean, DriverManagerDataSource, and HibernateTransactionManager in pretty much the same configuration as the petclinic example app, and get a BatchUpdateException when i try to delete a db record using getHibernateTemplate().delete(theRecord);. The delete causes the database and session state to be unsynchronized. Is there a way to update the spring session state, or how should this kind of issue be solved, i.e. how am i supposed to delete records? Update and Add works fine.

    Any help appreciated!

    Configuration:
    Code:
      <bean id="dataSource" 
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName">
          <value>org.hsqldb.jdbcDriver</value>
        </property>
        <property name="url"><value>jdbc&#58;hsqldb&#58;db/logistics</value></property>
        <property name="username"><value>sa</value></property>
        <property name="password"><value></value></property>
      </bean>
    
    
      <bean id="sessionFactory"
        class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
        <property name="dataSource"><ref local="dataSource"/></property>
        <property name="mappingDirectoryLocations">
          <list>
            <value>WEB-INF/hibernate-mappings</value>
          </list>
        </property>
        <property name="hibernateProperties">
          <props>
            <prop key="hibernate.dialect">
              net.sf.hibernate.dialect.HSQLDialect
            </prop>
          </props>
        </property>
    
      </bean>
    
      <bean id="transactionManager"
        class="org.springframework.orm.hibernate.HibernateTransactionManager">
        <property name="sessionFactory"><ref local="sessionFactory"/></property>
      </bean>
    In the controller (extends SimpleFormController):
    Code:
    protected ModelAndView onSubmit&#40;HttpServletRequest request,
        HttpServletResponse response, Object command, BindException errors&#41;
        throws Exception
    &#123;
        String formCommand = request.getParameter&#40;"cmd"&#41;;
        UserListBean bean = &#40;UserListBean&#41;command;
        
        if&#40;formCommand.equals&#40;"deleteuser"&#41;&#41;
        &#123;
            String strUserId = request.getParameter&#40;"userId"&#41;;
            User user = this.userDao.getUser&#40;new Long&#40;strUserId&#41;&#41;;
    
            // Trying to synchronize bean with db, to no avail
            List users = bean.getUsers&#40;&#41;;
            users.remove&#40;user&#41;;
            bean.setUsers&#40;users&#41;;
            
            this.userDao.removeUser&#40;user.getUserId&#40;&#41;&#41;;
        &#125;
        return new ModelAndView&#40;this.getSuccessView&#40;&#41;, "users", bean&#41;;
    &#125;
    And in the dao (extends HibernateDaoSupport), this is where the exception is thrown:
    Code:
        public void removeUser&#40;Serializable userId&#41;
        &#123;
            getHibernateTemplate&#40;&#41;.delete&#40;getUser&#40;userId&#41;&#41;;
        &#125;
    Stacktrace excerpt:
    Code:
    2004-nov-11 12&#58;00&#58;04 net.sf.hibernate.JDBCException <init>
    ALLVARLIG&#58; Could not execute JDBC batch update
    java.sql.BatchUpdateException&#58; failed batch
            at org.hsqldb.jdbc.jdbcStatement.executeBatch&#40;Unknown Source&#41;
            at org.hsqldb.jdbc.jdbcPreparedStatement.executeBatch&#40;Unknown Source&#41;
            at net.sf.hibernate.impl.BatchingBatcher.doExecuteBatch&#40;BatchingBatcher.java&#58;54&#41;
            at net.sf.hibernate.impl.BatcherImpl.executeBatch&#40;BatcherImpl.java&#58;126&#41;
            at net.sf.hibernate.impl.SessionImpl.executeAll&#40;SessionImpl.java&#58;2421&#41;
            at net.sf.hibernate.impl.SessionImpl.execute&#40;SessionImpl.java&#58;2376&#41;
            at net.sf.hibernate.impl.SessionImpl.flush&#40;SessionImpl.java&#58;2240&#41;
            at org.springframework.orm.hibernate.HibernateAccessor.flushIfNecessary&#40;HibernateAccessor.java&#58;214&#41;
            at org.springframework.orm.hibernate.HibernateTemplate.execute&#40;HibernateTemplate.java&#58;177&#41;
            at org.springframework.orm.hibernate.HibernateTemplate.delete&#40;HibernateTemplate.java&#58;357&#41;
            at se.notitium.security.dao.hibernate.HibernateUserDao.removeUser&#40;Unknown Source&#41;
            at se.notitium.logistics.web.useradmin.UserListController.onSubmit&#40;Unknown Source&#41;
            at org.springframework.web.servlet.mvc.SimpleFormController.processFormSubmission&#40;SimpleFormController.java&#58;223&#41;

  • #2
    If my memory serves, the configuration sample for the petclinic doesn't define suppression methods as transactionnal. Can you post the AOP part of your configuration and check that you added (if missing) a <map entry="delete*"> which wrap the method with a transaction ?

    Olivier

    Comment


    • #3
      Hi, thanks for your reply! I'm not at all familiar with AOP/transaction support in Spring. I had to read on about AOP/transaction support, and added what i guess should be correct transaction management:

      Code:
        <bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
          abstract="true">
          <property name="transactionManager"><ref bean="transactionManager"/></property>
          <property name="transactionAttributes">
            <props>
              <prop key="insert*">PROPAGATION_REQUIRED</prop>
              <prop key="update*">PROPAGATION_REQUIRED</prop>
              <prop key="delete*">PROPAGATION_REQUIRED</prop>
              <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
            </props>
          </property>
        </bean>
        
        <bean id="userEditController" parent="baseTransactionProxy">
          <property name="target">
            <bean class="se.notitium.logistics.web.useradmin.UserEditController">
              <property name="userDao"><ref bean="userDao"/></property>
              <property name="formView"><value>userEditView</value></property>
              <property name="successView"><value>userEditView</value></property>
              <property name="validator"><ref local="userEditValidator"/></property>
            </bean>
          </property>
        </bean>
      Is that correct? It doesn't help though, throws the same exception.

      Comment


      • #4
        I think you still have one problem, the target you choose for applying the transactional interception. The target of your transactional proxy is the controller while it should be the dao itself !
        try to do something like

        Code:
        <bean id="userDAO" parent="baseTransactionProxy">
          <property name="target">
            <bean class="...yourDAO">
              ...
            </bean>
          </property>
        </bean>
        
        <bean id="userEditController" class="se.notitium.logistics.web.useradmin.UserEditController">
         <property name="userDao"><ref bean="userDao"/></property>
          <property name="formView"><value>userEditView</value></property>
          <property name="successView"><value>userEditView</value></property>
          <property name="validator"><ref local="userEditValidator"/></property>
        </bean>
        HTH

        Olivier

        Comment


        • #5
          Bliss!

          Changes:
          No transaction support at all, i removed the AOP (posted above) stuff, erased the db, and (just to be sure) restarted the computer. Started tomcat, had hibernate create the db tables, and it just works... The tables probably where inconsistent with hibernate. Bleargh, i want to know...but it's nice that it works.

          At least i got a gentle introduction to AOP. Thanks ojolly!

          Comment

          Working...
          X