인프런 커뮤니티 질문&답변

sy k님의 프로필 이미지
sy k

작성한 질문수

자바 ORM 표준 JPA 프로그래밍 - 기본편

상속관계 매핑

Join 관련 테이블에 데이터 미반영 관련 질문드립니다

해결된 질문

작성

·

521

0

  • 아래 코드와같이 Inheritance strategy 설정 및 @DiscriminatiorColum 에노테이션을 추가하였습니다

  • (1) DB 결과를 보면 movie 테이블에 똑같은 데이터가 2번 저장됩니다("Create")임에도 불구하고

  • (2) movie.setDirector 등 관련 설정 데이터가 들어가지 않습니다

  • (3) DType 테이블이 생성되지 않습니다

    어떠한 이유 때문에 이문제가 발생하는지 잘 모르겠습니다

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn
public class Item {
    @Id
    @GeneratedValue
    private Long id;

    private String name;
    private int price;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }
}

 

package helloJpa;

import javax.persistence.Entity;

@Entity
public class Movie extends Item{
    private String director;
    private String actor;

    public String getDirector() {
        return director;
    }

    public void setDirector(String director) {
        this.director = director;
    }

    public String getActor() {
        return actor;
    }

    public void setActor(String actor) {
        this.actor = actor;
    }
}

 

public class JpaMain {
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();

        try{

            Movie movie = new Movie();
            movie.setDirector("Kim");
            movie.setActor("Brandon Grace");
            movie.setName("Saga of Wings");
            movie.setPrice(10000);
            em.persist(movie);

            em.flush();
            em.clear();

            Movie findMovie = em.find(Movie.class, movie.getId());
            System.out.println("findMovie =" + findMovie);

            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            em.close();
        }
        emf.close();
    }
}

 

 

`DB`

DB.png

답변 4

1

안녕하세요. sy k님, 공식 서포터즈 OMG입니다.
우선 코드 문제인지 아닌지 확인하기 위해 올리신 코드 기반으로 테스트해봤습니다.

패키지구조

image

Item.java

import javax.persistence.*;

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn
public class Item {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;

    private String name;
    private int price;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }
}

Movie.java


import javax.persistence.Entity;

@Entity
public class Movie extends Item{
    private String director;
    private String actor;

    public String getDirector() {
        return director;
    }

    public void setDirector(String director) {
        this.director = director;
    }

    public String getActor() {
        return actor;
    }

    public void setActor(String actor) {
        this.actor = actor;
    }
}

JpaMain.java

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

public class JpaMain {
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();

        try{

            Movie movie = new Movie();
            movie.setDirector("Kim");
            movie.setActor("Brandon Grace");
            movie.setName("Saga of Wings");
            movie.setPrice(10000);
            em.persist(movie);

            em.flush();
            em.clear();

            Movie findMovie = em.find(Movie.class, movie.getId());
            System.out.println("findMovie =" + findMovie);

            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            em.close();
        }
        emf.close();
    }
}

 

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>jpa-basic</groupId>
    <artifactId>ex1-hello-jpa</artifactId>
    <version>1.0.0</version>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.0</version>
        </dependency>

        <!-- JPA 하이버네이트 -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>5.4.13.Final</version>
        </dependency>

        <!-- H2 데이터베이스 -->
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.200</version>
        </dependency>


    </dependencies>
    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>
</project>

 

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2"
             xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
    <persistence-unit name="hello">
        <properties>
            <!-- 필수 속성 -->
            <property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
            <property name="javax.persistence.jdbc.user" value="sa"/>
            <property name="javax.persistence.jdbc.password" value=""/>
            <property name="javax.persistence.jdbc.url" value="jdbc:h2:tcp://localhost/~/jpa"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
            <!-- 옵션 -->
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.format_sql" value="true"/>
            <property name="hibernate.use_sql_comments" value="true"/>
            <property name="hibernate.hbm2ddl.auto" value="create" />
        </properties>
    </persistence-unit>
</persistence>

 

쿼리 로그

Hibernate:

drop table if exists Item CASCADE

Hibernate:

drop table if exists Movie CASCADE

Hibernate:

drop sequence if exists hibernate_sequence

Hibernate: create sequence hibernate_sequence start with 1 increment by 1

Hibernate:

create table Item (

DTYPE varchar(31) not null,

id bigint not null,

name varchar(255),

price integer not null,

primary key (id)

)

Hibernate:

create table Movie (

actor varchar(255),

director varchar(255),

id bigint not null,

primary key (id)

)

Hibernate:

alter table Movie

add constraint FK5sq6d5agrc34ithpdfs0umo9g

foreign key (id)

references Item

9월 23, 2022 8:34:31 오후 org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator initiateService

INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]

Hibernate:

call next value for hibernate_sequence

Hibernate:

/* insert Movie

*/ insert

into

Item

(name, price, DTYPE, id)

values

(?, ?, 'Movie', ?)

Hibernate:

/* insert Movie

*/ insert

into

Movie

(actor, director, id)

values

(?, ?, ?)

Hibernate:

select

movie0_.id as id2_0_0_,

movie0_1_.name as name3_0_0_,

movie0_1_.price as price4_0_0_,

movie0_.actor as actor1_1_0_,

movie0_.director as director2_1_0_

from

Movie movie0_

inner join

Item movie0_1_

on movie0_.id=movie0_1_.id

where

movie0_.id=?

findMovie =Movie@534180a2

 

h2

image

 

올리신 코드 중 다른 부분은 item클래스의 @GeneratedValue를 시퀀스로 지정한 것 외에는 동일합니다.

차이가 나는 부분은 두 가지 문제로 예상해 볼 수 있는데요

  1. test.mv.db 의 문제(기존에 생성하고 지우면서 발생한)

  2. 기타 다른 코드로 인한 문제

