728x90

들어가면서

Java에서 모든 객체는 기본적으로 Object 클래스를 상속하며, Object 클래스에는 equals()와 hashCode() 메서드가 정의되어 있습니다.

차이점

equals() 메서드는 객체의 동등성을 비교하고, hashCode() 메서드는 객체를 해시 테이블 등에 저장할 때 사용됩니다.

객체의 equals() 메서드를 오버라이딩하면, 두 객체의 동등성을 비교할 때 더욱 정확한 결과를 얻을 수 있습니다. equals() 메서드를 오버라이딩하지 않으면, 두 객체가 동일한 인스턴스인지만 비교하게 됩니다. 예를 들어, String 클래스의 경우, 문자열의 값이 같으면 두 String 객체는 동등한 것으로 간주됩니다. 하지만 String 객체의 equals() 메서드를 오버라이딩하지 않으면, 두 String 객체가 동등한지 여부를 확인하는 것이 불가능합니다.

hashCode() 메서드는 객체를 해시 테이블 등에 저장할 때 사용됩니다. 만약 두 객체가 equals() 메서드를 통해 동등하다면, 두 객체의 hashCode() 값도 동일해야 합니다. hashCode() 메서드를 오버라이딩하지 않으면, 객체의 메모리 주소를 기반으로 해시 코드가 생성됩니다. 하지만 같은 객체라도 프로그램의 실행 상황에 따라 메모리 주소가 달라질 수 있으므로, 이러한 방식으로 해시 코드를 생성하면 문제가 발생할 수 있습니다.

따라서, equals() 메서드와 hashCode() 메서드를 오버라이딩하여 객체의 동등성 비교와 해시 코드 생성을 정확하게 구현해야 합니다.

@equals와 @hashCode는 자바 어노테이션으로, 해당 메서드를 오버라이딩하겠다는 것을 나타냅니다. 이 어노테이션을 사용하면 개발자가 실수로 메서드를 오버라이딩하지 않는 경우를 방지할 수 있습니다.

객체의 equals() 메서드와 hashCode() 메서드를 오버라이딩하는 방법을 예시 코드로 보여드리겠습니다.

다음은 Student 클래스를 예시로 들어보겠습니다.

public class Student {
    private String name;
    private int age;
    private int studentId;

    // 생성자와 getter/setter 메서드는 생략

    @Override
    public boolean equals(Object obj) {
        if (obj == this) return true;
        if (!(obj instanceof Student)) return false;
        Student student = (Student) obj;
        return student.studentId == this.studentId;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + studentId;
        return result;
    }
}

위 코드에서 equals() 메서드는 학생의 학번(studentId)을 비교하여 두 객체가 동등한지 여부를 판단하도록 구현되었습니다. 또한, hashCode() 메서드는 학번(studentId) 값을 사용하여 해시 코드를 생성하도록 구현되었습니다.

만약 equals() 메서드와 hashCode() 메서드를 오버라이딩하지 않았다면, 두 학생 객체가 동등한지 여부를 확인하는 것이 불가능했을 것입니다.

Student student1 = new Student("John", 20, 1001);
Student student2 = new Student("Alice", 22, 1001);
boolean isEqual = student1.equals(student2); // true

위 코드에서 student1과 student2는 이름과 나이는 다르지만 학번이 동일합니다. 따라서 equals() 메서드를 오버라이딩하여 학번이 같은 경우 동등하다는 것을 정의하면, 두 객체가 동등하다고 판단됩니다.

hashCode() 메서드를 오버라이딩하지 않으면, 객체의 메모리 주소를 기반으로 해시 코드가 생성됩니다. 하지만 같은 객체라도 프로그램의 실행 상황에 따라 메모리 주소가 달라질 수 있으므로, 이러한 방식으로 해시 코드를 생성하면 문제가 발생할 수 있습니다. 따라서 hashCode() 메서드를 오버라이딩하여 학번(studentId) 값을 사용하여 해시 코드를 생성하도록 구현합니다.

Map<Student, String> map = new HashMap<>();
map.put(student1, "John");
map.put(student2, "Alice");
System.out.println(map.get(student1)); // John
System.out.println(map.get(student2)); // Alice

위 코드에서는 HashMap을 사용하여 학생 객체와 문자열 데이터를 저장하였습니다. HashMap은 객체의 해시 코드를 기반으로 데이터를 저장하므로, hashCode() 메서드를 오버라이딩하여 해시 코드를 정확하게 생성하는 것이 중요합니다. 따라서 위 코드에서는 학번(studentId)을 사용하여 해시 코드를 생성하도록 구현하였습니다.

결론적으로…

equals()와 hashCode() 메서드를 오버라이딩하여 객체의 동등성 비교와 해시 코드 생성을 정확하게 구현해야 합니다. @equals와 @hashCode 어노테이션을 사용하면 오버라이딩을 보다 쉽게 구현할 수 있습니다.


내저장소 바로가기 luxury515

728x90

JPA 패치 전략 (Fetch Strategy)이란?

