프로그래밍n학습자료(2018~)/Hibernate

[Hibernate] 8. Hibernate(하이버네이트) 기타 등등

단세포소년 2018. 3. 8. 16:59
반응형

    기타

    Composite ID , Composite Primary Key

     

    복합키로 여러개의 컬럼이 하나의 Key 되는 형태이다.

     

    아래는 아파트 테이블로 /호수, 소유자 이름 컬럼을 갖는다. /호수가 Primary Key이다.

     

    APT_DONG APT_HO 복합키를 구성한다.

    CREATE TABLE `DB_TEST`.`Apartment` (

      `APT_DONG` INT NOT NULL COMMENT '',

      `APT_HO` INT NOT NULL COMMENT '',

      `APT_OWNER_NAME` VARCHAR(45) NULL COMMENT '',

      PRIMARY KEY (`APT_DONG`, `APT_HO`)  COMMENT '')

    ENGINE = InnoDB

    DEFAULT CHARACTER SET = utf8;

     

     

     

    @IdClass 방식

    • 식별자 클래스(IDClass) 맵핑클래스(Entity)클래스의 멤버변수명이 같아야 한다.
    • Serializable 인터페이스 구현해야함
    • equals(), hashCode() 구현해야함
    • 기본 생성자( Default Constructor) 구현해야함.

     

     

    맵핑 클래스

    package org.onecellboy.db.hibernate.table;

     

    import java.io.Serializable;

     

    import org.onecellboy.db.hibernate.table.Apartment_Embeddable.APT_PK;

     

    public class APT_PK_Idclass  implements Serializable{

            private static final long serialVersionUID = 1L;

            

            private int dong;

            private int ho;

            

            public APT_PK_Idclass() {

                    // TODO Auto-generated constructor stub

            }

            public APT_PK_Idclass(int dong, int ho)

            {

                    this.dong = dong;

                    this.ho = ho;

            }

            public int getDong() {

                    return dong;

            }

            public void setDong(int dong) {

                    this.dong = dong;

            }

            public int getHo() {

                    return ho;

            }

            public void setHo(int ho) {

                    this.ho = ho;

            }

            

            @Override

             public boolean equals(Object o) {

                    return ((o instanceof APT_PK) && dong == ((APT_PK)o).getDong() && ho == ((APT_PK) o).getHo());

                }

            @Override

             public int hashCode() {

                    return (int)(dong ^ ho);

             }

     

     

    }

     

     

     

    package org.onecellboy.db.hibernate.table;

     

    import java.io.Serializable;

     

    import javax.persistence.Column;

    import javax.persistence.Entity;

    import javax.persistence.Id;

    import javax.persistence.IdClass;

    import javax.persistence.Table;

     

    @Entity

    @Table(name = "Apartment")

    @IdClass(APT_PK_Idclass.class)

    public class Apartment_Idclass {

            

            

            

            @Id

            @Column(name="APT_DONG",columnDefinition="INT")

            private int dong;

            

            @Id

            @Column(name="APT_HO",columnDefinition="INT")

            private int ho;

            

            

            

            @Column(name="APT_OWNER_NAME",columnDefinition="VARCHAR(45)")

            private String owner_name;

     

     

     

            public int getDong() {

                    return dong;

            }

     

     

     

            public void setDong(int dong) {

                    this.dong = dong;

            }

     

     

     

            public int getHo() {

                    return ho;

            }

     

     

     

            public void setHo(int ho) {

                    this.ho = ho;

            }

     

     

     

            public String getOwner_name() {

                    return owner_name;

            }

     

     

     

            public void setOwner_name(String owner_name) {

                    this.owner_name = owner_name;

            }

            

            

    }

     

     

    위에서 보면 복합키를 정의한 APT_PK_Idclass 멤버변수 dong, ho Entity 클래스 Apartment_Idclass 복합키 컬럼과 맵핑되는 멤버변수 dong, ho 이름이 같다. 복합키를 @IdClass 맵핑하는 방식은 복합키 클래스와 Entity 클래스의 멤버변수명이 같아야 한다.

     

     

     

     

     

     

    테스트 코드

    package org.onecellboy.db.hibernate;

     

    import static org.junit.Assert.*;

     

    import java.io.File;

     

    import org.hibernate.Session;

    import org.hibernate.SessionFactory;

    import org.hibernate.Transaction;

    import org.hibernate.boot.MetadataSources;

    import org.hibernate.boot.registry.StandardServiceRegistry;

    import org.hibernate.boot.registry.StandardServiceRegistryBuilder;

    import org.junit.After;

    import org.junit.AfterClass;

    import org.junit.BeforeClass;

    import org.junit.Test;

    import org.onecellboy.db.hibernate.table.APT_PK_Idclass;

    import org.onecellboy.db.hibernate.table.Apartment_Embeddable;

    import org.onecellboy.db.hibernate.table.Apartment_Idclass;

     

    public class CompositeKeyIdclass {

            static SessionFactory sessionFactory = null;

            static StandardServiceRegistry registry = null;

     

            @BeforeClass

            public static void setUp()

            {

                    registry = new StandardServiceRegistryBuilder().configure(new File("./conf/hibernate/hibernate.cfg.xml"))

                                    .build();

                                    sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();

     

            }

            

            @AfterClass

            public static void setDown()

            {

                    sessionFactory.close();

            }

            

            @After

            public void testAfter()

            {

                    System.out.println();

                    System.out.println();

            }

            

            @Test

            public void test() {

                    Session session =null;

                    Transaction tx = null;

                    

                    System.out.println("======Insert TEST======");

                    session = sessionFactory.openSession();

                    tx = session.beginTransaction();

                    

                    Apartment_Idclass apartment1 = new Apartment_Idclass();

                    apartment1.setOwner_name("땅부자");

                    

                    // primary key 설정

                    apartment1.setDong(104);

                    apartment1.setHo(1303);

     

                    session.save(apartment1);

                    

                    

                    tx.commit();

                    session.close();

                    

                    

                    System.out.println();

                    System.out.println();

                    System.out.println("======Select TEST======");

                    session = sessionFactory.openSession();

                    tx = session.beginTransaction();

                    

                    APT_PK_Idclass apt_pk=new APT_PK_Idclass(apartment1.getDong(),apartment1.getHo());

            

                    Apartment_Idclass apartment2 =session.get(Apartment_Idclass.class, apt_pk);

                    

                    System.out.println("*** Dong = "+apartment2.getDong());

                    System.out.println("*** Ho = "+apartment2.getHo());

                    System.out.println("*** Owner = "+apartment2.getOwner_name());

                    

                    tx.commit();

                    session.close();

            }

     

    }

     

     

     

     

    결과

    ======Insert TEST======

    Hibernate: insert into Apartment (APT_OWNER_NAME, APT_DONG, APT_HO) values (?, ?, ?)

     

     

    ======Select TEST======

    Hibernate: select apartment_0_.APT_DONG as APT_DONG1_0_0_, apartment_0_.APT_HO as APT_HO2_0_0_, apartment_0_.APT_OWNER_NAME as APT_OWNE3_0_0_ from Apartment apartment_0_ where apartment_0_.APT_DONG=? and apartment_0_.APT_HO=?

    *** Dong = 104

    *** Ho = 1303

    *** Owner = 땅부자

     

     

     

     

     

     

     

    @Embeddable 방식

    idClass 방식과 비슷하나 멤버변수명이 동일하지 않아도 된다. @AttributeOverrides 통해 멤버변수와 컬럼을 맵핑할 있다.

    따라서 식별자 클래스를 여러 다른 Entity 에서 사용가능하다. 생각해보면 복합키는 하나의 테이블 아니라 foreign key등으로 여러 테이블에서 쓰인다.

     

    Embeddable 복합키, 복합 외래키에서 쓰이기 좋다.

     

     

     

    맵핑 클래스

    package org.onecellboy.db.hibernate.table;

     

    import java.io.Serializable;

     

    import javax.persistence.AttributeOverrides;

    import javax.persistence.AttributeOverride;

    import javax.persistence.Column;

    import javax.persistence.Embeddable;

    import javax.persistence.EmbeddedId;

    import javax.persistence.Entity;

    import javax.persistence.Table;

     

    @Entity

    @Table(name = "Apartment")

    public class Apartment_Embeddable {

            @Embeddable

            public static class APT_PK implements Serializable{

                    private static final long serialVersionUID = 1L;

                    

                    protected int dong;

                    protected int ho;

                    

                    public APT_PK() {

                            // TODO Auto-generated constructor stub

                    }

                    public APT_PK(int dong, int ho)

                    {

                            this.dong = dong;

                            this.ho = ho;

                    }

                    public int getDong() {

                            return dong;

                    }

                    public void setDong(int dong) {

                            this.dong = dong;

                    }

                    public int getHo() {

                            return ho;

                    }

                    public void setHo(int ho) {

                            this.ho = ho;

                    }

                    

                    @Override

                     public boolean equals(Object o) {

                            return ((o instanceof APT_PK) && dong == ((APT_PK)o).getDong() && ho == ((APT_PK) o).getHo());

                        }

                    @Override

                     public int hashCode() {

                            return (int)(dong ^ ho);

                     }

     

            }

     

            @EmbeddedId

            @AttributeOverrides(value = {

                            @AttributeOverride(name="dong", column=@Column(name="APT_DONG",columnDefinition="INT")),

                            @AttributeOverride(name="ho", column=@Column(name="APT_HO",columnDefinition="INT"))

                      })

            private APT_PK id;

            

            

            @Column(name="APT_OWNER_NAME",columnDefinition="VARCHAR(45)")

            private String owner_name;

     

     

            public APT_PK getId() {

                    return id;

            }

     

     

            public void setId(APT_PK id) {

                    this.id = id;

            }

     

     

            public String getOwner_name() {

                    return owner_name;

            }

     

     

            public void setOwner_name(String owner_name) {

                    this.owner_name = owner_name;

            }

            

            

            

            

    }

     

    위의 예제에서는 Embeddable 클래스를 Inner 클래스로 선언했다. Embeddable 클래스가 범용적으로 다른 곳에서도 사용된다면 외부로 빼주면 된다.

     

     

     

    설명

    코드

            @Embeddable

            public static class APT_PK implements Serializable{

                    private static final long serialVersionUID = 1L;

                    

                    protected int dong;

                    protected int ho;

    설명

    복합키는 Serializable, 직렬화 가능 클래스이다.

    복합키를 구성하는 컬럼의 데이터 형태에 맞추어 멤버변수를 정의해라.
     

     

    코드

                 @Override

                     public boolean equals(Object o) {

                            return ((o instanceof APT_PK) && dong == ((APT_PK)o).getDong() && ho == ((APT_PK) o).getHo());

                        }

                    @Override

                     public int hashCode() {

                            return (int)(dong ^ ho);

                     }

    설명

    equals() hashCode() 메소드는 복합키 비교에서 사용되므로 Override해주자.
     

    Composite-ID 경우 equals(), hashCode() override 하지 않는다면 아래와 같은 경고가 발생한다.

    1601 [WARN] RootClass: HHH000038: Composite-id class does not override equals(): ....

    1602 [WARN] RootClass: HHH000039: Composite-id class does not override hashCode(): .....

     

     

    코드

            @EmbeddedId

            @AttributeOverrides(value = {

                            @AttributeOverride(name="dong", column=@Column(name="APT_DONG",columnDefinition="INT")),

                            @AttributeOverride(name="ho", column=@Column(name="APT_HO",columnDefinition="INT"))

                      })

            private APT_PK id;

    설명

    복합키를 설정하는 부분이다.

    @AttributeOverride name 복합키 클래스의 멤버변수명이다.
    @Column name 실제 맵핑되는 테이블의 컬럼명이다.

    위의 예는 APT_PK클래스의 dong 멤버변수는 APT_DONG 컬럼과 맵핑, ho 멤버변수는 APT_HO 맵핑됨을 알려준다.

     

     

     

     

     

     

     

    테스트 코드

    package org.onecellboy.db.hibernate;

     

    import static org.junit.Assert.*;

     

    import java.io.File;

     

    import org.hibernate.Session;

    import org.hibernate.SessionFactory;

    import org.hibernate.Transaction;

    import org.hibernate.boot.MetadataSources;

    import org.hibernate.boot.registry.StandardServiceRegistry;

    import org.hibernate.boot.registry.StandardServiceRegistryBuilder;

    import org.junit.After;

    import org.junit.AfterClass;

    import org.junit.BeforeClass;

    import org.junit.Test;

    import org.onecellboy.db.hibernate.table.Apartment_Embeddable;

    import org.onecellboy.db.hibernate.table.Apartment_Embeddable.APT_PK;

     

    public class CompositePrimaryKey {

            static SessionFactory sessionFactory = null;

            static StandardServiceRegistry registry = null;

     

            @BeforeClass

            public static void setUp()

            {

                    registry = new StandardServiceRegistryBuilder().configure(new File("./conf/hibernate/hibernate.cfg.xml"))

                                    .build();

                                    sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();

     

            }

            

            @AfterClass

            public static void setDown()

            {

                    sessionFactory.close();

            }

            

            @After

            public void testAfter()

            {

                    System.out.println();

                    System.out.println();

            }

            

            @Test

            public void test() {

                    Session session =null;

                    Transaction tx = null;

                    

                    System.out.println("======Insert TEST======");

                    session = sessionFactory.openSession();

                    tx = session.beginTransaction();

                    

                    Apartment_Embeddable apartment1 = new Apartment_Embeddable();

                    apartment1.setOwner_name("땅부자");

                    

                    Apartment_Embeddable.APT_PK id=new Apartment_Embeddable.APT_PK(103, 1204);

                    apartment1.setId(id);

                    

                    

                    session.save(apartment1);

                    

                    

                    tx.commit();

                    session.close();

                    

                    

                    System.out.println();

                    System.out.println();

                    System.out.println("======Select TEST======");

                    session = sessionFactory.openSession();

                    tx = session.beginTransaction();

                    

                    Apartment_Embeddable.APT_PK apt_pk=new Apartment_Embeddable.APT_PK(apartment1.getId().getDong(), apartment1.getId().getHo());

                    

                    

                    Apartment_Embeddable apartment2 =session.get(Apartment_Embeddable.class, apt_pk);

                    

                    System.out.println("*** Dong = "+apartment2.getId().getDong());

                    System.out.println("*** Ho = "+apartment2.getId().getHo());

                    System.out.println("*** Owner = "+apartment2.getOwner_name());

                    

                    tx.commit();

                    session.close();

                    

                    

            }

     

    }

     

     

     

    결과

    ======Insert TEST======

    Hibernate: insert into Apartment (APT_OWNER_NAME, APT_DONG, APT_HO) values (?, ?, ?)

     

     

    ======Select TEST======

    Hibernate: select apartment_0_.APT_DONG as APT_DONG1_0_0_, apartment_0_.APT_HO as APT_HO2_0_0_, apartment_0_.APT_OWNER_NAME as APT_OWNE3_0_0_ from Apartment apartment_0_ where apartment_0_.APT_DONG=? and apartment_0_.APT_HO=?

    *** Dong = 103

    *** Ho = 1204

    *** Owner = 땅부자

     

     

     

     

     

     

    Composite Key Join(복합키 조인)/여러 컬럼 조인

    여러개의 컬럼으로 조인하고 싶을 경우

     

     

    일반적인 한개의 컬럼 조인의 경우 아래와 같다.

    @OneToMany(fetch=FetchType.EAGER, targetEntity=Users_Coupon.class, cascade=CascadeType.ALL)

    @JoinColumn(name = "uc_user_id", referencedColumnName="usr_id")

    private Set<Users_Coupon> Users_coupons;

     

     

    하지만 Composite Key Join 같은 여러 컬럼으로 조인하는 경우는 아래와 같다.

        @OneToMany(cascade=CascadeType.ALL)

        @JoinColumns ({

            @JoinColumn(name="parentCivility", referencedColumnName = "isMale"),

            @JoinColumn(name="parentLastName", referencedColumnName = "lastName"),

            @JoinColumn(name="parentFirstName", referencedColumnName = "firstName")

        })

        public Set<Child> children;

     

     

     

     

     

     

    MapsId ( EmbeddedId primary key, 복합키 관계)

    @MapsId 복합키 관계 설정시 사용된다.

     

    @MapsId 외래 키와 매핑한 연관관계를 기본 키에도 매핑하겠다는 뜻이다.

     

    말이 어려우니 예를들어 아래를 보자.

       // parent entity has simple primary key

     

        @Entity

        public class Employee {

           @Id long empId;

           String name;

           ...

        }

     

        // dependent entity uses EmbeddedId for composite key

     

        @Embeddable

        public class DependentId {

           String name;

           long empid;   // corresponds to primary key type of Employee

        }

     

        @Entity

        public class Dependent {

           @EmbeddedId DependentId id;

            ...

           @MapsId("empid")  //  maps the empid attribute of embedded id

           @ManyToOne(name="EMPLOYEE_ID")

             Employee emp;

        }

     

     

    @MapsId("empid") 복합키 DependentId 클래스의 "empid" 멤버변수명이다.

    @MapsId Composite Primary Key(Embeddable) 일부만 관계에서 사용될 해당 컬럼명만 명시하면 된다. 명시하지 않으면 전체가 사용된다.

     

    Dependent 테이블의 "EMPLOYEE_ID" 컬럼은 Employee 테이블의 기본키인 "empId" 참조한다. 이때 Dependent "EMPLOYEE_ID" 컬럼은 복합키의 요소이고 컬럼이 DependentId 클래스의 empid 변수와 맵핑됨을 알리는 것이다.

     

    @AttributeOverrides 없이도 복합키 클래스의 변수와 컬럼을 맵핑 시킬 있는 방식이다.

     

    필자는 보통 Embedded 대해 아래와 같이 명시적으로 맵핑한다. :

     @Entity

        public class Dependent {

           @EmbeddedId

           @EmbeddedId

            @AttributeOverrides(value = {

                            @AttributeOverride(name="name", column=@Column(name="NAME",columnDefinition="VARCHAR")),

                            @AttributeOverride(name="empid", column=@Column(name="EMPLOYEE_ID",columnDefinition="BITINT"))

                      })

         DependentId id;

     

     

     

     

     

     

     

     

    NamedNativeQuery or Subselect ( = logical view )

     

     

     

     

     

     

     

     

     

     

     

    MappedSuperclass

    참고 : https://www.concretepage.com/hibernate/example-mappedsuperclass-hibernate

    https://docs.jboss.org/hibernate/jpa/2.1/api/javax/persistence/MappedSuperclass.html

     

    공통적인 부모 맵핑 클래스를 만들고 이를 상속받아 확장하는 방법

     

    예를 들어 테이블이 lion, tiger 있다.

     

     

     

     

     

    Fetching Strategies ( 패칭 전략)

    참고 :

    https://www.mkyong.com/hibernate/hibernate-fetching-strategies-examples/

    http://www.javamakeuse.com/2015/03/tutorial-hibernate-4-subselect-fetching.html

     

    관계된 데이터(OneToMany 등등) 들을 가져올때 Join 사용할 것인지, subquery 사용할 것인지등 선택하는 것이다. 튜닝관련 옵션으로 상황에 따라 판단해서 결정하고 사용해야 한다.

     

     

     

     

     

     

     

     

    Paging(페이징, 원하는 지점에서 개수만큼 가져오기)

     

    데이터베이스마다 다르겠지만 Mysql 경우 limit 키워드를 이용하여 원하는 개수의 결과를 가져오는 방법이다.

     

    예제

    query = session.createQuery("SELECT sdt.id, sdt.name FROM Student sdt");

    query.setFirstResult(1);

    query.setMaxResults(3);

    setFirstResult() : 시작 지점이다. index 0부터 시작한다.

    setMaxResults() : 결과로 가져올 개수이다.

     

    위의 경우는 1부터 3 가져오라는 것이다.

     

     

     

    결과 쿼리

    select student0_.ID as col_0_0_, student0_.NAME as col_1_0_ from Student student0_ limit ?, ?

     

     

     

     

     

     

     

     

     

     

     

     

     

    Column Lazy Loading ( 컬럼 게으른(늦은) 불러오기 )

    https://vladmihalcea.com/the-best-way-to-lazy-load-entity-attributes-using-jpa-and-hibernate/

    @OneToMany .. 관계 맵핑시 Lazy Loading으로 부하를 줄이는 방법이 존재한다는 것을 알고 있다.

     

    Entity 맵핑시 하나의 컬럼에도 Lazy Loading 적용할 있다.

     

    컬럼에 Lazy Loading 적용해야하는 경우를 생각해보자.

    예를 들어 게시판을 만들었다고 하자. 제목, 글쓴이, 날짜, 내용의 컬럼이 존재할 게시판 목록 구성을 위해서는 내용은 일단 필요없다. 내용은 또한 데이터량이 많을 것이다. 이때는 내용을 Lazy Loading 처리하고 하나의 게시글을 요청하면 부하를 확실히 줄일 있다.

     

    그렇다면 컬럼에 대한 Lazy Loading 어찌 처리할까. OneToOne 관계를 이용하면 된다. 간략한 정보에 대한 맵핑클래스와 자세한 정보가 들어있는 맵핑클래스를 OneToOne 관계에 두고 Lazy Loading 하면 된다.

     

     

     

     

     

     

    UniqueContraint(유일성 제한)

    해당 annotation 맵핑 클래스를 통해 DB 스키마 생성을 위해 쓰인다.

     

    하나의 컬럼에 대한 Unique 보통 컬럼에 unique=true 통해 설정한다.

    @Column(name="PHONE_NUMBER",columnDefinition="VARCHAR(45)",unique = true)

    private String number;

     

     

     

    만약 다수의 컬럼에 대한 Unique 경우는 @Table에서 설정한다.

    @Table(

       name = "people",

       uniqueConstraints = {@UniqueConstraint(columnNames = {"name", "number"})}

    )

    경우 Constraint 명이 랜덤으로 자동으로 생성된다. ) uk_3rkljasdkljefkljdf

     

     

     

    만약 Constraint 대해 이름을 부여하고 싶다면 아래와 같이 하면 된다.

    @Table(

       name = "people",

       uniqueConstraints = {

         @UniqueConstraint(

            columnNames = {"name", "number"},

            name="uk_people_name_number")}

    )

     

     

     

    여러개의 Constraint 아래와 같다.

    @Table(

       name = "people",

       uniqueConstraints = {

         @UniqueConstraint(columnNames = {"name", "number"}),name="uk_people_name_number"},

         @UniqueConstraint(columnNames = "login_id")},

           

    )

    컬럼 하나에 대한 Unique 설정도 가능하다. : login_id

     

     

     

     

     

     

     

    @Formula(공식),  컬럼 연산(계산)하기,Subquery 넣기

    @Formula sql function 이용하여 원하는 하나의 column 수식을 이용하여 select 있다. select에서만 사용된다.

     

    주의할 것은 하나의 column 반환 있어야 한다. select 에서 반화되는 하나의 컬럼에 대한 수식이다.

     

    sql function 써야하는 경우 아주 유용하다.

     

    수식 :

    @Entity

    @Table(name="people")

    public class People {

     

            @Id

            @GeneratedValue(strategy=GenerationType.IDENTITY)

            @Column(name="PEOPLE_ID",columnDefinition="INT")

            private int id;

            

            @Column(name="PEOPLE_NAME",columnDefinition="VARCHAR(45)")

            private String name;

     

            @Formula( "upper( PEOPLE_NAME )" )

            private String upperName;

            

            public String getUpperName() {

                    return upperName;

            }

    (생략....)

    }

     

    @Formula 내에는 컬럼에 대한 수식을 넣으면 된다.(컬럼명이다. 멤버변수명이 아니다.)

     

     

     

    테스트

            Session session = sessionFactory.openSession();

            Transaction tx = session.beginTransaction();

     

            People people = session.get(People.class, select_id);

            System.out.println("*people.getUpperName : "+people.getUpperName());

     

            tx.commit();

            session.close();

     

    아래의 결과 이다.

    Hibernate: select people_bi0_.PEOPLE_ID as PEOPLE_I1_4_0_, people_bi0_.PEOPLE_NAME as PEOPLE_N2_4_0_, upper( people_bi0_.PEOPLE_NAME ) as formula0_0_ from people people_bi0_ where people_bi0_.PEOPLE_ID=?
    *people.getUpperName :
    JANE

    select 수식이 입력된 것을 있다.

     

     

     

     

     

    서브쿼리를 이용 아래와 같다.:

            @Formula( "( select Max(o.PEOPLE_ID) from people o)" )

            private int maxID;

            

            public int getMaxID() {

                    return maxID;

            }

    이런식으로 서브쿼리시에는 반드시 테이블에 alias 주어야한다. 또한 해당 서브쿼리의 반환은 1개여야 한다.

     

    결과

    Hibernate: select people_bi0_.PEOPLE_ID as PEOPLE_I1_4_0_, people_bi0_.PEOPLE_NAME as PEOPLE_N2_4_0_, ( select Max(o.PEOPLE_ID) from people o) as formula0_0_ from people people_bi0_ where people_bi0_.PEOPLE_ID=?

     

     

     

     

     

     

     

     

    Lazy Loading 주의점

    Lazy Loading Session Close()되기전에만 동작한다. 만약 Session Close() Lazy Loading 데이터에 접근을 한다면 아래와 같은 에러가 발생한다.

    org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: org.onecellboy.db.hibernate.table.People_Uni.clubs, could not initialize proxy - no Session

    at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:582)

    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:201)

    at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:145)

    at org.hibernate.collection.internal.PersistentBag.size(PersistentBag.java:261)

    at org.onecellboy.db.hibernate.OneToManyJoinTableUni.testPeople(OneToManyJoinTableUni.java:147)

    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

    at java.lang.reflect.Method.invoke(Unknown Source)

    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)

    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)

    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)

    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)

    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)

    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)

    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)

    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)

    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)

    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)

    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)

    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)

    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)

    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)

    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)

    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)

    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)

    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)

    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)

    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)

    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)

    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)

     

     

     


반응형