두 가지 예상되는 원인을 확인하기 위해서는 제가 진행한 것처럼

jpa.mv.db < 와 같이 새로운 데이터베이스 파일을 생성해서 실행 확인해주세요.

그래도 동일한 현상이 발생한다면, 기존 강의 프로젝트를 복사해서 백업해두고,

저처럼 3개의 클래스로만 확인해주세요.(DB파일도 초기화)


감사합니다.

0

sy k님의 프로필 이미지
sy k
질문자

jpa.mv.db 이 말씀이

persistence.xml에서 test 대신 jpa 로 적고, 연결시에도 jpa로 해서 연결을 해 보라는 말씀이실까요?

그렇게 연결했더니
Database "/Users/sungyoungkim/jpa" not found,
이렇게 db가 안만들어졌다는 메시지가 뜨면서 연결이 되지 않습니다

네, 맞습니다.

jpa.mv.db는 h2 초반 설정 강의를 참고하여 생성해주셔야합니다.

https://www.inflearn.com/course/ORM-JPA-Basic/unit/21684?tab=curriculum

1분부터 참고해주세요 tes로 생성&설정 하는 것 대신 jpa 생성&설정해서 확인해주세요

sy k님의 프로필 이미지
sy k
질문자

jpa 생성해서 main 함수 실행해보니 이번에도 MOVIE에 데이터가 들어가지 않습니다 ㅠㅠ
쿼리에도 null 값으로 들어가는데 이유를 모르겠네요 ㅠㅠ

값이 없어서 DROP TABLE MOVIE 로 테이블을 지우고 다시 돌리면 또 데이터가 들어가는데 그 이후에 다시 실행하면 데이터가 사라집니다 ㅠㅠ


Hibernate:

call next value for hibernate_sequence

Hibernate:

/* insert helloJpa.Movie

*/ insert

into

Item

(name, price, DTYPE, id)

values

(?, ?, 'Movie', ?)


image

그래도 동일한 현상이 발생한다면, 기존 강의 프로젝트를 복사해서 백업해두고,

저처럼 3개의 클래스로만 확인해주세요.(DB파일도 초기화)

sy k님의 프로필 이미지
sy k
질문자

OMG님 답변 너무나 감사합니다 ㅠㅠ

CREATE 대신에 UPDATE 를 하면 정상적으로 들어가기는 합니다 그런데 이상하게 ID 1번값의 MOVIE 만 안들어가는걸 발견했습니다

그래서 CREATE 를 해서 main 을 날리면 데이터가 안들어갔던것 같습니다
저렇게 최초 데이터가 유실되는 경우 어떤곳을 살펴 보아야 할까요?

영한 강사님 쿼리를 보니까 insert table 이라고 쿼리가 나가던데 저는 CREATE  로 main 함수를 실행해보면 alter 쿼리가 나가더라고요 그래서 update 로 바꾸어서 실행해보니 최초를 제외한 데이터는 저렇게 쌓이고 있습니다

image

  • 제가 올린 이미지처럼 item클래스에 @GeneratedValue(SEQUENCE)로 변경해주세요

  • 다른 테이블이 생성되지 않도록 @Entity는 Movie와 Item만 붙여주세요

  • 데이터베이스 초기상태로 확인해야합니다. jpa2를 만들고(create로 실행) 결과를 공유해주세요

 

sy k님의 프로필 이미지
sy k
질문자

https://www.inflearn.com/questions/17219

OMG님!! 문제 워인 찾았습니다! 게시판을 뒤져봤는데 이걸 왜 못봤나 싶네요 ㅠㅠ 구글링에서 인프런 질문 링크가 나와서 클릭해봤습니다 ㅎㅎ

버전 문제라고 합니다!

항상 답변 너무 감사드립니다 ㅠㅠ

포기하지 않고 계속 들을 수 있었던거 정말 OMG님 덕분입니다 ㅠㅠ

저도 확인 중 오류가 발생해서 위에 보시면

5.4.13으로 작성하신걸 보실 수 있으세요

image또한, DB를 새로 생성 요청 드린 것도 영한님 말씀과 같은 이유였구요

image

처음 댓글남기실 때는 h2에서 db파일의 확장자명과, h2의 db생성 방법 등 익숙치 않으셨지만

이번 질문을 통해 알아가셨다고 생각합니다. 이후 영한님 강의는 동일하게 진행되니 그 때는 더 수월하실꺼에요!

-

끝까지 포기하시지 않고 해결하려고 노력하셔서 해결가능했다고 생각합니다:)

이후 문제 발생 시 언제든 질문남겨주세요~

sy k님의 프로필 이미지
sy k
질문자

사랑합니다 ㅠㅠS2

0

sy k님의 프로필 이미지
sy k
질문자

뭐가 문제가 있는거 같긴합니다 ㅠㅠ DROP TABLE 해서 모두 다 지우고 실행해서 보면 최초값을 잘 나오는데

그 이후에 서버 타입을 CREATE 로 해서 실행하면 movie는 값이 아무것도 안나오네요 ㅠㅠ

0

sy k님의 프로필 이미지
sy k
질문자

jpa.mv.db 라는게 무슨 뜻 일까요?ㅠㅠ

그런데 일단 해결은 했습니다. .db  파일이 뭐지 몰라서 일단 DROP TABLE 로 다 지우고 실행시키니까 데이터가 정상입력됩니다!

무엇이 문제였을까요 ㅠㅠㅋㅋ

mv.db는 데이터베이스 파일입니다.

강의에서 생성한 test 데이터베이스가 test.mv.db입니다.

sy k님의 프로필 이미지
sy k

작성한 질문수

질문하기