이슈 모음 (5) - JPA

jinvicky·2024년 1월 16일
0
post-thumbnail

Intro

jpa를 사용하면서 필요한 기능/변수들을 에러를 통해 배웠다.
내가 진행중인 개인 사이트는 crud 기본이기 때문에 도움이 될 거라고 생각한다.

@Transient

나는 프론트와 service 단까지는 vo, DB 쪽은 dto를 만들어서 사용하고 있는데 문제가 생겼다.

  • 상태코드값을 같이 프론트에 넘겨주고 싶다.
    (현재 상태코드만 디비에 저장하고 메세지는 Enum으로 저장중)
  • 디비 컬럼 외에도 계산된 컬럼들이 있어서 컬럼이 아닌 별도 iv들이 필요하다.

결국 디비 컬럼이 아닌 값을 담는 변수가 필요하다.
이럴 때 @Transient를 사용한다.

    @Column(name = "STATUS")
    private String status;

    @Transient
    private String statusNm;
    
    @PostLoad
    public void doLoad () {
        this.setStatusNm(GlobalCode.getDescByCode(this.getStatus()));
        this.setCmsTypeNm(GlobalCode.getDescByCode(this.getCmsType()));
    }

@PostLoad

디비에서 데이터를 로드하자마자 처리되는 부분이다.
해당 코드에 맞는 메세지를 가져와서 status Nm에 저장해서 프론트에서 처리할 필요없이 바로 보여주도록 처리했다.

GlobalCode.java

public static String getDescByCode(String status) {
        for (GlobalCode code : GlobalCode.values()) {
            if (code.getCode().equals(status)) {
                return code.getDesc();
            }
        }
        return null;
    }

@JsonIgnore

매핑을 진행하다보면 json어쩌고 에러들이 굉장히 자주 나오는데 해결은 간단하다. @JsonIgnore 어노테이션을 추가하면 된다.

@Entity
@Table(name="cms_aply")
@Getter
@Setter
public class CmsApplyDto {

    @Id
    @GeneratedValue(strategy = GenerationType.UUID)
    @Column(name = "ID")
    private String id;

    @ManyToOne(cascade = CascadeType.ALL)
    @JsonIgnore
    @JoinColumn(name = "CMS_ID", referencedColumnName = "ID")
    private CommissionDto cmsDto;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "MEM_ID", referencedColumnName = "ID")
    private MemberDto memberDto;

    @OneToOne(mappedBy = "applyDto")
    private CmsPayDto cmsPayDto;

커미션 신청 DTO는 위와 같이 회원, 결제, 커미션과 연동되어 있다.
알아보기로는 @OneToMany보다 @ManyToOne을 사용하라고 한다. 하지만 일단 연습이니 이것저것 써보기로 한다.

커미션당 커미션 신청 건들을 가져와서 상태가 "신청중" 인 건의 cnt와 예약중인 건의 cnt를 가져오려면 어떻게 해야 할까?

제일 먼저 @ManyToOne을 시도해 보았다.

포인트

  • @OneToMany의 대상은 컬렉션 타입일 것
    (n개가 올 테니 그냥 객체로는 당연히 안된다;;)
  • FetchType.LAZY일 경우 에러가 난다고 한다.

참고 https://minni7.tistory.com/98
대충 위 블로그에서 말하는 에러가 발생했었고, 주의하는 것이 좋겠다. LAZY를 쓸 경우 필요시에 조회를 해서 생기는 이슈라고 함.

그렇게 해서 cms/list를 조회하면

이런 식으로 List<CmsApplyDto>가 따라온다.
실제로는 특정 상태의 count가 필요한 것이기에 @Formula를 사용해 보았다.
CommissionDto.java

	@Formula("select count(*) from cms_aply where cms_id = id and status = 'CM02'")
    private Long prsCnt;

	@Formula("select count(*) from cms_aply where cms_id = id and status = 'CM08'")
    private Long rsvCnt;

JpaRepository CRUD

findBy, containning 등의 조합을 사용해서 직접 쿼리를 짜지 않아도 편히 조회가 된다는 장점이 있지만

  1. dto의 iv에 _를 사용하면 안된다.

    No Property Found for Type ~

위처럼 _가 들어가면 인식을 못한다... 그래서 명명규칙을 카멜케이스로 변경했다.
실제로 아래의 Sort.by()를 했을 때 reg_date를 인식 못해서 바꿔야 했다.

List<CmsApplyDto> list = repository.findAll(Sort.by("regDate"));
profile
Front-End와 Back-End 경험, 지식을 공유합니다.

0개의 댓글