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.
- Should I also mark
read()method withTransactional(readOnly = true)? As it only performs read operations. - 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 - 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)
- Is it good to have @Transactional at both Service and Repository layer?