18

Spring Boot 1.3.1 の使用

@RestController がデフォルトで Transactionnal である理由がわかりません。ドキュメントでそう言っているものは見つかりませんでした。

以下のコントローラーのメソッド findOne() が Transactionnal であるという事実をプッシュする例:

@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 を発生させる必要がありますが、ここでは成功し、Author の選択をトリガーします。したがって、メソッド findOne はトランザクションのようです。Eclipse デバッガーを使用すると、補完的な選択をトリガーするのは実際にはこの行であると確信できます。しかし、なぜそのメソッドは transactionnal なのですか?

@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

何か案が ?

それが機能である場合、私はそれをオフにしたいのですが...

4

3 に答える 3

24

MirMasej の回答に加えて、もう 1 つありOpenEntityManagerInViewInterceptorます。次の条件が true の場合、 Spring Boot は自動的に を登録します。

  • あなたはウェブアプリケーションを持っています
  • JPAを使用します

あなたの場合、両方の条件が当てはまります。このインターセプターは、リクエストの全期間にわたってエンティティーマネージャーを開いたままにします。自動構成はクラスで行われますJpaBaseConfiguration

この動作が望ましくない場合は、次のプロパティを application.properties ファイルに追加できます。

spring.jpa.open-in-view=false

ところで。この動作はトランザクションから完全に独立しており、エンティティ マネージャーのライフサイクルにのみ関連しています。両方のトランザクションが同じ基になるエンティティ マネージャー インスタンスを持っている場合は、2 つの別個のトランザクションを持つことができ、LazyInitializationException はありません。

于 2016-01-06T21:29:03.983 に答える
1

@dunniの答えは絶対に素晴らしく、うまくいきます。私の場合、@Controllerから@Serviceのメソッドへの@Transactional処理の読み取り専用 JPA 操作の呼び出しでパフォーマンスが低下しましたが、@WebServlet から同じメソッドを呼び出すと、2倍の速さで処理されました。ただし、 @Controllerからspring.jpa.open-in-view=falseを設定すると、 @WebServletからと同じくらい速く処理されます

ただし、この意味でさらに、次のことを一元的に行うことができ、@Controllerから呼び出されたメソッドに@Transactionalでこのように注釈を付けて同じように機能します。例:

@GetMapping("/test")
@Transactional(propagation = Propagation.NEVER, readOnly = true)
public void test()
于 2021-12-16T13:00:17.533 に答える
0

1 対 1 の関係は、常に積極的にフェッチされます。メソッド名から判断するbook.getAuthor().getFirstname()と、 book->author と author->firstName はそのような関係です。 LazyInitializationException遅延コレクションでのみ発生します。

于 2016-01-06T20:02:14.477 に答える