jpa01. 엔터티

Entity Type

@Entity
@Getter @Setter
public class Account {
    @Id @GeneratedValue
    private Long id;

    private String username;
    private String password;
}

@Entity : DB의 Account 테이블에 매핑되는 클래스

@Id : Account 테이블의 PK에 매핑 (Entity는 고유 식별자를 가짐)

@GeneratedValue : Auto-Incresement 설정

@Culumn : 컬럼이라고 알려줌 (생략 가능)

 

EntityManager

@Component
@Transactional
public class JpaRunner implements ApplicationRunner {

    @PersistenceContext
    EntityManager entityManager;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        Account account = new Account();
        account.setUsername("keesun");
        account.setPassword("jpa");

        // 1번 방법
        entityManager.persist(account);

        // 2번 방법
        Session session = entityManager.unwrap(Session.class);
        session.save(account);
    }
}

 

@Entity

@Entity(name = "myAccount")
@Table(name = "myAccount")
public class Account {

}

@Entity(name = "myAccount") => 하이버네이트 JPA안의 객체에서 쓰는 이름. (별도로 설정하지 않으면 클래스의 이름과 동일하게 사용)

@Table(name = "myAccount") : DB의 테이블에 매핑되는 이름을 설정 (이 설정이 없으면 엔티티의 이름과 동일한 이름으로 설정됨.)

 

@Id

엔터티의 PK를 설정

 

@Id
private Long id;
@Id
private long id;

둘 중에 뭘 쓸까.

long의 경우, 0이 초기화 됨. -> 테이블에 id가 0인 레코드를 가진 어카운트와 새로 만든 어카운트(id=0)가 구분이 안됨.

Long의 경우, null로 초기화 됨. -> 테이블에 id가 0인 레코드를 가진 어카운트와 새로 만든 어카운트(id = null)가 구분이 됨

 

@GeneratedValue

@Id @GeneratedValue(strategy="AUTO")
private Long id;

strategy

  • SEQUENCE
  • TABLE
  • IDENTITY
  • AUTH (DEFAULT. 사용하는 DB에 따라 적절한 방법 선택)

 

@Column

Entity의 전역필드에는 @Column이 생략되어 있음.

@Column(nullable = false, unique = true)
private String username;

 

@Temporal

@Temporal(TemporalType.TIMESTAMP)
private Date created

JPA 2.1까지는 Date 써야함. (컨버터를 사용해서 LocalDate로 바꾸는 방법도 있긴 하지만 패스)

JPA 2.2부터 Java8의 LocalDate 사용 가능 (Hibernate 5.3 이상)

 

@Transient

@Transient
private String no;

해당 필드를 테이블의 컬럼으로 매핑하지 않음.

 
 

Value Type

다른 엔터티에 종속적인 타입.

 

Entity Type vs Value Type

  • PK가 있어야 하는가
  • 독립적으로 존재해야 하는가

 

Value Type은 pk가 없고 독립적일 필요도 없는 것들이다.

 

private Address address;

Address는 Entity Type이냐 Value Type이냐??

Address가 테이블로 뽑을만한 것이 맞는가? PK는 뭘로 할건데? 테이블로 뽑는건 아닌 것 같음.

 

@Embeddable

@Embeddable
public class Address {
    private String street;
    private String city;
    private String state;
    private String zipCode;
}

( @Column이 생략되어 있음 )

 

@Entity
public class Account {
    // ...

    @Embedded
    @AttributeOverrides({
            @AttributeOverride( name = "city", column = @Column(name = "home_city")),
            @AttributeOverride( name = "streat", column = @Column(name = "home_streat")),
            @AttributeOverride( name = "zipCode", column = @Column(name = "home_zip_code"))
    })
    private Address HomeAddress;

    @Embedded
    @AttributeOverrides({
            @AttributeOverride( name = "city", column = @Column(name = "office_city")),
            @AttributeOverride( name = "streat", column = @Column(name = "office_streat")),
            @AttributeOverride( name = "zipCode", column = @Column(name = "office_zip_code"))
    })
    private Address OfficeAddress;
}

 

결과

image

CREATE TABLE account (
    id int8 not null, 
    home_city varchar(255), 
    home_streat varchar(255), 
    home_zip_code varchar(255), 
    office_city varchar(255), 
    office_streat varchar(255), 
    office_zip_code varchar(255), 
    password varchar(255), 
    username varchar(255) not null, 
    primary key (id)
)

CREATE TABLE study (
    id int8 not null, 
    name varchar(255), 
    owner_id int8, 
    primary key (id)
)

ALTER TABLE IF EXISTS ACCOUNT
ADD CONSTRAINT UK_gex1lmaqpg0ir5g1f5eftyaa1 UNIQUE (username)

ALTER TABLE IF EXISTS study
ADD CONSTRAINT FK210g5r7wftvloq2ics531e6e4 
FOREIGN KEY (owner_id) REFERENCES account