我对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()。
Session.persist()
org.hibernate.annotations.@Cascade
Session.saveOrUpdate()
这只是一个例子,此处有完整的文档说明
对于您的代码,如果要Manufacturer在保存Project使用时自动保存:
Manufacturer
Project
@ManyToOne (fetch = FetchType.EAGER, cascade = {javax.persistence.CascadeType.PERSIST}) @JoinColumn (name = "mfr_id") public Manufacturer getManufacturer () { return this.manufacturer; }
要么
@Cascade(CascadeType.PERSIST)