Programming/Java

Java 객체 복사 Cloneable interface

Jan92 2021. 9. 16. 22:10

Cloneable interface

Java 객체 복사 Cloneable interface

 

카드 결제 내역을 기록으로 테이블에 남기던 중, 찾아서 적용한 방식입니다. 

이전에 성공 처리된 결제 내역에 대해서 취소 요청한 경우, 기존의 거래 기록 row는 그대로 두고, 다른 데이터는 같지만 state가 취소 요청인 새로운 row를 생성하여 저장해야 하는 상황에서 Cloneable interface를 적용하여 사용하였습니다.

 

 

@Builder
@Getter
@Setter
@NoArgsConstructor
@Entity
public class PaymentTransaction extends BaseEntity implements Cloneable {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long idx;
  
  .
  .
  .

  // 결제 요청에 따른 거래 고유 번호
  @Column
  private String transactionSeq;

  // 거래 상태 값 (0: 요청, 1: 성공, 2: 실패, 3: 취소 요청, 4: 취소 실패, 5: 취소 성공)
  @Column
  private String state = "0";

  @Override
  public Object clone() throws CloneNotSupportedException {
    return super.clone();
  }
}

(중간 내용을 생략한 PaymentTransaction Entity)

 

사용법은 Cloneable interface를 implements 하고 clone() 메소드를 오버라이드 합니다.

clone() 메서드는 상위 클래스 Object의 clone() 메서드를 리턴합니다.

 

* CloneNotSupportedException 처리가 필요합니다. 

 

 

 

* clone() 메서드에 대한 설명

 

Creates and returns a copy of this object. The precise meaning of "copy" may depend on the class of the object. The general intent is that, for any object x, the expression:

       x.clone() != x

will be true, and that the expression:

       x.clone().getClass() == x.getClass()

will be true, but these are not absolute requirements. While it is typically the case that:

       x.clone().equals(x)

will be true, this is not an absolute requirement.

By convention, the returned object should be obtained by calling super.clone. If a class and all of its superclasses (except Object) obey this convention, it will be the case that x.clone().getClass() == x.getClass().

 

 

 

PaymentTransaction transaction = new PaymentTransaction();
PaymentTransaction clonedTransaction = (PaymentTransaction)transaction.clone();

log.info(transaction.toString());          
log.info(clonedTransaction.toString());

// com.project.payment.api.entity.PaymentTransaction@164f8306
// com.project.payment.api.entity.PaymentTransaction@6b786d31

다음과 같이 clone() method를 통해 객체를 복사할 수 있습니다.

그리고 각각의 객체는 서로 다른 참조 값을 가진 다른 객체가 됩니다.

 

* 고려할 점은 clone() 하였을 때 Return Type이 Object 이기 때문에 해당 클래스로 캐스팅이 필요합니다.