Giter VIP home page Giter VIP logo

jpa-quickstart's Introduction

jpa-quickstart's People

Contributors

olivelover avatar

Watchers

 avatar  avatar

Forkers

ddangggoong

jpa-quickstart's Issues

Issue : DDL 실행시 의도치 않은 email컬럼 발생

DDL 실행시 의도치 않은 "email" 컬럼 발생

1. 발생한 문제

JPA 코드를 실행하는 도중 "Entity"에 명시하지 않은 "email"컬럼이 쿼리문에 발생하게 되었습니다.

// console

(...)
Hibernate: drop table if exists S_EMP CASCADE 
Hibernate: create table S_EMP (id bigint not null, DEPT_NAME varchar(255), email varchar(255), name varchar(255), salary double, START_DATE timestamp, title varchar(255), COMMISSION_PCT double, mailId varchar(255), primary key (id))
(...)
Hibernate: insert into S_EMP (COMMISSION_PCT, DEPT_NAME, mailId, name, salary, START_DATE, title, id) values (?, ?, ?, ?, ?, ?, ?, ?)
(...)
// Employee.java

package org.example.chapter02.biz.domain;

import lombok.Data;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;

@Data
@Entity
@Table(name = "S_EMP")
public class Employee {
    @Id
    private Long id;

    private String name;

    private String mailId;

    @Column(name = "START_DATE")
    private Date startDate;

    private String title;

    @Column(name = "DEPT_NAME")
    private String deptName;

    private Double salary;

    @Column(name = "COMMISSION_PCT")
    private Double commissionPct;
}

콘솔과 "Entity"를 비교하면 분명 "email"컬럼 생성은 의도 하지 않았습니다. 하지만 콘솔에는

