2010-03-24 145 views
2

我有一个spring-hibernate应用程序,它无法正确映射对象:基本上我有2个域对象,PostUser。语义是每个帖子都有一个相应的用户。Spring-hibernate映射问题

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 ... 

这显然是错误的:它应该加入UserIdpostUserIduser,但它不正确地加入PostIdpost(其主键)UserIduser

任何想法?谢谢!

更新: 由于一对夫妇的帖子下面我现在意识到,我应该一直在使用一个多到一的映射,而不是一比一的。我改变了映射post下以下几点:

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

但现在我得到一个运行时错误告诉我,有没有叫uId属性。这是有道理的,因为我的post域对象中没有uId列(我只是引用了user对象)。现在我对我如何让Hibernate意识到它需要将帖子表中的外键映射到用户表格感到困惑。应该明确地将uId属性添加到我的post域对象中作为占位符的外键?

我希望我做的意义......

回答

1

因为用户有很多帖子,你的协会其实是一个“多到一”,而不是“一比一”。它应该工作,如果你相应地映射它。

编辑:是的,你可以在帖子的财产Post.user用“多对一”,或者设定User.posts在用户与“一个一对多”映射,或都。你是否指定了外键列的名称?在Hibernate中,数据库中的“列”被映射到Java类中的“属性”。也就是说,column属性包含数据库中外键列的名称,而不是Java类中任何属性的名称。如果我正确地阅读你的问题,你应该使用“UserId”,而不是“uId”。

哦,并且fetch =“join”不能懒惰,因​​为它强制用户在与帖子相同的查询中获取。

+0

谢谢,但将此映射放置在“后”映射中是否正确?我试着用类似的不正确结果。我不知道如何让它在Post表中加入UserId,因为我的域对象没有任何外键的概念,只是对用户对象的引用。 – James 2010-03-25 00:06:49

+0

感谢您的更新,请您详细说明“您是否指定了外键列的名称?”,因为我怀疑这可能是我的问题? – James 2010-03-25 00:19:11

+0

谢谢!!!我浪费了这么多时间...因为你可能猜到我是冬眠的新手...... – James 2010-03-25 00:27:01

0

这就是一对一映射的行为。他们通常共享一个主键。 Hibernate假设post的主键与用户的主键相同。 This page总结了这种行为。

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

+0

对于有超过1篇文章的用户,你是对的。我只是困惑到何处放置此映射:在Post的映射下或在User的映射下? – James 2010-03-25 00:07:51