DevKim

[02] Jpashop 실습하기 전, remind 본문

Spring Boot

[02] Jpashop 실습하기 전, remind

on_doing 2021. 7. 8. 17:30
728x90

[ Transaction remind ]

username과 id만 가지고 있는, 단순한 Member 객체를 만들고 Test code를 생성하여 돌려보았을 때

에러가 터졌다. 왜일까?

@RunWith(SpringRunner.class)
@SpringBootTest
class MemberRepositoryTest {

    @Autowired MemberRepository memberRepository;
    
    @Test
    public void testMember() throws Exception{
        //given
        Member member= new Member();
        member.setUsername("memberA");

        //when
        Long saveId = memberRepository.save(member);
        Member findMember = memberRepository.find(saveId);


        //then
        assertThat(findMember.getId()).isEqualTo(saveId);
        assertThat(findMember.getUsername()).isEqualTo(member);
    }
}

정답은 Transaction의 부재

Entity Manager을 통한 모든 데이터 변경은 항상 트렌젝션 안에서 실행되어야함을 잊지 말아야한다.

테스트 코드 실행시, 테스트에서는 자동으로 rollback이 되니, 실제 DB에 저장되는지를 확인하고 싶으면 rollback을 false로 설정해주자

 

* findMember == member : True

같은 영속성 컨텍스트에서는 id값이 같으면 엔티티 동일성을 보장해준다.


[ 간단 예제 ] 엔티티 분석

다음과 같이 엔티티가 설계되어있을 때, 눈 여겨볼 점은 카테고리와 아이템의 다대다 관계,

그리고 멤버와 Order의 양방향 연관관계이다.

1. 실무에서 다대다 연관관계는 풀어서쓰는 것이 좋으므로 중간에 연결 테이블을 생성하여 풀어내야한다.

2. Member 가 주문리스트를 가지고 있어야할 것 같지만, 사실상 그렇지 않다.

Member는 Order할 때 필요한 필터링될? 값일 뿐이다. 따라서 사실상 Member가 Order을 들고 있을 필요는 없다.

주문이 회원을 참조하는 것으로 충분하다.

 

* 테이블의 상속관계 매핑은 single table 매핑을 사용했다.


[ Entity 설계시 참고할 내용 remind ]

https://yeon-woo-kim.tistory.com/252?category=1194323 

 

[Tip] Entity 설계 시 주의할 점 & 참고할 점

1. 실무에서는 가급적 Getter은 열어두고, Setter은 닫아주자 - 실무에선 엔티티를 조회 할 일이 너무 많으므로, Getter의 경우엔 열어두는 것이 좋다. 단, Setter를 막 열어두면 나중에는 엔티티가 도대

yeon-woo-kim.tistory.com


[Enum Type 매핑시 주의사항]

@Enumerated(EnumType.STRING)으로 설정하기

*주의*

DB에 이름이 아닌 순서가 저장될 수 있으므로

ORDINAL 사용 금지!!!!!!!


[ 계층 구조 매핑 ]

ex. 카테고리 구조 

 

parent-child의 계층적인 관계에서,

child는 여러개의 카테고리를 가질 수 있고, parent는 하나의 child를 가지므로 다음과 같이 표현할 수 있다.

/**
* 자기 자신 매핑 ( 카테고리 구조 - 계층 구조 )
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id")
private Category parent;

@OneToMany(mappedBy = "parent")
private List<Category> child = new ArrayList<>();

[ 값 타입 주의사항 ]

 

JPA 스펙상, 엔티티나 임베디드 타입(@Embeddable)은 기본 생성자protected로 설정하는 것이 안전하고,

@Setter을 모두 지우고, 생성자를 만들어서 초기에만 세팅이 되도록 해주자

 

※ 임베디드 타입인 Address 리팩토링

@Embeddable
@Getter
public class Address {

    private String city;
    private String street;
    private String zipcode;

    protected Address()
    {
        
    }

    public Address(String city, String street, String zipcode) {
        this.city = city;
        this.street = street;
        this.zipcode = zipcode;
    }
}

 

728x90
Comments