Hibernate: create table S_EMP (id bigint not null, DEPT_NAME varchar(255), email varchar(255), name varchar(255), salary double, START_DATE timestamp, title varchar(255), COMMISSION_PCT double, mailId varchar(255), primary key

위와 같이 "email"컬럼이 생성됩니다. image

2. 시도

1. DROP TABLE

"이전에 DDL로 생성한 테이블 컬럼이므로 h2데이터 베이스에서 테이블스키마를 저장해두는 풀이 있기 때문에 의도치 않은 컬럼이 생기는 것일까?" 하는 가정을 하게되었습니다.

DROP TABLE을 시도 하였지만, 여전히 엔티티에서 정의하지 않은 "email"과 함께 DDL 실행됩니다.

2. 컬럼 필드 주석으로 추적하기

Employe 클래스의 멤버들을

@Id
private Long id;

위의 id만 두고 주석처리를 하고 다시 JPA로 INSERT를 시도하였습니다.

분명 id를 제외한 컬럼은 주석이지만 역시나 DDL은 "email"과 함께 다른 컬럼들도 생성하는 것을 확인하였습니다.

이는 Employee클래스를 올바르게 참조하는 것이 아니라는 의미입니다.

3. 원인 및 해결

도서를 보며 코드를 따라 작성할 때, 도서의 환경은 Eclipse이고, 저의 환경은 IntelliJ입니다. IntelliJ는 다수의 프로젝트 생성을 허용하지 않기 때문에 내부에 "chapter01", "chapter02"패키지로 관리하고 있었습니다.

// hibernate 실행 시 작성했던 "chapter01"의 EmployeeVO

package org.example.chapter01.hibernate;

import lombok.Data;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.sql.Timestamp;

@Data
@Entity
@Table(name = "S_EMP")
public class EmployeeVO {

    @Id
    private Long id;

    private String name;

    @Column(name = "START_DATE")
    private Timestamp startDate;

    private String title;

    @Column(name = "DEPT_NAME")
    private String deptName;

    private Double salary;

    private String email;
}

이곳에 "email"컬럼이 있습니다.

// JPA 실행시 작성한 chapter02 경로의 Employee 클래스

package org.example.chapter02.biz.domain;

import lombok.Data;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;

@Data
@Entity
@Table(name = "S_EMP")
public class Employee {
    @Id
    private Long id;

    private String name;

    private String mailId;

    @Column(name = "START_DATE")
    private Date startDate;

    private String title;

    @Column(name = "DEPT_NAME")
    private String deptName;

    private Double salary;

    @Column(name = "COMMISSION_PCT")
    private Double commissionPct;
}

두 코드 모두 @Entity어노테이션과 @Table(name = "S_EMP")어노테이션이 붙어 있는 공통점이 있습니다.

그렇다면 이렇게 추측해 볼 수 있습니다. "hibernate"에서 DDL을 수행할 때 @Entity을 우선적으로 확인하여 "Entity"의 대상으로 하고 @Table어노테이션의 테이블 명으로 DDL을 수행한뒤, 동일한 테이블 명에 대해서는 DDL을 수행 하지 않는 다는 것을 생각해 볼 수 있습니다.

매핑되는 테이블 명 달리하기
// "chapter01"의 테이블 명 변경

package org.example.chapter01.hibernate;

import lombok.Data;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.sql.Timestamp;

@Data
@Entity
@Table(name = "S_EMP_1")
public class EmployeeVO {

    @Id
    private Long id;

    private String name;

    @Column(name = "START_DATE")
    private Timestamp startDate;

    private String title;

    @Column(name = "DEPT_NAME")
    private String deptName;

    private Double salary;

    private String email;
}
// console

(...)
Hibernate: drop table if exists S_EMP CASCADE 
(...)
Hibernate: drop table if exists S_EMP_1 CASCADE 
Hibernate: create table S_EMP (id bigint not null, COMMISSION_PCT double, DEPT_NAME varchar(255), mailId varchar(255), name varchar(255), salary double, START_DATE timestamp, title varchar(255), primary key (id))
Hibernate: create table S_EMP_1 (id bigint not null, DEPT_NAME varchar(255), email varchar(255), name varchar(255), salary double, START_DATE timestamp, title varchar(255), primary key (id))
(...)
Hibernate: insert into S_EMP (COMMISSION_PCT, DEPT_NAME, mailId, name, salary, START_DATE, title, id) values (?, ?, ?, ?, ?, ?, ?, ?)
(...)

각기 다른 테이블이 생성되는 것을 알 수 있습니다.

image image

가정한 것에 의해 의도한대로 컬럼이 생성되었습니다.

Reader reader = Resources.getResourceAsReader("org/example/chapter01/mybatis/sql-map-config.xml")의 경로를 못찾는 문제

xml의 경로를 찾지 못하는 문제

Reader reader = Resources.getResourceAsReader("org/example/chapter01/mybatis/sql-map-config.xml");

디버깅 을 하다가 위 코드 부분에서 경로를 못찾는 문제가 있다는 것을 알게 되었습니다.

1. Try

오타 확인

JDBC에서 오타에 의해 실행이 안되었던 적이 있어 오타를 확인하여 몇가지의 오타를 고쳤지만, 여전히 동일한 오류가 발생하였습니다.

2. 원인

src
└── main
    ├── java
    │   └── org
    │       └── example
    │           └── chapter01
    │               └── mybatis
    │                   ├── EmployeeDAO.java
    │                   ├── EmployeeServiceClient.java
    │                   ├── EmployeeVO.java
    │                   ├── sql-map-config.xml
    │                   ├── s_emp-mapping.xml
    └── resources

org.example.chapter01.mybatis의 경로에 .xml파일도 같이 두었습니다. 이로 인한 경로설정이 제대로 되지 않은 것이 원인이었습니다.

3. 해결

src
└── main
    ├── java
    │   └── org
    │       └── example
    │           └── chapter01
    │               └── mybatis
    │                   ├── EmployeeDAO.java
    │                   ├── EmployeeServiceClient.java
    │                   ├── EmployeeVO.java
    └── resources
        └── org
            └── example
                └── chapter01
                    └── mybatis
                        ├── sql-map-config.xml
                        └── s_emp-mapping.xml

"IntelliJ IDEA"가 애플리케이션을 빌드할 때, 모든 리소스를 소스 경로에 상대적인 디렉토리 구조를 유지하면서 출력 디렉토리로 복사합니다. "IntelliJ IDEA" 에서는 아래의 형식은 기본적으로 리소스로 인식합니다.

  • .dtd
  • .jpeg
  • .properties
  • .gif
  • .jpg
  • .tld
  • .html
  • .png
  • .xml

참고 : IntelliJ 공식문서

.xml 파일을 클래스와 같은 경로에 두었기 때문에, 컴파일 시에 .java 파일이 .class로 변환되는 동안 .xml파일은 인식을 하지 못해 경로를 찾을 수 없었습니다. 즉, "IntelliJ"가 애플리케이션을 빌드 하는 과정에서 .xml 파일을 리소스로 인식하지 못하였습니다. 해당 파일을 resources에 위치 시킴으로써 해결 할 수 있었습니다.

IDE는 다 비슷한줄 알고 단순히 도서를 보며 따라해보고 있었는데 이번 시간을 통해 Eclipse와 IntelliJ의 빌드 방식에 차이가 있다는 것을 알게되었습니다.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.