我有一个spring-hibernate应用程序无法正确映射对象:基本上我有2个域对象,Post
和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 ...
显然这是错误的:它应该从UserId
加入post
加UserId
来自user
,而不是从{{1}错误地加入PostId
来自post
的{{1}}的(主键)。
有什么想法吗?谢谢!
更新:
感谢下面的几个帖子,我现在意识到我应该使用多对一映射而不是一对一映射。我将UserId
下的映射更改为以下内容:
user
但现在我收到运行时错误,告诉我没有名为post
的属性。这是有道理的,因为我的<many-to-one name="User" class="com...User" column="uId"/>
域对象中没有uId
列(我只是引用了uId
个对象)。现在我真的很困惑,我怎么能让Hibernate意识到它需要将外键从post表映射到user表。是否应该将post
属性明确添加到我的user
域对象作为外键的占位符?
我希望我有意义......
答案 0 :(得分:1)
由于用户有很多帖子,因此您的关联实际上是“多对一”,而不是“一对一”。如果你相应地映射它应该可以工作。
修改:是的,您可以使用“多对一”映射Post上的Post.user属性,或者使用“一对一”将User中的User.posts映射到许多“,或两者兼而有之。您是否指定了外键列的名称?
Edit2 :在Hibernate中,数据库中的“列”映射到Java-Class中的“属性”。也就是说,column属性包含数据库中外键列的名称,而不是Java类中任何属性的名称。如果我正确地阅读了您的问题,您应该使用“UserId”,而不是“uId”。
哦,并且fetch =“join”不能是懒惰的,因为它要求在与帖子相同的查询中获取用户。
答案 1 :(得分:0)
这是一对一映射的行为。他们通常共享一个主键。 Hibernate假设post的主键与用户的主键相同。 This page总结了这种行为。
我怀疑一个用户实际上可以拥有多个帖子。这使您的映射成为一对多。