Spring Data 2.2.8은 DomainClassConverter가 죽었으므로주의

업데이트 정보



2020/07/24에 2.2.9가 출시되어 무사히 아래에서 설명하는 문제는 일어나지 않습니다.

소개



Spring Data에는 요청 매개 변수 (쿼리 문자열 또는 양식) 또는 @PathVariable로 id를 전달하면 도메인 객체를 검색하고 설정하는 DomainClassConverter라는 매우 유용한 기능이 있습니다.
htps : // / cs. sp 링 g. 이오 / sp 린 g - 타타 / j 파 / 도 cs / 2.2.8. Repease / Refue Rense / HTML / # 이것. 음 b. 바시 c

@PathVariable을 변환하는 예제
    @GetMapping("/users/{id}")
    public User show(@PathVariable("id") User user) {
        return user;
    }

그러나 버전 2.2.8에서는이 기능이 죽었습니다.
위의 예에 표시된 /users/1에 액세스하면 다음과 같이 500 오류가 발생합니다.
There was an unexpected error (type=Internal Server Error, status=500).
Failed to convert value of type 'java.lang.String' to required type 'com.example.demo.User'; 
nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'com.example.demo.User': no matching editors or conversion strategy found

덧붙여 제가 보고를 받은 것은 Spring Data JPA를 사용하고 있는 프로젝트에서 폼 제출(POST)이 죽는 상황이었습니다만, 이 경우, 폼에 메우고 있는 관련 오브젝트를 검색하려고 해 사망, 스테이터스 로 400이 반환되었습니다.

해결 방법



없습니다.
결함보고수정도 있습니다. 2.2.9에서는 이 문제가 발생하지 않습니다.

2.2.9가 출시 될 때까지 pom.xml을 괴롭히는 등 2.2.7로 되돌리십시오 (개인적으로 치명적이므로 일찍 출시되기를 바랍니다)

무엇이 문제인가?



2.2.8에 포함된 DomainClassConverter는 다음과 같은 수정을 한다.
Defer initialization of Repositories in DomainClassConverter.

결과적으로 2.2.7까지 앱이 시작될 때 수행 된 Converter 등록 프로세스

2.2.7의 DomainClassConverter
    public void setApplicationContext(ApplicationContext context) {

        this.repositories = new Repositories(context);

        this.toEntityConverter = Optional.of(new ToEntityConverter(this.repositories, this.conversionService));
        this.toEntityConverter.ifPresent(it -> this.conversionService.addConverter(it));

        this.toIdConverter = Optional.of(new ToIdConverter());
        this.toIdConverter.ifPresent(it -> this.conversionService.addConverter(it));
    }

2.2.8에서 지연이 실행되고,

2.2.8의 DomainClassConverter
    public void setApplicationContext(ApplicationContext context) {

        this.repositories = Lazy.of(() -> {

            Repositories repositories = new Repositories(context);

            this.toEntityConverter = Optional.of(new ToEntityConverter(repositories, conversionService));
            this.toEntityConverter.ifPresent(it -> conversionService.addConverter(it));

            this.toIdConverter = Optional.of(new ToIdConverter(repositories, conversionService));
            this.toIdConverter.ifPresent(it -> conversionService.addConverter(it));

            return repositories;
        });
    }
this.repositoriessetApplicationContext 메소드 위에 있는 getConverter 메소드가 불려 갔을 때 1에 지연 초기화되지만,
이미 이해할 것입니다 ...
아무도! ! getConverter 메소드를 호출하지 않는 것이다! ! !

어떻게든 호출하는 방법은 없는 것일까하고 한 시간 고민해도 해결할 수 없었기 때문에 최신이라고 수정되고 있는지 확인하면 처음에 꼽은 커밋을 발견했다는 오치입니다.

후기



그래서 이번에는 Spring Data의 수정에 의해 빠졌다는 이야기였습니다. 하나 버그를 고치면 다른 곳이 망가졌다는 상황이군요.
단지 지연 초기화를 도입한 커밋 자체는 로 되어 있어, 「테스트하지 않은 부분은 망가져도 모른다」라고 하는 것은 Spring과 같이 규모가 커져 오면 일어날 수 있는 것이다 라고 자계도 포함해 생각했습니다.


getConverter 메소드는 convert 메소드(이 메소드는 Spring의 핵심 기능)가 불려 갔을 때에 사용된다. 

좋은 웹페이지 즐겨찾기