gpt4 book ai didi

java - Hibernate可以保留哪些类型的类?

转载 作者:行者123 更新时间:2023-12-01 22:22:57 25 4
gpt4 key购买 nike

我想知道休眠是否对特定类型的类施加任何限制以使其持久化。我读过Hibernate可以持久化JavaBean类和Pojos。

这是否意味着休眠不能持久化不属于这两类的类?

我们可以在休眠状态下坚持非pojo类吗?例如

Class A extends B{}


基本上,我需要知道什么使休眠无法在RDBMS中持久化类?

最佳答案

持久类是应用程序中实现业务问题实体的类(例如,电子商务应用程序中的客户和订单)。并非所有持久类的实例都被视为处于持久状态。例如,实例可以替代地是瞬态的或分离的。

如果这些类遵循一些简单规则(也称为普通旧Java对象(PO​​JO)编程模型),则Hibernate效果最佳。但是,这些规则都不是硬性要求。实际上,Hibernate3对持久性对象的性质几乎不做任何假设。您可以通过其他方式(例如,使用Map实例树)来表示域模型。

大多数Java应用程序都需要表示猫科动物的持久类。例如:

public class Cat {
private Long id; // identifier

private Date birthdate;
private Color color;
private char sex;
private float weight;
private int litterId;

private Cat mother;
private Set kittens = new HashSet();

private void setId(Long id) {
this.id=id;
}
public Long getId() {
return id;
}

void setBirthdate(Date date) {
birthdate = date;
}
public Date getBirthdate() {
return birthdate;
}

void setWeight(float weight) {
this.weight = weight;
}
public float getWeight() {
return weight;
}

public Color getColor() {
return color;
}
void setColor(Color color) {
this.color = color;
}

void setSex(char sex) {
this.sex=sex;
}
public char getSex() {
return sex;
}

void setLitterId(int id) {
this.litterId = id;
}
public int getLitterId() {
return litterId;
}

void setMother(Cat mother) {
this.mother = mother;
}
public Cat getMother() {
return mother;
}
void setKittens(Set kittens) {
this.kittens = kittens;
}
public Set getKittens() {
return kittens;
}

// addKitten not needed by Hibernate
public void addKitten(Cat kitten) {
kitten.setMother(this);
kitten.setLitterId( kittens.size() );
kittens.add(kitten);
}


}

持久类的四个主要规则:
1,实现一个无参数的构造函数

Cat具有无参数的构造函数。所有持久类都必须具有默认构造函数(可以是非公共的),以便Hibernate可以使用Constructor.newInstance()实例化它们。建议您使用默认构造函数,至少具有包可见性,以便在Hibernate中生成运行时代理。
2.2。提供标识符属性(可选)

猫有一个名为id的属性。此属性映射到数据库表的主键列。该属性可能被称为任何东西,其类型可能是任何原始类型,任何原始“包装”类型,java.lang.String或java.util.Date。如果您的旧数据库表具有组合键,则可以使用具有这些类型的属性的用户定义的类(请参阅本章后面的有关组合标识符的部分。)

标识符属性严格是可选的。您可以不使用它们,而让Hibernate在内部跟踪对象标识符。但是,我们不建议这样做。

实际上,某些功能仅适用于声明标识符属性的类:

分离对象的传递重新连接(级联更新或级联合并)-请参见第10.11节“传递持久性”
Session.saveOrUpdate()
Session.merge()
我们建议您在持久性类上声明统一命名的标识符属性,并使用可为空(即非原始)的类型。


优先选择非最终课程(可选)


代理的Hibernate的主要功能取决于持久类是非最终类,还是声明所有公共方法的接口的实现。

您可以持久化未实现与Hibernate接口的最终类​​。但是,您将无法使用代理进行延迟关联获取,这最终将限制您进行性能调整的选项。

您还应该避免在非最终类上声明公共最终方法。如果要使用带有公共final方法的类,则必须通过设置lazy =“ false”显式禁用代理。


为永久字段声明访问器和更改器(可选)


Cat为其所有持久字段声明访问器方法。许多其他ORM工具直接保留实例变量。最好在关系模式和类的内部数据结构之间提供一个间接方式。默认情况下,Hibernate保留JavaBeans样式属性并识别形式为getFoo,isFoo和setFoo的方法名称。如果需要,您可以切换为直接访问特定属性。

无需将属性声明为公共属性-Hibernate可以使用默认,受保护或私有获取/设置对保留属性。

实现继承

子类还必须遵守第一和第二条规则。它从超类Cat继承其标识符属性。例如:

包装

    public class DomesticCat extends Cat {
private String name;

public String getName() {
return name;
}
protected void setName(String name) {
this.name=name;
}
}


实现equals()和hashCode()

如果您执行以下操作,则必须重写equals()和hashCode()方法:

打算将持久类的实例放入Set中(表示多值关联的推荐方式);和
打算使用附加的分离实例
Hibernate仅在特定会话范围内保证持久身份(数据库行)和Java身份的等效。混合在不同会话中检索到的实例时,如果希望对集合具有有意义的语义,则必须实现equals()和hashCode()。

最明显的方法是通过比较两个对象的标识符值来实现equals()/ hashCode()。如果值相同,则两者必须相同,因为它们相等。如果将两者都添加到集合中,则集合中将只有一个元素。不幸的是,您不能将这种方法与生成的标识符一起使用。 Hibernate只会将标识符值分配给持久对象。新创建的实例将没有任何标识符值。此外,如果实例未保存且当前在Set中,则保存该实例将为该对象分配一个标识符值。如果equals()和hashCode()基于标识符值,则哈希码将更改,从而破坏Set的协定。有关此问题的完整讨论,请参见Hibernate网站。这不是Hibernate问题,而是对象标识和相等性的常规Java语义。

建议您使用业务键相等性实现equals()和hashCode()。业务密钥相等性意味着equals()方法仅比较构成业务密钥的属性。这是一个可以识别我们在现实世界中的实例的密钥(自然的候选密钥):

公共类猫{

...
public boolean equals(Object other) {
if (this == other) return true;
if ( !(other instanceof Cat) ) return false;

final Cat cat = (Cat) other;

if ( !cat.getLitterId().equals( getLitterId() ) ) return false;
if ( !cat.getMother().equals( getMother() ) ) return false;

return true;
}

public int hashCode() {
int result;
result = getMother().hashCode();
result = 29 * result + getLitterId();
return result;
}


}
业务密钥不必像数据库主键候选者那样坚固,不可变或唯一属性通常是业务密钥的理想候选者。

关于java - Hibernate可以保留哪些类型的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29352904/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com