在同一个表上进行Hibernate一对一映射

时间:2014-12-08 15:15:02

标签: hibernate mapping parent one-to-one

我们有一个场景,其中有一个主要产品和另一个子产品,其行为与主要产品完全相同。主要产品最多可以有一个子产品。每当用户选择主要产品时,我们将显示用户子产品(如果有)。我设计了它像

这样的方式
    public class Product  {
...
    private Product parentProduct;

和hibernate映射xml(是的..我们仍在使用xml)

    <one-to-one name="parentProduct" class="uk.co.xxx.domain.Product" cascade="save-update" foreign-key="PARENT_PRODUCT_ID"/>

对于主要产品,parentProduct将为null。

我不确定天气一对一这样有效。尚未尝试保存产品。

您对此类设计有什么建议吗?我看到一些潜在的错误,如子产品共享主产品的许多属性,并且在创建产品本身时存在重复的代码和潜在的错误。但是,通过避免子产品的单独表格,我避免使用产品表的现有报告代码,批处理等进行更改。

2 个答案:

答案 0 :(得分:1)

这应该有效。您可以在复制构造函数中设置与父项共享的属性(创建子产品时,将父产品作为构造函数参数传递,复制所需内容,将父项设置为parentProduct)。

替代方案可能是SubProduct extends Product,但您使用的是SINGLE_TABLE继承策略,而不是TABLE_PER_CLASS。您只需将dtype列(以及您已有的外键列)添加到Product表,这样您就知道哪些产品是主要产品,哪些产品不是。如果您已有现有数据,则需要更新dtype的值。

答案 1 :(得分:1)

我有同样的问题。我需要一种双向一对一的关系,避免改变数据库的设计。我想在同一个表中保存产品和子产品(相同类型和80%的共享数据)的关系。我选择用具有唯一约束的多对一来表示这种关系(与一对一相同)。

<hibernate-mapping package="com.my.package" >
<class name="Product" table="PRODUCT" >
    <!-- Class Cache -->
    <cache usage="nonstrict-read-write"/> 
    <id name="id" type="java.lang.Long">
        <column name="ID" precision="12" scale="0" />
        <generator class="sequence">
            <param name="sequence">PRODUCT_SEQ</param>
        </generator>
    </id>
    ...
    <many-to-one name="parentProduct" not-null="true" foreign-key="ID" class="com.my.package.Product" column="PARENT_PRODUCT_ID" cascade="save-update" unique="true" fetch="select" />
    ...
</class>

这个解决方案相当不错,但不是双向关系。我的意思是很容易从孩子那里找到父母而不是反过来。

Order.List<Products>
Product_1 -> null 
Product_2 -> Product_1 
...

知道Product_1是否有孩子而不是每次执行java cicles以检查整个productsList是否有事情要做?

我希望这个解决方案可以帮助你,但不完整。