Spring JPA: Data not saved to Database when processing from an Async method

Viewed 5044

I have an app that uses Spring JPA and does some background processes using the @Async spring annotation. The process require saving the parameters in the database or if it already exist update the db.

This doesn't work fine as my data entity doesn't get persisted in the database after the @Async method is done. But when I removed the @Async annotation from the method, all things work fine. My data saved or updated to DB.

Does anyone have an idea what could be wrong or what I may be missing?

Thanks.

** UPDATE [CODE SAMPLE]

ASYNCSERVICE

@Service
@EnableAsync
class AsyncService() {
    @Async
    public void process(firstEntity, secondEntity) {
        firstEntity = prepareParams(firstEntity);
        secondEntity = prepareParams(secondEntity);
        save(firstEntity, secondEntity);
    }
}

ENTITYRELATIONSERVICE

@Transactional
@Service
class EntityRelationService() {

    private SecondEntityRepo secondEntityRepo;

    @Autowired
    public EntityRelationService(SecondEntityRepo secondEntityRepo) {
        this.secondEntityRepo = secondEntityRepo;
    }

    @Transactional
    public void save(p1, p2) {
        p2.setRelation(p1);

        this.secondEntityRepo(p2);
    }
}

BEAN CONFIG

@Bean
@Primary
@ConfigurationProperties(prefix = "app.database")
public DataSource dataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName(driver);
    dataSource.setUrl(url);
    dataSource.setUsername(username);
    dataSource.setPassword(password);
    return dataSource;
}

@Bean
@Primary
public LocalSessionFactoryBean sessionFactory() {
    LocalSessionFactoryBean sf = new LocalSessionFactoryBean();
    sf.setDataSource(dataSource());
    sf.setPackagesToScan("com.app");
    Properties props = new Properties();
    props.put("hibernate.use_sql_comments", false);
    props.put("hibernate.show_sql", true);
    sf.setHibernateProperties(props);
    return sf;
}

@Bean
public HibernateTransactionManager transactionManager() {
    HibernateTransactionManager transactionManager =
            new HibernateTransactionManager();
    transactionManager.setSessionFactory(sessionFactory().getObject());
    return transactionManager;
}
2 Answers

I had a similar issue: Whenever a method (A) throws an exception all changes are rolled back. Also all changes that happened inside other methods that were called from method (A) are rolled back.

My solution was to put the following annotation on a method where I was sure to always save the object no matter what happens elsewhere:

import org.springframework.transaction.annotation.Transactional;


@Transactional(propagation = Propagation.REQUIRES_NEW)
public void doStuff() {
...
}
Related