JPA에서 패치 전략이란 연관된 엔티티를 조회할 때, 즉시 로딩(EAGER)과 지연 로딩(LAZY) 방식을 지정하는 것을 의미합니다.

  • EAGER (즉시 로딩)

즉시 로딩은 연관된 엔티티가 항상 같이 로딩되어 가져옵니다. 예를 들어, Member 엔티티와 Team 엔티티가 일대다 관계일 때, Member 엔티티를 조회할 때 연관된 Team 엔티티도 함께 조회합니다.

@Entity
public class Member {
    @Id
    @GeneratedValue
    private Long id;
    
    private String name;
    
    @ManyToOne(fetch = FetchType.EAGER)
    private Team team;
    
    // Getter, Setter
}

@Entity
public class Team {
    @Id
    @GeneratedValue
    private Long id;
    
    private String name;
    
    // Getter, Setter
}
  • LAZY (지연 로딩)

지연 로딩은 연관된 엔티티가 실제 사용될 때 로딩됩니다. 예를 들어, Member 엔티티와 Order 엔티티가 일대다 관계일 때, Member 엔티티를 조회할 때 연관된 Order 엔티티는 필요할 때 로딩됩니다.

@Entity
public class Member {
    @Id
    @GeneratedValue
    private Long id;
    
    private String name;
    
    @OneToMany(mappedBy = "member", fetch = FetchType.LAZY)
    private List<Order> orders = new ArrayList<>();
    
    // Getter, Setter
}

@Entity
public class Order {
    @Id
    @GeneratedValue
    private Long id;
    
    private String name;
    
    @ManyToOne
    private Member member;
    
    // Getter, Setter
}

내저장소 바로가기 luxury515

728x90

JPA 조인 전략 (Join Strategy)

JPA에서 조인 전략이란 상속 관계 매핑을 위한 전략으로, 부모 클래스와 자식 클래스를 각각 별도의 테이블로 만들고 조인(JOIN) 연산을 이용해 조회하는 방식입니다.

조인 전략 예시 코드

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Item {
    @Id
    @GeneratedValue
    private Long id;
    
    private String name;
    
    private int price;
    
    // Getter, Setter
}

@Entity
public class Book extends Item {
    private String author;
    
    private String isbn;
    
    // Getter, Setter
}

@Entity
public class Movie extends Item {
    private String director;
    
    private String actor;
    
    // Getter, Setter
}

위 코드에서 Item 클래스에 @Inheritance(strategy = InheritanceType.JOINED) 어노테이션을 추가하여 조인 전략을 사용합니다. Book 클래스와 Movie 클래스는 각각 Item 클래스를 상속받으며, 각각 자신만의 속성을 가지고 있습니다. 이 때, JPA는 각 클래스를 별도의 테이블로 생성하고, JOIN 연산을 이용해 조회합니다.


내저장소 바로가기 luxury515

728x90

JPA 맵핑 전략 (Mapping Strategy)

JPA에서 맵핑 전략이란 데이터베이스 테이블과 객체 간에 매핑하는 방식을 지정하는 것입니다.

맵핑 전략 종류

  1. 객체-관계 매핑 (ORM) : 객체를 테이블에 매핑하는 방식
  1. 클래스-테이블 매핑 : 클래스를 테이블에 매핑하는 방식
  1. 필드-컬럼 매핑 : 필드를 컬럼에 매핑하는 방식
  1. 기본 키 매핑 : 기본 키를 매핑하는 방식
  1. 연관관계 매핑 : 연관관계를 매핑하는 방식

맵핑 전략 예시 코드

@Entity
@Table(name = "MEMBER")
public class Member {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID")
    private Long id;
    
    @Column(name = "NAME")
    private String name;
    
    @ManyToOne
    @JoinColumn(name = "TEAM_ID")
    private Team team;
    
    // Getter, Setter
}

@Entity
@Table(name = "TEAM")
public class Team {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID")
    private Long id;
    
    @Column(name = "NAME")
    private String name;
    
    @OneToMany(mappedBy = "team")
    private List<Member> members = new ArrayList<>();
    
    // Getter, Setter
}

위 코드에서 @Entity, @Table, @Id, @GeneratedValue, @Column, @ManyToOne, @JoinColumn, @OneToMany 어노테이션 등을 이용해 각각의 맵핑 전략을 지정하였습니다.

  • 객체-관계 매핑 : @Entity 어노테이션
  • 클래스-테이블 매핑 : @Table 어노테이션
  • 필드-컬럼 매핑 : @Column 어노테이션
  • 기본 키 매핑 : @Id, @GeneratedValue 어노테이션
  • 연관관계 매핑 : @ManyToOne, @JoinColumn, @OneToMany 어노테이션


내저장소 바로가기 luxury515

'Back-end > JPA' 카테고리의 다른 글

JPA 패치전략  (0) 2023.04.13
JPA 조인전략  (0) 2023.04.13
JPA에서 Specification 사용해보기  (0) 2023.04.13
JPA 에서 복합키 를 사용하는 이유 ,구현 방법.  (0) 2023.04.11
JoinColumn vs MappedBy 에 관하여  (0) 2023.04.11

+ Recent posts