2014-02-13 70 views
21

我试图让休眠@OneToOne注释工作,并没有在这里很成功......的Java:Hibernate的@OneToOne映射

比方说,我有一个表叫status,看起来像这样:

+------------------------------------------------+ 
|      status      | 
+------------------------------------------------+ 
| id | frn_user_id | frn_content_id | status | 
+----+-------------+----------------+------------+ 
| 1 |  111  |  0  | "active" | 
+----+-------------+----------------+------------+ 
| 2 |  0  |  222  | "inactive" | 
+----+-------------+----------------+------------+ 

而且我已经得到了User,看起来像这样的实体:

@Entity 
@Table(name = "user") 
public class User { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "id", nullable = false) 
    private Integer id; 

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "userId") 
    private Status status; 

    // getters and setters 
} 

,用一个类似的Content,和为Status诺特尔实体,看起来像这样:

@Entity 
@Table(name = "status") 
public class Status { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "id", nullable = false) 
    private Integer id; 

    @Column(name = "frn_user_id") 
    private Integer userId; 

    @Column(name = "frn_content_id") 
    private Integer contentId; 

    @Column(name = "status") 
    private String status; 

    // getters and setters 
} 

当我执行上User读,我希望User.getStatus()将返回Status物体id=1。相反,我得到一个AnnotationException:“引用属性不是(One | Many)ToOne:Status.userId在mappedBy User.status”

我已经倾倒了文档,教程和示例在这里所以,至今尝试过的失败了。

另外值得注意的是:这应该支持一对一或一对一的关系,因为某些usercontent记录在status表中不会有引用。

任何帮助将不胜感激!

+2

'userId'需要是带'@ OneToOne' /'@ JoinColumn'的'User'类型。另请注意,您有一个错字(contentId/userId) – 2014-02-13 18:20:51

+0

另请参阅http://stackoverflow.com/questions/18303522/jpa-hibernate-issue-with-onetoone-mappedby-annotation?rq=1 – 2014-02-13 18:21:53

+0

只是一个数据库设计理念:也许你可以重新考虑你的设计作为用户和内容之间的多对多关系,并且状态描述将在该设计中是一个用户属性? –

回答

65

您的状态实体不得具有Integer类型的属性userIdcontentId,与@Column映射。它必须具有属性user和类型的用户和内容,与@OneToOne映射的content

public class User { 
    @OneToOne(mappedBy = "user") 
    private Status status; 
    // ... 
} 

public class Status { 
    @OneToOne 
    @JoinColumn(name = "frn_user_id") 
    private User user; 
    // ... 
} 

用户具有一个状态。状态有一个用户。

+0

感谢您分享此。我被过去3天的'mappedBy'困住了。我谷歌搜索&经过这么多Stackoverflow的帖子,但没有运气。当我通过你的解决方案时,我记得**我已经在关系**的背面的'OneToOne'映射中创建了一个'java.util.Set'。只要**我删除了'Set'并且只需创建实体类型属性,我的代码就开始工作**。非常感谢。给予好评。 – OO7

+0

我经历了[@Vlad Mihalcea回复此帖子]有点困惑(http://stackoverflow.com/questions/23925322/delete-child-from-parent-and-parent-from-child-automatically-with -jpa-注解/ 23926548#23926548)。在他的回答中,'孩子'有'许多玩具',那么*为什么他用'OneToOne(mappedBy =“child”)''注释了'List 玩具'?为什么不用'OneToMany'?*你也在'Status'的'User'中指定了'JoinColumn',而Vlad Mihalcea没有在'Toy'中的'Child'中。 * mappedBy'带有/不带'JoinColumn'的目的是什么?*请您澄清我的疑问吗? – OO7

+0

这是错的。它应该是OneToMany。JoinColumn用于指定连接列的名称。如果你没有指定一个,Hibernate将使用一个defaukt名字(这个默认名字是如何构造的,在JPA规范中指定) –