I have simple code example with Spring Data:
Entity
@Entity
@Table(name = "car")
public class Car {
@Id
@GeneratedValue
private Long id;
private String name;
//...
}
Repository:
@Repository
public interface CarRepository extends JpaRepository<Car, Long> {
}
Service with example methods:
@Service
public class CarService {
@Autowired
private CarRepository carRepository;
public void change() {
Car one = carRepository.findOne(1L);
one.setName("changed"); //important
}
}
And controller:
@RestController("/")
public class CarController {
@Autowired
private CarRepository carRepository;
@Autowired
private CarService carService;
@GetMapping
public List<Car> home() {
carService.change();
List<Car> all = carRepository.findAll();
return all;
}
}
I also have data.sql with 3 records:
insert into car values (1, 'aaa');
insert into car values (2, 'bbb');
insert into car values (3, 'ccc');
When I send request to the localhost:8080 I get list with three cars, where the first one is updated:
insert into car values (1, 'changed');
insert into car values (2, 'bbb');
insert into car values (3, 'ccc');
My expectation is that after calling change() from controller actually nothing happens because this method is not transactional. So why my home() method in controller returns list with updated entity?
This question is completly different from this Spring data jpa @transactional I don't understand why you mark this as duplicate.
I assume, that you are using Spring Boot. If you use Spring Boot with Spring MVC and Spring Data, by default a Hibernate Session will be opened every time your controller methods receive a request. A Session provides a physical connectivity between your application and database. This functionality can be controlled with the spring.jpa.open-in-view
application property.
Car one = carRepository.findOne(1L); //1
one.setName("changed"); //2
List<Car> all = carRepository.findAll(); //3
return all;
First Level Cache
.Since the modified value is never flushed to the DB, after your controller call you can check your DB, and you will see, that the old value remained for your object, despite you received a different value in the controller response.
If you set the spring.jpa.open-in-view
property to false, your controllers will return the "correct" value.
According to the Spring Data documentation methods are transactional!
4.7. Transactionality
CRUD methods on repository instances are transactional by default. For reading operations the transaction configuration readOnly flag is set to true, all others are configured with a plain @Transactional so that default transaction configuration applies. For details see JavaDoc of SimpleJpaRepository.
Read the full documentation here: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With