Hibernate (5.2.2)의 상속 전략 "table per subclass"에 문제점이 있습니다. 매핑최대 절전 모드. 게으른 로딩 콜렉션의 데카르트 제품
클래스 (gettters 및 호텔은 나열되지 않습니다) :
//Class with shared fields
@MappedSuperclass
public class DBObject {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
protected Integer id;
@Column(name = "correctdt")
@Temporal(TemporalType.TIMESTAMP)
protected Date correctDate;
@Override
public boolean equals(Object o) {
boolean result = false;
if (o != null && (o instanceof DBObject)) {
DBObject oo = (DBObject) o;
if (id != null) {
result = id.equals(oo.id);
}
}
return result;
}
@Override
public int hashCode() {
return (id != null) ? id.hashCode() : 0;
}
}
//Class with a collection of items with inheritance.
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "tmp_test_class")
public class TestClass extends DBObject implements Serializable{
@OneToMany(mappedBy = "testClass")
protected Collection<TestParent> tests = new ArrayList<>();
}
//Parent class
@Entity
@Table(name = "tmp_test_parent")
@Inheritance(strategy = InheritanceType.JOINED)
public class TestParent extends DBObject implements Serializable{
@Column
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "test_id")
protected TestClass testClass;
}
//Subclass
@Entity
@Table(name = "tmp_test_child1")
public class TestChild extends TestParent{
@Column
private String field1;
}
컬렉션 TestClass
비만에서 tests
가 데이터베이스에서로드 할 경우에만 접근이 (게으른 로딩).
TestClass
을로드 한 후 콜렉션에 액세스 할 때 테이블간에 연결이없는 데카르트 제품과 함께 구성된 sql-query (LEFT OUTER JOIN
제외).
SELECT tests0_.test_id AS test_id4_2_0_,
tests0_.id AS id1_2_0_,
tests0_.id AS id1_2_1_,
tests0_.correctdt AS correctdt2_2_1_,
tests0_.name AS name3_2_1_,
tests0_.test_id AS test_id4_2_1_,
tests0_1_.field1 AS field1_0_1_,
CASE
WHEN tests0_1_.id IS NOT NULL
THEN 1
WHEN tests0_.id IS NOT NULL
THEN 0
END AS clazz_1_
FROM tmp_test_parent tests0_,
tmp_test_child1 tests0_1_
WHERE tests0_.test_id=?
FetchType = EAGER
으로 설정하면 수집이 올바르게로드됩니다. 그러나 컬렉션이 대부분의 경우 필요하지 않으므로 요청시로드해야합니다. 상속 클래스
테이블 :
표 tmp_test_parent
(3 기록)
"ID" "NAME" "TEST_ID" "CORRECTDT"
1 "11" 1 14.09.16 12:31:40
2 "22" 1 21.09.16 12:31:46
3 "33" 1 21.09.16 12:31:51
표 tmp_test_child
(2 개 기록) 시험에
"ID" "FIELD1" "CORRECTDT"
1 111 21.09.16 12:32:26
3 333 21.09.16 12:32:28
등급 :
//Class for testing
public class MainClass {
public static void main(String[] args) throws Exception {
Session session = HibernateSessionFactory.getSessionFactory().openSession();
//Loading class, that contains collection
TestClass test = session.get(TestClass.class, 1);
//Loading collection
Collection<TestParent> tests = test.getTests();
System.out.println(tests.size()); //Incorrect result (6 entries)
//Loading collection directly
Collection<TestParent> tests2 = session.createCriteria(TestParent.class)
.add(Restrictions.eq("testClass.id", 1))
.list();
System.out.println(tests2.size()); //Correct result (3 entries)
}
}
은 무엇인가 내 잘못이야. 예?