4

我正在尝试设计一个非常简单的应用程序,但我对 Hibernate 对实体和值对象的定义(如 Java Persistence with Hibernate 的第 4 章中所定义)感到有些困惑。

我拥有的是一个带有客户的应用程序,他们可以下订单(一对多关系)。这些订单中的每一个都有许多订单行(也是一对多)。现在,我认为客户有身份(客户编号),订单(订单编号)也是如此,因此它们是实体对象?我的困惑来自订单行。

订单行包含数量、产品编号和价格。订单行没有订单就无法存在,也没有自己的身份,因此我将其视为一个值对象。但是我不能将订单行作为订单表的一部分,因为订单与其订单行之间存在一对多的关系。一对多关系如何与值对象的定义一起工作?从休眠书中:

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

如果有人能解决我的困惑,我将不胜感激:)

4

5 回答 5

6

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

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

据我所知,这本书使用了一个示例,其中一个address表示为单个字符串和一个user对象,其中包含一个地址字符串:

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

  • 实现为实体类型(这可能意味着使用单独的表),地址将在没有用户的情况下独立存在,并且两个用户将能够共享相同的地址。

在您的情况下,订单行不属于订单,其持久状态未嵌入订单行(没有意义),它有自己的身份(由 orderId 和 productId 组成)。订单行绝对不是值类型,它是实体类型。

实际上,一旦您考虑关联(一对一、一对多等),您肯定会操纵实体。

于 2009-11-08T11:50:31.370 回答
1

我认为您正在寻找复合元素。参考中有一个实际使用 Order 和 purchaseItems(订单行)的示例。当 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>

来自:依赖对象的集合

于 2009-11-08T11:59:49.687 回答
1

我认为您所拥有的是一个相当通用的 ORM 问题。

您提到“订单行没有订单就无法存在,也没有自己的身份”。
好吧,虽然 OrderLine 不能与 Order 一起存在,但这并不意味着它不能具有标识。

以您的 Order 实体为例,没有客户它就无法存在,但是您已经将其视为实体,是吗?

因此,这里是对实体的建议:
- Customer(可以没有或有多个 Order 实体)
- Order(可以有一个或多个 OrderLine 实体)
- OrderLine

于 2009-11-08T10:50:06.603 回答
0

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

于 2013-02-19T19:24:25.317 回答
0

您可以将订单行设置为值类型,并且值类型支持一对一映射以及一对多映射。显然Java Collections用来映射值类型与实体的*对多关系。在合适的集合内部,根据需要使用元素和复合元素,描述如下:对于实体和值类型之间的一对多关系(非 JDK 类型),使用复合元素。对于值类型表要包含 JDK 类型(比如字符串)的单个属性的一对多关系,使用元素。这个概念在 Java 持久性与 Hibernate 的第 6 章中给出。有关详细信息,请参阅此链接 https://docs.jboss.org/hibernate/orm/3.5/reference/en/html/components.html

于 2015-12-25T14:18:02.177 回答