2009-11-08 85 views
4

我试图设计一个非常简单的应用程序,并且让自己对Hibernate对实体和值对象的定义(如Java Persistence with Hibernate的第4章中定义)有点困惑。Hibernate映射中的值对象或实体对象?

我有一个应用程序与客户,谁可以下订单(一对多关系)。每个订单都有许多订单行(也是一对多)。现在,我认为客户有身份(客户号码),订单(订单号码)也是这样,因此它们是实体对象?我的疑惑来自订单行。

订单项有数量,产品编号和价格。订单行在没有订单的情况下不能存在,并且没有自己的身份,因此我将其视为价值对象。但是我不能让订单行成为订单表的一部分,因为订单和订单行之间存在一对多的关系。一对多关系如何与值对象的定义一起工作?从Hibernate书籍:

“值类型的对象没有数据库标识;它属于一个实体实例,其持久状态嵌入到拥有实体的表行中。值类型没有标识符或标识属性”

如果任何人都可以清理我的困惑我真的很感激它:)

回答

6

Hibernate的文档,使得区分实体类型值类型,而不是值对象。

  • 对象实体类型:拥有自己的数据库身份值类型的
  • 对象:属于一个实体,它的持久状态被嵌入拥有实体的表中一行。值类型没有标识符或标识符属性。

据我可以记得,书中使用具有表示为单个串的addressuser对象,其中包含一个地址字符串的样品:

  • 实现为值类型(通常意味着在数据库级别的同一个表中的列),如果用户被删除,那么它的地址也是如此。没有用户,地址就无法生存,无法共享。

  • 作为一个实体类型(这可能意味着使用一个单独的表)实施,地址将存在于他们自己的权利,没有用户和两个用户将能够共享相同的地址。

在你的情况下,一个订单不属于订单,它的持久状态不是嵌入命令行中(没有意义),它有它自己的身份(做的orderId和productId)。订单行绝对不是一个值类型,它是一个实体类型。实际上,一旦你根据关联性(一对一,一对多等)来思考,你肯定会操纵实体。

1

我想你所拥有的是一个比较通用的ORM问题。

您提到“订单行不能在没有订单的情况下存在,并且没有自己的标识”。
嗯,虽然OrderLine不能与Order一起存在,但并不意味着它不能拥有身份。

把你的订单实体,它不能存在没有客户,但你已经认为它是一个实体,是吗?

所以,在这里是为实体的建议:
- 客户(可以没有以上的订单实体)
- 订单(可有一个或多个订单行实体)
- 订单行

1

我想你正在寻找一个复合元素。在参考文献中有一个实际使用Order和purchasedItems(订单行)的例子。当Hibernate说,它不能单独存在,但这并不意味着它不能拥有自己的表,只是它总是与父元素相关联:

<class name="eg.Order" .... > 
    .... 
    <set name="purchasedItems" table="purchase_items" lazy="true"> 
    <key column="order_id"/> 
    <composite-element class="eg.Purchase"> 
     <property name="purchaseDate"/> 
     <property name="price"/> 
     <property name="quantity"/> 
     <many-to-one name="item" class="eg.Item"/> 
    </composite-element> 
    </set> 
</class> 

来源:Collections of dependent objects

0

值对象是一个小对象,表示一个简单的实体,其等式不基于身份:即两个值对象在具有相同值时相同,不一定是相同的目标

0

您可以将订单行作为值类型值类型支持一对一映射以及一对多映射。 很明显,Java集合用于映射值类型与实体的*到多关系。在适当的集合中,元素和复合元素按要求使用,如下所述: 对于实体和值之间的一对多关系类型(非JDK类型),使用复合元素。 对于值类型表包含JDK类型(比如字符串)的单个属性的一对多关系,使用元素。 这个概念在Hibernate的Java持久化的第6章中给出。 有关详情,请参阅此链接 https://docs.jboss.org/hibernate/orm/3.5/reference/en/html/components.html