我想优化我的数据库表。但是我对Hibernate/JPA的理解不够,现在帮助不大。如何将继承策略与多个子类层结合使用
我有一个Java对象模型,它看起来或多或少是这样的:
ParentClass
SubClass1
SubSubClass1
SubSubClass2
SubSubClass3
SubSubClass4
SubClass2
SubSubClass5
SubSubClass6
所有类包含字段。大约50%的所有字段都在ParentClass中。 40-50%属于SubClass1级别,0-10%属于SubSubclass级别。许多SubSubClass *类都是空的,但对于识别类型是必需的。
TRY 1:
大二我们首先做的是在父类上使用TABLE_PER_CLASS策略。这导致巨大的表的量:
SubSubClass1
SubSubClass2
SubSubClass3
SubSubClass4
SubSubClass5
SubSubClass6
这是不很凉爽,因为在这些表中的所有列的50%的所有表和其他剩下的是3-4表之间共享之间共享。
TRY 2:
我们改变了策略,以SINGLE_TABLE。
结果表只是一个大的“ParentClass”表。但是由于在所有子类中只有大约50%的列是共享的,因此很多字段必须设置为Null,这不够性感。
TRY 3:
下一个尝试是将逐步转向以 “SINGLE_TABLE” 策略混合TABLE_PER_CLASS战略。我决定不使用JOIN TABLES作为一种策略,因为我必须有许多小的子类,这些子类会导致创建许多许多带有一个或两个列的小表。
所以,我如下回答这样一个问题:How to mix inheritance strategies with JPA annotations and Hibernate?
我现在希望把所有的值从父类中的一个表,然后从第一分段到一个表为他们每个人的所有值。这将导致在这样的模式:
ParentClass
- SubClass1
- SubClass2
- SubClass3
这里是我的代码:
@MappedSuperclass
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class ParentClass {
private String value1;
}
@MappedSuperclass
@SecondaryTable(name = "SubClass1")
public abstract class SubClass1 extends ParentClass {
@Column(table = "SubClass1")
private String value11;
}
@MappedSuperclass
@SecondaryTable(name = "SubClass2")
public abstract class SubClass2 extends ParentClass {
@Column(table = "SubClass2")
private String value12;
}
@Entity
@SecondaryTable(name = "SubClass1")
public abstract class SubSubClass1 extends SubClass1 {
@Column(table = "SubClass1")
private String value111;
}
@Entity
@SecondaryTable(name = "SubClass2")
public abstract class SubSubClass2 extends SubClass2 {
@Column(table = "SubClass2")
private String value121;
}
里面居然作品相当不错的。但我的问题开始了:
首先我在SchemaUpdate期间得到以下错误。
Unsuccessful: alter table schema.SubClass1 add constraint AAAAAAA36D68C4 foreign key (id) references schema.ParentClass
ORA-02275: such a referential constraint already exists in the table
Unsuccessful: alter table schema.SubClass2 add constraint AAAAAAA36D68C4 foreign key (id) references schema.ParentClass
ORA-02275: such a referential constraint already exists in the table
我认为这些错误是由于,我在多个级别上多次使用次表。每次我使用它们时,都会创建另一个约束条件。这当然不起作用,因为约束已经存在。
第二个问题是,Hibernate的去疯狂,如果它应该来自所有这些表获取数据的事实:
select
*
from
(select
parentclass0_.value1 as value1_1_,
parentclass0_1_.value11 as erste1_3_,
parentclass0_1_.value111 as value1113_3_,
parentclass0_2_.value12 as value122_3_,
parentclass0_2_.value121 as value1214_3_,
parentclass0_.DTYPE as DTYPE2_
from
schema.parentclass parentclass0_
left outer join
schema.subclass1 parentclass0_1_
on parentclass0_.id=parentclass0_1_.id
left outer join
schema.subclass1 parentclass0_2_
on parentclass0_.id=parentclass0_2_.id
left outer join
schema.subclass1 parentclass0_3_
on parentclass0_.id=parentclass0_3_.id
left outer join
schema.subclass2 parentclass0_4_
on parentclass0_.id=parentclass0_4_.parentclass_id
left outer join
schema.subclass1 parentclass0_5_
on parentclass0_.id=parentclass0_5_.id
left outer join
schema.subclass1 parentclass0_6_
on parentclass0_.id=parentclass0_6_.id)
它加入我所用的@SecondaryTable标注在子类中,每次同一个表。它一次又一次地加入。我看了一下甲骨文的解释计划,告诉我这个计划会自动优化,如果我会优化它的话。但不管怎么说。真奇怪。
问题:
如何防止从创建相同的约束多次休眠?我认为这也会解决连接问题。或者应该停止尝试这样做,并有另一种方式?
我们结束了使用SINGLE_TABLE策略。分析SQL Querys显示了巨大的效率收益。单个表格会导致查询的成本为6.每个额外连接的表格都会增加1个成本。有了完整的联合表格布局,我们最终将获得超过150个表格,从而产生160个成本。这再次是单桌会议的26倍。我们认为我们会混合一些辅助表来优化代码的某些部分。测试表明,这是非常整洁,不会导致许多问题,除了我在我的问题中提到的问题(这是可以修复或可以忽略的) – user932708 2012-03-02 16:02:18