我对Hibernate还是很陌生,一直在尝试确定它将为您做什么以及需要您做什么。
最重要的是处理一个对象,该对象具有数据库中尚不存在的依赖项。例如,我有一个Project对象,其中包含一个Manufacturer字段,该字段接受Manufacturer对象作为其值。在数据库中,我有一个带mfr_id列的产品表,该列是对Manufacturers表的引用(一种相当典型的单向一对多关系)。
如果分配给该产品对象的制造商与数据库中已有的制造商相关,则没有问题。但是,当我尝试保存或更新引用尚未持久化的制造商的对象时,该操作将失败并出现异常。
线程“应用程序” org.hibernate.TransientObjectException中的异常:对象引用了一个未保存的临时实例-
在刷新之前保存该临时实例
我当然可以通过查看产品的ID字段是否为null并手动将其保存来手动检查产品制造商的状态,但这似乎是一个麻烦的解决方案。如果相关的依赖项尚未持久化,Hibernate是否支持自动持久化依赖项?如果是这样,我如何启用该行为?我使用的是与Netbeans捆绑在一起的Hibernate版本(我相信是3.5)和内联注释,用于指定映射行为。以下是我的产品和制造商类别,简化为处理依赖性的部分。(产品使用JOINED作为继承策略扩展了映射到可销售表的Sellable,该表就是包含标识产品的主键的表)
@Entity
@Table (
name="products",
schema="sellable"
)
public abstract class Product extends Sellable {
private Manufacturer manufacturer;
@ManyToOne (fetch = FetchType.EAGER)
@JoinColumn (name = "mfr_id")
public Manufacturer getManufacturer () {
return this.manufacturer;
}
/**
*
* @param manufacturer
*/
public Product setManufacturer (Manufacturer manufacturer) {
this.manufacturer = manufacturer;
return this;
}
}
依赖的制造商
@Entity
@Table (
name="manufacturers",
schema="sellable",
uniqueConstraints = @UniqueConstraint(columnNames="mfr_name")
)
public class Manufacturer implements Serializable {
private Integer mfrId = null;
private String mfrName = null;
@Id
@SequenceGenerator (name = "manufacturers_mfr_id_seq", sequenceName = "sellable.manufacturers_mfr_id_seq", allocationSize = 1)
@GeneratedValue (strategy = GenerationType.SEQUENCE, generator = "manufacturers_mfr_id_seq")
@Column (name="mfr_id", unique=true, nullable=false)
public Integer getMfrId () {
return mfrId;
}
private Manufacturer setMfrId (Integer mfrId) {
this.mfrId = mfrId;
return this;
}
@Column(name="mfr_name", unique=true, nullable=false, length=127)
public String getMfrName () {
return mfrName;
}
public Manufacturer setMfrName (String mfrName) {
this.mfrName = mfrName;
return this;
}
}
更新:我从这个问题尝试了以下内容,但是我仍然遇到了瞬态对象异常。
@ManyToOne (fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
我还检查了Netbeans捆绑了哪个版本的Hibernate,它是3.2.5。
更新2:我发现以下内容显然可以按照我的意愿工作。
@ManyToOne (fetch = FetchType.EAGER, cascade = CascadeType.ALL)
但是,我怀疑这不是我真正想要的级联类型。如果我删除产品,则认为删除其关联的制造商不是正确的操作,我相信现在会发生这种情况。
我确实尝试创建一个由所有可用类型组成的级联类型,但是那也不起作用。当我尝试保存与未保存的制造商关联的产品时,我遇到了同样的异常。
@ManyToOne (fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
我已经在多个地方看到了CascadeType.SAVE_UPDATE,但该模式似乎在Netbeans随附的Hibernate版本中不可用。
您必须查看级联操作;这种类型的操作允许您管理内部对象尊重其父对象的生命周期。
@ManyToOne(cascade),如果您使用Session.persist()
operation或org.hibernate.annotations.@Cascade
不使用JPA
function Session.saveOrUpdate()
。
这只是一个例子,此处有完整的文档说明
对于您的代码,如果要Manufacturer
在保存Project
使用时自动保存:
@ManyToOne (fetch = FetchType.EAGER, cascade = {javax.persistence.CascadeType.PERSIST})
@JoinColumn (name = "mfr_id")
public Manufacturer getManufacturer () {
return this.manufacturer;
}
要么
@Cascade(CascadeType.PERSIST)
问题内容: 我有使用获取的持久性hibernate对象 从那以后我改变了它。 我想执行以节省内存,因为我已经完成了该对象。 此处的文档指出,该对象的更改将不会保留。换句话说- 逐出会使我丢失对对象所做的更改。 我可以打电话,但是那会清空所有更改。 在逐出之前,如何保持对单个持久对象所做的更改? 问题答案: 呼叫或,然后您可以根据需要呼叫evict。但是,您必须先刷新会话,然后再执行此操作。出于充分
问题内容: JodaTime有一个提供Hibernate持久性的库。最近,我开始研究Joda-Money,开始了解如何使用hibernate来保持这种状态,而我看不到任何库。 有什么建议么? 问题答案: 好吧,我把你的意见,并炮制了钱的自定义类型为乔达库中的定义,作为参考的人可以看看它在这里,在这里使用和测试自定义类型在这里
问题内容: 我有一个数据库视图,该视图产生的结果集没有真正的主键。我想使用Hibernate / Persistence将结果集映射到Java对象上。当然,因为没有PK,所以我不能用修饰任何字段。 部署时,Hibernate抱怨缺少该组件。我该如何解决? 问题答案: 如果存在使行唯一的列组合,请围绕列组合建模主键类。如果没有,您基本上就不走运了-但您应该重新检查视图的设计,因为它可能没有意义。 有
创建新的Shelf # shelve_create.py import shelve with shelve.open('test_shelf.db') as s: s['key1'] = { 'int': 10, 'float': 9.5, 'string': 'Sample data', } # shelve_existing
问题内容: 依赖集合的hibernate文档说: 双向关联导航无法在另一侧参考购买。组件是值类型,并且不允许共享引用。单个购买可以在订单集中,但不能同时被商品引用。 有人可以帮我理解这一点吗? 1)为什么hibernate会限制另一方的购买参考? 2)为什么不允许共享引用? 3)物料不能同时引用一次购买是什么意思? 有人可以用一些例子解释一下。 问题答案: 为了解释这一点,我将从文档中的另一个示例
问题内容: 我用hibernate映射的对象具有奇怪的行为。为了知道对象为何表现异常,我需要知道是什么使该对象变脏了。有人可以帮我提示吗? 该对象是Java / Spring上下文中的Java类。因此,我希望针对Java平台的答案。 编辑:我想获得对Hibernate脏状态的访问以及它如何在连接到会话的对象上更改。我不知道一段代码会对您有什么帮助。 至于实际的问题:在由Spring Transac