Spring

11. 값 타입과 불변 객체~

공대키메라 2021. 7. 21. 23:21

값 타입은 복잡한 객체 세상을 조금이라도 단순화하려고 만든 개념이다!

따라서 값 타입은 단순하고 안전하게 다룰 수 있어야 한다. 

 

코드를 예를 들어 설명해 보면

두개의 Member 가 하나의 address 를 참조하고 있는 상황인데

member1과 member2에 같은 address를 삽입하고 

member2의 address값을 바꾸면 오잉?

 

연결되어 있는 member1의 값도 바뀌게 된다.

 

기존의 의도는 member2에 저장된 address의 값만 바꾸고 싶었는데

member1도 바뀌는 버그가 발생하는 것이다!

 

복잡한 경우에는 이 오류를 찾기 정말 힘들다고 한다. 

 

이를 방지하기 위해서는 새로운 address객체를 하나 더 생성해서 그것을 이용해

member2의 값을 바꿔야 한다. 

package hellojpa;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

public class jpaMain {

    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

        EntityManager em = emf.createEntityManager();

        EntityTransaction   tx = em.getTransaction();
        tx.begin();

        try{

            Address address = new Address("city","street", 10000);

            Member member1 = new Member();
            member1.setUsername("member1");
            member1.setHomeAddress(address);
            em.persist(member1);

            Address copyAddress = new Address(address.getCity(), address.getStreet(), address.getZipcode());

            Member member2 = new Member();
            member2.setUsername("member2");
            member2.setHomeAddress(copyAddress);
            em.persist(member2);

            member1.getHomeAddress().setCity("newCity");

            tx.commit();

        }catch(Exception e){
            tx.rollback();
            e.printStackTrace();
        }finally{
            //code
            em.close();
        }

        emf.close();
    }

}

 

 

 

address의 setter를 전부 지우면 됨!

아니면 private으로 만들어버림!

 

그러면 선언하면 변경될 일이 없다!

 

그대신 통으로 바꿔 껴야 한다.