Question

I'm working on a import module, where I'm reading from an excel file, fill the entities and save them.

Now my trouble is that I'm working with many entities and then i split the save on DB in three distinct methods.

This is my import method:

@Transactional(propagation = Propagation.REQUIRES_NEW)
private void readRowFromExcel(Row row){

    for(Row row : sheet){

        Customer customer = readCustomerFromExcel(row)
        CustomerDeatails customerDetails = readCustomerDetailsFromExcel(row)    

        customerService.save(customer,customerDetails);

        MyEntity myEntity = readMyEntityFromExcel(row);

        myEntityService.save(myEntity)

    }   


}

This is the save method in the customer service

@Transactional(propagation = Propagation.REQUIRED)
public void save(Customer customer, CustomerDetails customerDetails){

            customerRepository.save(customer);
            customerDatailsRepository.save(customer);

}

This is the save method in the myEntity service:

@Transactional(propagation = Propagation.REQUIRED)
public void save(MyEntity myEntity){

    myEntityRepository.save(myEntity)

}

Now my trouble is that if i get an exception on the following code line

MyEntity myEntity = readMyEntityFromExcel(row);

the entities customer and customerDetails are already persistent, while i should save only if everything works

My spring-context.xml

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="${db.driverClass}" />
        <property name="url" value="${db.connectionURL}" />
        <property name="username" value="${db.username}" />
        <property name="password" value="${db.password}" />
    </bean> 

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" 
        p:entityManagerFactory-ref="entityManagerFactory">
        <property name="persistenceUnitName" value="myUnit" />
    </bean>

    <!-- 
    <bean id="hibernateJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
        <description>Allow spring to configure hibernate specific settings</description>
    </bean>
     -->
    <bean id="eclipseLinkJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
    </bean>

    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        p:dataSource-ref="dataSource" 
        p:persistenceUnitName="myUnit"
        p:jpaVendorAdapter-ref="eclipseLinkJpaVendorAdapter">
        <property name="jpaPropertyMap">
            <map>
                <entry key="eclipselink.cache.shared.default" value="false" />
                <entry key="eclipselink.weaving" value="false" />
            </map>
        </property>
        <property name="loadTimeWeaver">
            <bean
                class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
        </property>
    </bean>

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

How can i do to solve it?

Was it helpful?

Solution

The solution is simple: you move the lines that read from excel before any DB persisting is made:

@Transactional(propagation = Propagation.REQUIRES_NEW)
private void readRowFromExcel(Row row){

    for(Row row : sheet){
        //Reading from Excel
        Customer customer = readCustomerFromExcel(row)
        CustomerDeatails customerDetails = readCustomerDetailsFromExcel(row);
        MyEntity myEntity = readMyEntityFromExcel(row);

        //DB persisting
        customerService.save(customer,customerDetails);
        myEntityService.save(myEntity)
    }   

}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top