Announcement Announcement Module
Collapse
No announcement yet.
Rollback with AbstractTransactionalDataSourceSpringContextTests not working Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Rollback with AbstractTransactionalDataSourceSpringContextTests not working

    I have a project where several technologies are mixed together:
    Spring 2.5.4
    Hibernate 3.2.6.ga
    Maven2
    Groovy 1.5.6 (since 2 weeks now in my project)

    90% of the project is written in Java including all Beans and Daos and most of the services. Now i tried to write a service in Groovy which writes some testdata from a csv-file into the DB.

    After a few test-runs i realized that the AbstractTransactionalDataSourceSpringContextTests from which all my testclasses are derived from doesnt doesnt do the rollback on my groovy-service (which calls a Java-Dao).

    here is the code:

    service-class which does implement an corresponding interface written has this function:
    Code:
    void doImport(IDataReader reader, Map<Object, String> columnMapping){
    
            def csvDomainMapping = columnMapping;
            def meta = reader.getMetaData();
            
            //check if metadata fits
            if (! csvDomainMapping.every {entry -> meta.contains(entry.key) })
                throw new IllegalArgumentException("metadata from csv-file does not match csv-domain-Mapping");
    
            m_tx = m_txMgr.getTransaction(new DefaultTransactionDefinition());
                
                for (element in reader) {
                   
                    def tempDomain = domainObjectClass.newInstance();
    
                    element.each {entry ->
                        //do some reflection-stuff and fill tempDomain
                    }
                    tempDomain = dao.makePersistent(tempDomain);
                }
            m_txMgr.commit m_tx;
        }
    the testfunction
    Code:
    public void testDoImport() {
            Map<Object, Class> c = new HashMap<Object, Class>();
           //fill map
    
            IDataReader r = new CsvDataReader(csvFile, c);
    
            Map<Object, String> m = new HashMap<Object, String>();
           //fill map
    
            im.doImport(r, m);
        }
    the spring-context:

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <!--DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
            "http://www.springframework.org/dtd/spring-beans-2.0.dtd"-->
    
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:lang="http://www.springframework.org/schema/lang"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd">
    <import resource="classpath:connection.xml"/>
    .... other stuff ....
    <bean id="deplzlookupdao" class="uboot.dwh.dao.core.DePlzLookupDao">
            <property name="sessionFactory" ref="sessionFactory"/>
        </bean>
    <lang:groovy id="deplzimporter" script-source="classpath:uboot/dwh/service/DePlzImporter.groovy">
            <lang:property name="dePlzLookupDao" ref="deplzlookupdao"/>
            <lang:property name="m_sf" ref="sessionFactory"/>
            <lang:property name="m_txMgr" ref="transactionManager"/>
        </lang:groovy>
    now this code actually IS working, only the rollback after the junit-test is not. in all my other services written in Java the rollback is done so i suggest there must be something with groovy

    hope you guys can help me out

  • #2
    Well it looks quite obvious if you look at your code.

    Code:
    void doImport(IDataReader reader, Map<Object, String> columnMapping){
    
            def csvDomainMapping = columnMapping;
            def meta = reader.getMetaData();
            
            //check if metadata fits
            if (! csvDomainMapping.every {entry -> meta.contains(entry.key) })
                throw new IllegalArgumentException("metadata from csv-file does not match csv-domain-Mapping");
    
            m_tx = m_txMgr.getTransaction(new DefaultTransactionDefinition());
                
                for (element in reader) {
                   
                    def tempDomain = domainObjectClass.newInstance();
    
                    element.each {entry ->
                        //do some reflection-stuff and fill tempDomain
                    }
                    tempDomain = dao.makePersistent(tempDomain);
                }
            m_txMgr.commit m_tx;
        }
    The line in red is a commit, committed data cannot be rolled back. So WHY do you do a manual commit here or even better why do you do manual transaction management here?

    Comment


    • #3
      its because i read a file containing a huge amount of data. so not using transactions would imply doing a commit on every dao.makepersisten(..); which would slow down things. if this issue with rollback is solved i would do a flush every 100 saved items..

      The line in red is a commit, committed data cannot be rolled back.
      normally i would agree, but
      - this has to work, because otherwise how would you handle transactions in your application? well the AbstractTransactionalDataSourceSpringContextTests handles transactions on its own so i would not need it to do it here, but if you are not testing, where is the transaction-stuff done? i would really appreciate for some help here, because actually im not a pro with hibernate..

      - this allready works in plenty other service-classes with functions in the form of:
      prepare data
      open transaction
      do db-stuff
      commit

      and i really can see no difference except the choice of language

      Comment


      • #4
        I suggest you read the chapter about transactions in the spring reference guide. You don't want to do MANUAL transaction management. You want to CONFIGURE transactions. So it should be an configuration detail.

        Also transaction should be configured on your SERVICE layer not your DAO layer. You want your business method to be transactional not every call to a dao....

        And if you REALLY want to do some manual management I strongly recommend the usage of TransactionTemplate instead of working directly with the PlatformTransactionManager.

        Comment


        • #5
          Originally posted by Marten Deinum View Post
          Also transaction should be configured on your SERVICE layer not your DAO layer. You want your business method to be transactional not every call to a dao....
          thats what i do. the service holds the transaction and makes calls to the dao. after all calls are done, the transaction is committed...

          ok, will do that thx in the meantime!

          Comment


          • #6
            still no rollback

            i switched to declarative transactions. my service-function now looks like:
            PHP Code:
            @Transactional(readOnly falsepropagation Propagation.REQUIRED)
                
            void doImport(IDataReader readerMap<ObjectStringcolumnMapping){

                    
            def csvDomainMapping columnMapping;
                    
            def meta reader.getMetaData();
                    
                    if (! 
            csvDomainMapping.every {entry -> meta.contains(entry.key) })
                        throw new 
            IllegalArgumentException("metadata from csv-file does not match csv-domain-Mapping");

                        for (
            element in reader) {
                            
            def tempDomain domainObjectClass.newInstance();

                            
            element.each {entry ->
                                
            def propName csvDomainMapping[entry.key];

                                if (
            propName != null) {
                                    
            def val entry.value;

                                    
            tempDomain."${propName}val;
                                    
            tempDomain tempDomain;
                                }
                            }
                            
            tempDomain dao.makePersistent(tempDomain);
                        }

                } 
            dont wonder about the syntax. how i said its groovy - not java.

            my test written in java which still extends AbstractTransactionalDataSourceSpringContextTests:
            PHP Code:
            public void testDoImport() {
                    
            Map<Object, Class> = new HashMap<Object, Class>();
            .... 
            set up map....

                    
            IDataReader r = new CsvDataReader(csvFilec);


                    
            Map<ObjectString= new HashMap<ObjectString>();
            .... 
            set up map... 
                    
            im.doImport(rm);
                } 
            in my application-context i've set

            <tx:annotation-driven transaction-manager="transactionManager"/>

            which of course is a bit lazy :P but it should do the work.


            still this service is the only one which does not the rollback

            Comment


            • #7
              Found the error.

              It was simply that i forgot the invocation of the super-method here:

              PHP Code:
              @Override
                  
              public void onSetUp() throws Exception {
                      
              super.onSetUp(); <<---- this line was missing
                      csvFile 
              this.getApplicationContext().getResource("plz.csv").getFile();
                  } 
              really stupid error -_-

              thx anyway for your help!!

              Comment

              Working...
              X