2

我有一个 spring-hibernate 应用程序无法正确映射对象:基本上我有 2 个域对象, aPost和 a User。语义是每个帖子都有 1 个对应的用户。

Post域对象大致如下:

class Post {

  private int pId;
  private String attribute;
  ...
  private User user;

  //getters and setters here

}

如您所见,Post包含对User. 当我加载一个Post对象时,我想User加载相应的对象(懒惰 - 仅在需要时)。

我的映射如下所示:

<class name="com...Post" table="post">
    <id name="pId" column="PostId" />
    <property name="attribute" column="Attribute" type="java.lang.String" />

    <one-to-one name="User" fetch="join"
        class="com...User"></one-to-one>
</class>

当然,我有一个基本的映射User设置。

就我的表模式而言,我有一个名为post外部的表UserId,它链接到该user表。

我认为这个设置应该可以工作,但是当我加载一个强制延迟加载User对象的页面时,我注意到正在生成以下 Hiberate 查询:

Select ... from post this_ left outer join user user2_ on this.PostId=user2_.UserId ...

显然这是错误的:它应该从 from 加入from ,UserId但它错误地从(它的主键)加入from 。postUserIduserPostIdpostUserIduser

有任何想法吗?谢谢!

更新:感谢下面的几篇文章,我现在意识到我应该使用多对一映射而不是一对一映射。我将映射更改post为以下内容:

<many-to-one name="User" class="com...User" column="uId"/>

但是现在我收到一个运行时错误,告诉我没有名为uId. 这是有道理的,因为我的域对象中没有uIdpost(我只是引用了一个user对象)。现在我真的很困惑如何让 Hibernate 意识到它需要将外键从 post 表映射到 user 表。uId是否应该向我的post域对象显式添加一个属性作为外键的占位符?

我希望我是有道理的...

4

2 回答 2

1

由于用户有很多帖子,因此您的关联实际上是“多对一”,而不是“一对一”。如果您相应地映射它,它应该可以工作。

编辑:是的,您可以将 Post 上的 Post.user 属性映射为“多对一”,或者将 User 中的 User.posts 设置为“一对多”,或两者兼而有之。您是否指定了外键列的名称?

Edit2:在 Hibernate 中,数据库中的“列”映射到 Java 类中的“属性”。也就是说,column 属性包含数据库中外键列的名称,而不是 Java 类中任何属性的名称。如果我没看错你的问题,你应该使用“UserId”,而不是“uId”。

哦,而且 fetch="join" 不能偷懒,因为它要求在与帖子相同的查询中获取用户。

于 2010-03-25T00:04:38.527 回答
0

这就是一对一映射的行为。它们通常共享一个主键。Hibernate 假设 post 的主键与 user 的主键相同。本页总结了这种行为。

我怀疑一个用户实际上可以拥有多个帖子。这使您的映射成为一对多。

于 2010-03-25T00:06:14.150 回答