【问题标题】:Hibernate, automatically persist dependant objects休眠,自动持久化依赖对象
【发布时间】:2013-08-26 22:27:01
【问题描述】:

我对 Hibernate 还很陌生,并且一直在尝试确定它将为您做什么以及它需要您做什么。

一个大的对象是处理一个对象,该对象具有数据库中尚不存在的依赖项。例如,我有一个 Project 对象,其中包含一个 Manufacturer 字段,该字段接受 Manufacturer 对象作为其值。在数据库中,我有一个产品表,其中包含一个 mfr_id 列,该列是对制造商表的引用(一种相当典型的单向一对多关系)。

如果分配给产品对象的制造商与数据库中已经存在的制造商相关,则没有问题。但是,当我尝试保存或更新引用尚未持久化的制造商的对象时,操作失败并出现异常。

线程“应用程序”org.hibernate.TransientObjectException 中的异常:对象引用了未保存的瞬态实例 - 在刷新之前保存瞬态实例

我当然可以通过查看产品的 ID 字段是否为 null 并保存它来手动检查产品制造商的状态,如果是,这似乎是一个麻烦的解决方案。如果相关依赖项尚未持久化,Hibernate 是否支持自动持久化依赖项?如果是这样,我该如何启用该行为?我正在使用与 Netbeans 捆绑在一起的 Hibernate 版本(我相信是 3.5)和内联注释来指定映射行为。下面是我的产品和制造商类,减少到处理依赖关系的部分。 (Product extends Sellable 映射到一个sellable表,使用JOINED作为继承策略,就是那个表包含了标识产品的主键)

@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;
    }
}

更新:我从this question 尝试了以下操作,但我仍然得到瞬态对象异常。

@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 版本中似乎没有这种模式。

【问题讨论】:

    标签: java hibernate orm cascade


    【解决方案1】:

    您必须查看级联操作;这种类型的操作允许您管理内部对象的生命周期,尊重其父对象。

    @ManyToOne(cascade)如果你使用Session.persist()操作或者org.hibernate.annotations.@Cascade如果你不使用JPA函数Session.saveOrUpdate()

    这只是一个例子,完整的文档点here

    对于您的代码,如果您想在保存Project 时自动保存Manufacturer,请使用:

    @ManyToOne (fetch = FetchType.EAGER, cascade = {javax.persistence.CascadeType.PERSIST})
    @JoinColumn (name = "mfr_id")
    public Manufacturer getManufacturer () {
      return this.manufacturer;
    }
    

    @Cascade(CascadeType.PERSIST)
    

    【讨论】:

    • 我尝试了你的建议,但是当我尝试保存对象时,我仍然得到关于瞬态对象的相同异常。我还尝试了@ManyToOne 的stackoverflow.com/questions/9032998/… 中建议的方法(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE}),但这也没有用
    • 你在使用 saveOrUpdate() 吗?在这种情况下,您需要org.hibernate.annotation.@Cascade(CascadeType.SAVE_UPDATE)
    • 目前我只是在使用 save()。今晚回家后我会考虑其他选择。
    • SAVE_UPDATE 似乎不是 Netbeans 附带的 Hibernate 版本中的有效级联类型。提示将可用选项列出为 ALL、PERSIST、MERGE、REFRESH 或 REMOVE
    • 你正在使用 javax.persistence.CascadeType;你必须使用 org.hibernate.annotation.CascadeType 和 org.hibernate.annotation.@Cascade 注释
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多