Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Data CrudRepository and Transactions

I'm trying to implement transactions on a CrudRepository Interface. I'm a beginner with this and my current problem is that when receiving a lot of requests from different clients, I'm sometimes getting a duplicate. To avoid that I wanted to use SQL Transactions and their implementation with Spring but I'm unable to get it working.

Here is how I've tried to do it :

@Repository
@EnableTransactionManagement
@Transactional
public interface ApplicationPackageDao extends CrudRepository<ApplicationPackage, Long> {

/**
 * Find if a record exists for this package name ,
 * @param packageName
 * @return
 */
@Transactional
ApplicationPackage findByPackageName(String packageName);

}

However it doesn't seem to work. I tried to add the @Transactionnal annotations earlier in the Java methods I'm calling but I can't get it working either.

How am I supposed to work with transactions on CrudRepository ? Or am I using completely the wrong thing?

like image 407
Jonathan Crégut Avatar asked Apr 14 '15 07:04

Jonathan Crégut


People also ask

How does Spring data JPA manage transactions?

Spring Boot and Spring Data JPA make the handling of transactions extremely simple. They enable you to declare your preferred transaction handling and provide seamless integration with Hibernate and JPA. The only thing you need to do is to annotate one of your methods with @Transactional.

Is CrudRepository transactional?

CRUD methods of CrudRepository are transactional by default. They are annotated with @Transactional annotation with default settings in implementation class at runtime.

Is CrudRepository transactional by default?

You are right. Only CRUD methods ( CrudRepository methods) are by default marked as transactional. If you are using custom query methods you should explicitly mark it with @Transactional annotation.


2 Answers

In addition to crm86's answer some more notes to the @Transactional annotation:

  • It seems to be best practice to annotate the entry points into your application (e.g. your web controller methods or the main method of a scheduled batch). By using the annotation attribute TxType you can ensure constraints/conditions in methods which are located deeper in your application (e.g. TxType.MANDATORY would throw if no trx-context is running, etc.).

  • The @Transactional annotation has only an effect if the class is loaded as spring bean (e.g. @Component annotation at class level).

  • Remember that only RuntimeException's lead to a rollback. If you want a checked Exception leading to a rollback you have to enumerate each such Exception by using the attribute rollbackOn.

  • The annotation at class level is valid for all public methods of this class. Method level annotations override those at the class level. The repeated annotation in your example above (first at class level, then at method level) has no effect.

like image 167
Heri Avatar answered Oct 20 '22 19:10

Heri


What I suggest:

Check your context and configuration classes with @Configuration annotation. From the documentation:

The @EnableTransactionManagement annotation provides equivalent support if you are using Java based configuration. Simply add the annotation to a @Configuration class

@EnableTransactionManagement and only looks for @Transactional on beans in the same application context they are defined in

Then you could use @Transactional in your service even in a method

Hope it helps

like image 3
crm86 Avatar answered Oct 20 '22 21:10

crm86