Использование Spring boot 1.3.1

Я не понимаю, почему @RestController по умолчанию является транзакционным. Я не нашел ничего такого в документации.

Пример, подтверждающий тот факт, что метод findOne () в контроллере ниже является транзакционным:

@RestController
@RequestMapping("/books")
public class BookController {

    @RequestMapping("/{id}")
    public Book findOne(@PathVariable Long id) {
        Book book = this.bookDao.findOneBookById(id);
        // following line
        // => triggers a select author0_.id as id1_0_0_ etc... // where author0_.id=?
        System.out.println(book.getAuthor().getFirstname()); 
        return book;
    }
}

Строка с System.out.println (book.getAuthor (). GetFirstname ()); должен вызвать LazyInitiaizationFailure, НО здесь он успешен и инициирует выбор автора. Таким образом, метод findOne кажется транзакционным. С отладчиком eclipse я могу быть уверен, что именно эта строка запускает дополнительный выбор. Но почему этот метод транзакционен?

@Configuration
@ComponentScan(basePackageClasses = _Controller.class)
@Import(BusinessConfig.class)
public class WebConfig extends WebMvcConfigurerAdapter {
   // ... here the conf to setup Jackson Hibernate4Module
}

@Configuration
@EnableAutoConfiguration
@EnableTransactionManagement
@EntityScan(basePackageClasses = _Model.class)
@ComponentScan(basePackageClasses = { _Dao.class })
public class BusinessConfig {
}

@SpringBootApplication
public class BookstoreStartForWebEmbedded {

    public static void main(String[] args) {
        SpringApplication.run(BookstoreStartForWebEmbedded.class, args);
    }

}

libs : 
spring-boot-starter 1.3.1.RELEASE
spring-boot-starter-test : 1.3.1.RELEASE
spring-boot-starter-valisation : 1.3.1.RELEASE
spring-boot-starter-web : 1.3.1.RELEASE
spring-boot-starter-data-jpa : 1.3.1.RELEASE
postgresql: 9.4-1206-jdbc41
querydsl-jps:3.7.0
jackson-annotations:2.6.4
jackson-datatype-hibernate4:2.6.4

Любая идея ?

Если это функция, я бы хотел ее отключить ...

12
Gauthier Peel 6 Янв 2016 в 22:57

2 ответа

Лучший ответ

В дополнение к ответам MirMasej есть еще одна вещь: Spring Boot автоматически зарегистрирует OpenEntityManagerInViewInterceptor при выполнении следующих условий:

  • у вас есть веб-приложение
  • вы используете JPA

Оба условия верны в вашем случае. Этот перехватчик удерживает диспетчер сущностей открытым на протяжении всего запроса. Автоконфигурация происходит в классе JpaBaseConfiguration.

Если вы не хотите такого поведения, вы можете добавить следующее свойство в свой файл application.properties:

spring.jpa.open-in-view=false

Кстати. это поведение полностью не зависит от транзакций, оно связано только с жизненным циклом менеджера сущностей. Вы по-прежнему можете иметь две отдельные транзакции и не иметь исключения LazyInitializationException, если обе транзакции имеют один и тот же базовый экземпляр диспетчера сущностей.

14
dunni 6 Янв 2016 в 21:29

Индивидуальные отношения всегда с нетерпением ждут. Судя по названиям методов book.getAuthor().getFirstname(), такими отношениями являются книга-> автор и автор-> firstName. LazyInitializationException будет выполняться только для ленивых коллекций.

0
MirMasej 6 Янв 2016 в 20:02