休眠,自动持久化依赖对象 [英] Hibernate, automatically persist dependant objects

查看:26
本文介绍了休眠,自动持久化依赖对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Hibernate 的新手,一直在尝试确定它会为您做什么以及它需要您做什么.

I'm quite new to Hibernate and have been trying to determine what it will do for you and what it requires you to do.

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

A big one is dealing with an object that has dependants that don't yet exist in the database. For example, I have a Project object that includes a Manufacturer field that accepts a Manufacturer object as its value. In the database I have a products table with a mfr_id column that's a reference to the manufacturers table (a fairly typical unidirectional one-to-many relationship).

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

If the manufacturer assigned to the product object relates to one that's already in the database then there's no problem. However, when I try to save or update an object that references a manufacturer that hasn't been persisted yet, the operation fails with an exception.

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

Exception in thread "Application" org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing

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

I can of course manually check the state of the product's manufacturer by seeing if it's ID field is null and saving it if it is, but this seems like a cumbersome solution. Does Hibernate support automatically persisting dependants if the dependant in question isn't yet persisted? If so, how do I enable that behaviour? I'm using the version of Hibernate bundled with Netbeans (3.5, I believe) and inline annotations for specifying the mapping behaviour. Below are my product and manufacturer classes, cut down to the parts that handle the dependency. (Product extends Sellable which maps to a sellable table, using JOINED as the inheritance strategy It's that table that contains the primary key that identifies the product)

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

更新:我从这个问题中尝试了以下内容,但我仍然得到瞬态对象异常.

UPDATE: I tried the following from this question, but I still get the transient object exception.

@ManyToOne (fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE})

我还检查了与 Netbeans 捆绑在一起的 Hibernate 版本,它是 3.2.5

I also checked what version of Hibernate is bundled with Netbeans, it's 3.2.5

更新 2:我发现以下内容似乎可以正常工作.

UPDATE 2: I found that the following appears to apparently work as I wanted.

@ManyToOne (fetch = FetchType.EAGER, cascade = CascadeType.ALL)

但是,我怀疑这不是我真正想要的级联类型.如果我删除一个产品,我认为删除其关联的制造商不是正确的操作,我相信现在会发生这种情况.

However, I suspect that this is not the cascade type I really want. If I delete a product, I don't think deleting its associated manufacturer is the correct action, which is what I believe will happen now.

我确实尝试过创建一个由所有可用类型组成的级联类型,但这也不起作用.当我尝试保存与未保存的制造商相关联的产品时,我遇到了同样的异常.

I did try creating a cascade type that consisted of all the types that were available, but that didn't work either. I got the same exception when I tried to save a product that had an unsaved manufacturer associated with it.

@ManyToOne (fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})

我在几个地方看到过 CascadeType.SAVE_UPDATE ,但是在 Netbeans 附带的 Hibernate 版本中似乎没有这种模式.

I've seen CascadeType.SAVE_UPDATE mentioned in several places, but that mode doesn't seem to be available in the version of Hibernate that comes with Netbeans.

推荐答案

你得看级联操作;这种类型的操作允许您管理内部对象的生命周期,尊重它们的父对象.

You have to look at cascading operations; this type of operation permits you to manage lifecycle of inner object respect their parent.

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

@ManyToOne(cascade) if you use Session.persist() operation or org.hibernate.annotations.@Cascade if you use not JPA function Session.saveOrUpdate().

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

This is just an example, for full doc point here

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

For your code, if you want to automatically save Manufacturer when saving Project use:

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

@Cascade(CascadeType.PERSIST)

这篇关于休眠,自动持久化依赖对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