2021년 1월 15일 금요일

@JsonIdentityInfo 사용시 주의점

Spring 에서 JPA 사용하며 JSON 으로 변환시
Domain 간 양방향 참조를 걸 경우가 있다.

이때 JSON 으로 변환 하며 무한 루프에 빠지는데
이를 방지 하기 위해 
예전 방식

@JsonManagedReference

@JsonBackReference

과 

요즘 방식

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id”)

을 쓰게 된다.


요즘 방식 @JsonIdentityInfo  의 경우 위 예제는 

id 로 중복을 방지하여 무한루프를 방지 하는데


한번의 변환에 같은 아이디가 존재 할 경우 JSON 변환을 하지 않는다.


무슨말이냐 하면..


JSON 변환 하는 과정에서 @JsonIdentityInfo  가 달려있는 도메인의 id 가 1개 이상 있으면 안된다는 것이다.

1개 이상 있으면 변환 과정중 1회 이상의 데이터는 변환하지 않는다.

해당 내용은 @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id”)

형태로 사용했을 경우이고

generator 를 변경하면 가능 할 것 같아 보이긴 한다.


그림으로 설명하기 귀찮아서 글로 적긴 했는데

아무튼 참고해라.



-- 추가 --

@JsonIdentityInfo 는 generator 별로 숫자, 문자, uuid 등으로 키를 생성하여

json변환 중 같은 키가 발견되면 같은 스코프 내에서는 표시 하지 않는다.


내 상황같은 경우를 잘 분석 해보니 데이터 루프 중 1depth 까지만 데이터를 표시하고 이하는 표시 하지 않는것을원한 것으로 분석 됐다.

이를 위해 위에서 언급 한 방식을 사용하지 않고

@OneToMany 어노테이션이 달린 List 데이터 필드 위에

@JsonIgnoreProperties 를 사용하여 해당 필드의 List 데이터 내에 

@ManyToOne 으로 설정 한 릴레이션에서 Json 편환을 하지 않도록 했다.

@JsonIgnoreProperties("auctionCase")

@OneToMany(mappedBy = "auctionCase", fetch = FetchType.LAZY)

private List<Research> research;



2020년 11월 2일 월요일

Spring boot 의 application.properties 사용방법

지금까지 spring boot 에서 application.properties 를 

사용해본 방법은 아래의 2 가지 상황이다.

  1. 서버의 환경 변수에 따른 dev, prd 등 의 능동적 적용
  2. 복수의 properties 파일을 적용

위에서 언급한 1,2번에 대한 사용 법을 안내 한다.

  • 서버의 환경 변수에 따른 dev, prd 등 의 능동적 적용
  • - 사용 이유 : 
    소스의 수정 없이 서버 인프라의 환경에 따라 application.properties 의 값을 적용하고자 할 경우

    - 방법 : 
    서버에서 VM argument 로 
    -Dspring.profiles.active=prd 와 같이 구동시 주입. 
    소스 상에서는  
    application-default.properties 
    application-prd.properties 
    와 같이  
    application-[값].properties 
    으로 구분함. 
    만약 구동 중  spring.profiles.active VM argument 값 없을경우 default 가 적용됨.

     

  • 복수의 properties 파일을 적용
  • - 사용 이유 : 
    패키지별 설정파일을 따로 분리하고자 하여 사용 하게 됨.

    - 방법 : 

     -Dspring.config.additional-location=classpath:config/*/ 

    위와같이 VM argument 적용하면 /src/main/resources/config/모든폴더/application.properties 를 찾아 적용한다. 

    이때 기존에 존재하던 classpath:application.properties 파일이 먼저 적용 되고 

    추가 파일은 override 되므로 참고하길 바란다.

     


     

     

      

    2020년 9월 24일 목요일

    SOAP 통신 주의할점. 아무리 봐도 왜 오류나는지 모른다면

    SOAP 통신을 Postman 혹은 curl 로 테스트를 해보고자 하였으나

    오류가 발생 하였다.

    Http header 와 body 를 아무리 보고 또 봐도 틀린게 없는데 왜 안되는걸까?

    왜지? 2일 정도를 보고 또 보다가 

    성공한 사람의 request 를 raw 데이터로 비교 해봐도 모르겠다 뭐지??

    이때 SOAP UI 테스트 툴로 테스트 하니 성공 함.

    기존 request 와 SOAP UI 를 사용한 request 의 다른점을 확인하기 위해 

    로컬에 네트워크 scanner 를 키고 캡쳐를 했다.

    postman 과 SOAP UI.

    결과는 환장 함.


    header 에 SOAPAction key 로

    Endpoint 에서 사용할 function 을 정의 하는데 

    - Postman  : FN_TEST

    - SOAP UI : "FN_TEST"

    맞다. 큰따움표다 ㅋ

    SOAPAction : "FN_TEST" 여야 하는것이었다.


    이게 SOAP 의 규약 인지 

    아니면 내가 진행 하는 프로젝트의 룰인지는 더 찾아봐야 하겠으나

    뭐니 이게...

    2020년 8월 3일 월요일

    JPA 메서드로 쿼리 생성시 주의 사항

    메서드로 쿼리를 만들다 보면 분명 정확하게 했는데 
    Unable to locate Attribute  with the the given name [] on this ManagedType []
    이런 오류를 뱉으면서 안될때가 있다.

    뭐 당연히 변수 명은 camelcase 로 정의 했을것이고
    method 에서는 대문자로 시작했지.

    Entity
    private String aTest;

    Repository
    private findByATest(String aTest);

    이렇게 하면 문제 없는거 아냐?

    문제 없을것 같지만 안된다

    문제의 원인은 
    위 Entity 에서 정의한 변수명 룰에 있다.
    첫 시작 소문자가 1자리면 안된다.

    예를 들어 
    Entity
    private String aaTest;

    Repository
    private findByAaTest(String aTest);

    로 수정 후 테스트 시 문제 없는것을 확인 했다.

    문제를 알았으니 왜 인지를 알아야 하는데
    아직 모르겠다.
    왜일까..

    이런 저런 정보를 보았을때 Java Bean naming conventions 에 영향을 받는것이 아닌가 싶다..


    -- 정리 --
    해당 문제를 피해갈수 있는 방법
    1. 변수의 시작을 무조건 소문자 한자리로 시작 하지 않는다.
        aTest => aaTest
    2. 룰에 맞지 않는 변태 같은 짓이지만 변수의 시작을 대문자로 바꾼다.
        aTest => ATest

    해당 문제가 발생 한 이유는
    Entity 에 테이블의 접두사 T 를 항상 붙였다.
    예를 들어 code 관련 테이블은 TCode
    이럴때 당연히 camelcase 로 변경 하면 tCode 인데 
    이것때문에 문제가 생겼다.

    우선 근본적인 원인을 찾기 전까지는 접두사 T 를 붙이는 짓은 피하자.

    2020년 3월 21일 토요일

    git submodule 사용시 참조

    project 를 git 에 등록해서 관리하는데
    해당 project 하위에 타 git project 를 등록해서 사용할 경우
    이를 지원 하기 위해 git submodule 을 쓴다.

    설명은 아래 블로그에.

    https://pinedance.github.io/blog/2019/05/28/Git-Submodule