Entity에 대해서 롬복 어노테이션인 @EequalsAndHashCode를 적용하게 되면 모든 인자값을 서로 비교하여 객체를 검사하기에

Id만 선택하여 @EquealsAndHashCode를 작성한다.

 

아래는 그와 관련된 간단한 예제 코드이다.

@Getter
@ToString
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(indexes = {
        @Index(columnList = "title"),
        @Index(columnList = "hashtag"),
        @Index(columnList = "createdAt"),
        @Index(columnList = "createdBy")
})
@Entity
public class Article {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Setter
    @Column(nullable = false)
    private String title;

    @Setter
    @Column(nullable = false, length = 1000)
    private String content;

    ...

	// AS-IS
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Article article = (Article) o;
        return Objects.equals(id, article.id);
    }


	// TO-BE
    // 객체 타입이 object 타입인지 확인한 후(instanceof) object를 비교할 객체 타입으로 
    // casting 하는 과정이 필요했는데 자바버전 14 이후로 그 과정이 없어졌고, 
    // scope 안에 참조변수를 넣을 수 있게 되었고 이를 Pattern variable이라 한다.
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Article article)) return false;
        return id != null && id.equals(article.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}

더 자세한 내용은 밸덩을 확인하길 바란다.

반응형

Java에서의 Optional <T>는 nullable 한 'T'타입을 감싸는 Wrapper 클래스공식 API문서에서 Note 형식으로

Optional은 기본적으로 "결과 없음"을 분명히 나타내야 할 필요가 있고 사용으로 인해 null 오류가 발생할 가능성이 있는 메서드 반환 유형으로 사용하기 위한 것입니다.

라고 쓰여있지만 사실 이 글만 봤을 때에 어떻게 써야 맞는 건지 혹은 내가 쓰고 있는 방식이 제대로 쓰고 있는 방식인지에 대해 의문점이 들기에 여러 자료 글들을 찾아봤으며 '26 Reasons Why Using Optional Correctly Is Not Optional' 라는 글을 찾게 되었으며 이를 공유하고 또 정리하고자 이 글을 쓰게 되었다.

// 1. Optional값의 초기값에 null을 할당하지 마라 

// AVOID
public Optional<Cart> fetchCart() {
    
    Optional<Cart> emptyCart = null;
    ...
}

// PREFER
public Optional<Cart> fetchCart() {

    Optional<Cart> emptyCart = Optional.empty();
    ...
}  

// 2. Optional.get()을 호출하기 전에 값을 가지고 있는지 먼저 체크해라

// AVOID
Optional<Cart> cart = ... ; // this is prone to be empty
...
// if "cart"is empty then this code will throw a java.util.NoSuchElementException
Cart myCart = cart.get();

// PREFER
if (cart.isPresent()) {
    Cart myCart = cart.get();
    ... // do something with "myCart"
} else {
    ... // do something that doesn't call cart.get()
}

// 3. 값이 없으면 Optional.orElse()를 통해 이미 생성된 기본 객체를 Set/Return한다

// AVOID
public static final String USER_STATUS = "UNKNOWN";
...
public String findUserStatus(long id) {

    Optional<String> status = ... ; // prone to return an empty Optional

    if (status.isPresent()) {
        return status.get();
    } else {
        return USER_STATUS;
    }
}

// PREFER
public static final String USER_STATUS = "UNKNOWN";
...
public String findUserStatus(long id) {

    Optional<String> status = ... ; // prone to return an empty Optional

    return status.orElse(USER_STATUS);
}

....
반응형

+ Recent posts