Search code examples
springhibernatespring-boottransactional

Why controller has transaction when stream on collection


I don't know why when I change entity in controller it is saved in a database. It looks like the controller has a transaction. When I set the property in the for loop it's not saved in database.

my spring controller

  @RestController
    public class CartController {
        @Autowired
        DeliveryTypeRepository deliveryTypeRepository;

        @GetMapping("/cartStepTwoAction")
        public ModelAndView cartStepTwoAction() {
            List<DeliveryType> dtList = deliveryTypeRepository.findAll();
            dtList.stream().forEach(x -> x.setPriceBrutto(new BigDecimal(44)));
            // why dirty checking save change ?

            ...

            ModelAndView model = new ModelAndView();
            return model;
        }

    }

, and repository

 @Repository
    public class DeliveryTypeRepositoryImpl implements DeliveryTypeRepository {

        @PersistenceContext
        EntityManager em;

        @Override
        public List<DeliveryType> findAll() {

                    String sql = "SELECT e FROM DeliveryType e";
                    Query query = em.createQuery(sql);
                    return query.getResultList();
        }
    }

Solution

  • Spring Boot will automatically register an OpenEntityManagerInViewInterceptor when the following conditions are true:

    • you have a web application
    • you use JPA

    Both conditions are true in your case. This interceptor holds the entity manager open for the whole duration of a request. The auto configuration occurs in the class JpaBaseConfiguration.

    To disable that behavior, you need to configure the following property:

    spring.jpa.open-in-view=false