我们有一个场景,其中有一个主要产品和另一个子产品,其行为与主要产品完全相同。主要产品最多可以有一个子产品。每当用户选择主要产品时,我们将显示用户子产品(如果有)。我设计了它像
这样的方式 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。
我不确定天气一对一这样有效。尚未尝试保存产品。
您对此类设计有什么建议吗?我看到一些潜在的错误,如子产品共享主产品的许多属性,并且在创建产品本身时存在重复的代码和潜在的错误。但是,通过避免子产品的单独表格,我避免使用产品表的现有报告代码,批处理等进行更改。
答案 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是否有事情要做?
我希望这个解决方案可以帮助你,但不完整。