I am using Spring data JPA's repository for my application. Currently I am using basic CRUD operations provided by default by spring data jpa repositories and for complex join queries, I am writing custom JPQL queries as follows:
public interface ContinentRepository extends JpaRepository<Continent, Long>
{
@Query(value = "SELECT u FROM Continent u JOIN FETCH ... WHERE u.id = ?1")
public List<Continent> findContinent(Long id);
}
In my Service class, I am autowiring this repository and performing DB operations.
@Service
public class MyService
{
@Autowired
public ContinentRepository cr;
public void read()
{
var result1 = cr.findContinent(1);
var result2 = cr.findContinent(2);
}
@Transactional
public void write()
{
var c = new Continent();
// setters
c = cr.save(c);
}
}
Currently I am just marking the write()
as org.springframework.transaction.annotation.Transactional
.
read()
method with Transactional(readOnly = true)
? As it only performs read operations.findContinent(Long id)
as Transactional(readOnly = true)? I read that all the default methods as marked as Transactional https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions
- Should I also mark read() method with Transactional(readOnly = true)? As it only performs read operations.
Not really necessary, however it might create some optimisations regarding cache memory consumption accordingly to this blog https://vladmihalcea.com/spring-read-only-transaction-hibernate-optimization/
- Should I also mark the findContinent(Long id) as Transactional(readOnly = true)? I read that all the default methods as marked as Transactional https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions
The same answer like in the first case
- In the repository interface, should I mark the Transactional annotation at the method level or at the interface level. (Also, I suspect most of the custom methods will be read only)
In general I added to the method level, because I have more control over the parameters like rollback
- Is it good to have @Transactional at both Service and Repository layer?
I recommend you to have at the Service level because, there, you can update many tables (so you can use many repositories), and you want your entire update to be transactional.
- Should I also mark read() method with Transactional(readOnly = true)? As it only performs read operations.
Yes. It is good practice, you will know immediately that this method doesn't change anything in database, and what is more important, you will disable some unintentional changes in database using this service method. If this method tries to do any update on DB exception will be thrown and rollback will be called.
- Should I also mark the findContinent(Long id) as Transactional(readOnly = true)? I read that all the default methods as marked as Transactional https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions
Depends how you are using it. If you are always calling this from @Sevice then no. I think that is common use case as fare as I know.
- In the repository interface, should I mark the Transactional annotation at the method level or at the interface level. (Also, I suspect most of the custom methods will be read only)
Same as 2.
- Is it good to have @Transactional at both Service and Repository layer?
Same as 2.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.