Java HIbernate加载子类和类
我正在使用Hibernate连接到我的数据库。 我的应用程序中有一个继承结构,问题是当我执行类似“from Animal”的查询时,它会对类Animal、它的子类以及所有与Animal及其子类的关联进行左外连接。Java HIbernate加载子类和类,java,hibernate,orm,Java,Hibernate,Orm,我正在使用Hibernate连接到我的数据库。 我的应用程序中有一个继承结构,问题是当我执行类似“from Animal”的查询时,它会对类Animal、它的子类以及所有与Animal及其子类的关联进行左外连接。 如何避免这种情况。只有在我的条件查询中通过fetchmode指定数据时,我才想加载数据?基本上,这是Hibernate使用的默认ORM继承设计模式,称为类继承(所有类都映射到一个表),如果您想更改,可以通过google: -单个类层次结构或每个类的表(这将把每个类映射到数据库中的一个单
如何避免这种情况。只有在我的条件查询中通过fetchmode指定数据时,我才想加载数据?基本上,这是Hibernate使用的默认ORM继承设计模式,称为类继承(所有类都映射到一个表),如果您想更改,可以通过google:
-单个类层次结构或每个类的表(这将把每个类映射到数据库中的一个单独的表)
-具体类层次结构(这将仅将具体实现映射到表)。假设您有如下类结构:
class Animal { }
class Dog : Animal { }
class Cat : Animal { }
然后,当您选择所有Animal
s时,您还希望加载所有Dog
s和Cat
s。毕竟它们是动物
联想是另一回事。您可以创建映射,使关联是惰性负载而不是急切负载。是的,Hibernate支持多态查询。从文件中: 类似以下的查询:
from Cat as cat
不仅返回Cat
的实例,而且返回
也包括子类,如DomesticCat
。
Hibernate查询可以命名任何Java
from子句中的类或接口。
查询将返回所有
扩展该类的持久类
类或实现接口。这个
下面的查询将返回所有
持久对象:
from java.lang.Object o
名为的接口可能是
由各种持久性的
课程:
from Named n, Named m where n.name = m.name
最后两个查询将需要
多个SQL选择
。这意味着
order by子句没有
正确排列整个结果集。
这也意味着你不能称之为
使用Query.scroll()
进行查询
这是默认行为(称为隐式多态性),Hibernate同时支持隐式和显式多态性:
隐式多态性意味着类的实例将
由命名任何
超类或实现的接口或
类,以及任何
将返回该类的子类
通过命名类的查询
它本身显式多态性均值
将返回该类实例
仅通过显式命名的查询
那个班。指定
类将只返回
映射到该
声明为
或
。
在大多数情况下,默认设置为
polymorphics=“implicit”
是
适当的显式多态性是
当使用两个不同的类时非常有用
映射到同一个表,这允许
“轻量级”类,其中包含
表列的子集
这可以在类级别进行配置。如果使用xml映射,请使用polymorphics=“explicit”
。使用Hibernate的@Entity
注释如果您正在使用注释,请参阅。下面是一个例子:
@javax.persistence.Entity
@org.hibernate.annotations.Entity(polymorphism = PolymorphismType.EXPLICIT)
@Inheritance(strategy = InheritanceType.JOINED)
public class Foo {
...
}
为了避免类层次结构获取期间出现多个联接,您可以应用单表层次结构映射策略,然后使用选择获取策略在子类上定义辅助表。但是,这会将“重连接”模型转换为“N+1选择”模型。例如:
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = Super.DISCRIMINATOR_COLUMN, discriminatorType = DiscriminatorType .STRING, length = 255)
public class Super {
public static final String DISCRIMINATOR_COLUMN = "classname";
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
protected long id;
@Column(updatable = false, insertable = false)
protected String classname;
protected String superProp = "superProp";
public long getId() {
return id;
}
public String getClassname() {
return classname;
}
public String getSuperProp() {
return superProp;
}
public void setSuperProp(String superProp) {
this.superProp = superProp;
}
}
@Entity
@SecondaryTable(name = SubA.TABLE)
@Table(appliesTo = SubA.TABLE, fetch = FetchMode.SELECT)
public class SubA extends Super {
public static final String TABLE = "SUBA";
@Column(table = TABLE)
protected String subAProp = "subAProp";
public String getSubAProp() {
return subAProp;
}
public void setSubAProp(String subAProp) {
this.subAProp = subAProp;
}
}
@Entity
@SecondaryTable(name = SubB.TABLE)
@Table(appliesTo = SubB.TABLE, fetch = FetchMode.SELECT)
public class SubB extends Super {
public static final String TABLE = "SUBB";
@Column(table = TABLE)
protected String subBProp = "subBProp";
public String getSubBProp() {
return subBProp;
}
public void setSubBProp(String subBProp) {
this.subBProp = subBProp;
}
}
以及在超级查询的上执行的SQL操作:
select [...] from SUPER super0_
select super_1_.subaprop as subaprop1_83_ from SUBA super_1_ where super_1_.id=1
select super_2_.subbprop as subbprop1_84_ from SUBB super_2_ where super_2_.id=2
关于这种方法和hibernate一般性能提示的更多信息,您可以阅读。我也有同样的问题,我只是假设它必须这样做,因为表不是很大,我没有费心考虑它,但我确实想知道您是否可以阻止它。谢谢John。我明白你的意思。您能否让我知道在映射文件中指定什么,以便仅当通过fetchmode需要时才加载关联。我目前面临的问题是,当我加载超类时,它也加载子类的关联。我希望避免这样做。对于一对一的延迟加载,请参阅:或者对于一对多的延迟加载,请参阅这将适用于关联(has-a关系)。它是否也适用于多态查询(is-a)。我的观点是,更改继承策略不会禁用多态查询。