Java에서 deep copy와 swallow copy

Choizz·2023년 6월 30일
0

Java

목록 보기
7/11

이번 포스팅은 프로젝트 중 발생한 문제를 해결하는 과정에서 알게된 deep copy(깊은 복사)swallow copy(얕은 복사)에 대해서 포스팅 해보겠습니다.


프로젝트 개발 중, 정기 결제를 개발해야 하는 상황에서 첫 번째 결제 때 사용한 order 객체를 그대로 복사해 첫 번째 order 객체와 동일한 order 객체의 정보를 이용하여 결제 요청을 보내야했습니다.

저는 처음에 첫 결제 때 사용한 order 엔티티를 가지고 와서 그대로 사용하려 했지만 에러가 발생했습니다.

org.hibernate.HibernateException: Found shared references to a collection

이러한 에러가 나서 찾아보니 특정 영속 객체에서 참고하고 있는 객체를 다른 영속 객체에 주입시킬 경우에 발생하는 에러인 것을 확인했습니다. 즉, 같은 엔티티를 영속화할 경우 에러를 발생시켰습니다.

그래서 동일한 order 엔티티를 사용하기 위해 deep copy를 해야한다는 것을 알게됐습니다.
(제가 처음 시도한 것은 swallow copy라고 볼 수 있을 것 같습니다.)


Swallow Copy(얕은 복사)

  • 얕은 복사의 경우 한 객체의 주솟값을 그대로 복사에서 사용합니다. 이러면 복사를 해도 참조하고 있는 값은 원본 객체와 복사 객체가 공유하게 됩니다.
  • Heap에 있는 객체 주소를 공유하다 보니 원본 객체나 복사 객체의 값을 변경할 경우 서로에게 영향이 가게 됩니다.
	Test test1 = new Test();
    Test testCopy = test1; // 얕은 복사

Deep Copy(깊은 복사)

  • 깊은 복사는 원본 객체가 가지고 있는 값들을 사용하여 새로운 객체를 만드는 것을 의미합니다.
  • Heap 메모리에 새로운 주솟값이 생성되는 것입니다.
  • 이렇게 되면, 원본 객체와 복사 객체는 서로의 값은 갖지만 독립된 객체로서 역할을 할 수 있습니다.
  • 저는 생성자를 활용하여 깊은 복사를 했습니다.
    public Order( Order origin ){
        this.name = origin.getName();
        this.address = origin.getAddress();
        this.detailAddress = origin.getDetailAddress();
        this.phone = origin.getPhone();
        this.subscription = origin.isSubscription();
        this.totalItems = origin.getTotalItems();
        this.totalPrice = origin.getTotalPrice();
        this.totalDiscountPrice = origin.getTotalDiscountPrice();
        this.expectPrice = origin.getExpectPrice();
        this.user = origin.getUser();
        this.itemOrders = origin.getItemOrders();
        this.orderStatus = OrderStatus.ORDER_SUBSCRIBE;
        this.totalQuantity = origin.getTotalQuantity();
    }

이러한 방식으로 생성자를 활용하여 처음에 객체의 값들을 복사해 새로운 order 객체를 생성했습니다.


배운점

  • Java에서 copy에 관한 개념에 대해 알게 됐습니다.
  • Jpa에서 같은 엔티티는 영속화 할 수 없다는 것 또한 알게됐습니다.

reference

profile
집중

0개의 댓글