Hibernate(5.2.2)の継承戦略 "table per subclass"に問題があります。マッピングとHibernate。レイジーローディングコレクションのデカルト製品
クラス(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
をロードした後にコレクションにアクセスすると、表間に接続がないデカルト製品(LEFT OUTER JOIN
)を持つsql-queryが形成されます。
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)
}
}
は何ですか間違っている例?