Hibernate - 双向@OneToOne

use*_*299 9 hibernate one-to-one

我有2个类:User和UserPicture,它们之间有1:1的关系.

public class User {
     @Id
     @GeneratedValue(strategy=GenerationType.AUTO)
     @Column(name="id", nullable = false, unique = true)
 private int id;

     private String firstname;

     private String lastname;

     @OneToOne
     @JoinColumn(name = "picture") //field named "picture" in the database
     private UserPicture userPicture;

     ..
}


public class UserPicture {

     @Id
     @GeneratedValue(strategy=GenerationType.AUTO)
     @Column(name="id", nullable = false, unique = true)
     private int id;

     private Blob image;

     @OneToOne
     @JoinColumn(name = "user")
     User user;
Run Code Online (Sandbox Code Playgroud)

UserPicture中的'user'将被加载,但User中的'userPicture'不会 - 我错了什么?

编辑 必须添加我只是创建一个UserPicture并插入它们(使用现有的userId) - 也许我需要在UserPicture级联'用户'?

Pig*_*ras 17

你必须映射你的课程.

public class User {
    ...
    @OneToOne (mappedBy="user")
    private UserPicture userPicture;
    ...
}

public class UserPicture {
    ...
    @OneToOne
    @JoinColumn (name="user")
    private User user;
    ...
}
Run Code Online (Sandbox Code Playgroud)


AEv*_*ans 5

关于您的问题:(因为我没有足够的声誉来回复评论)

“一切都清楚了!还有一个问题,是否可以使 User 中的 userPicture 变得懒惰? – user1731299 2012 年 10 月 24 日 10:44”

是的,可以让它延迟获取。但是,仅仅说“fetchType=FetchType.Lazy”是行不通的。原因是,Hibernate 需要检查连接表以查看它是否为空值,或者那里是否有记录。因为它是一个 OneToOne 映射,Hibernate 认为它可以通过拉回任何存在的数据来保存数据库调用,因为它无论如何都必须检查它是否为空。x-to-many-mappings 不是这种情况,因为 Hibernate 知道“many”意味着有一个列表在另一个表上等待......无论是空列表还是填充列表,它仍然是一个列表。对于单个值,它必须区分实际数据和空值。

解决这个问题的方法是告诉 Hibernate 那里总是有一个值,永远不会有一个空值。知道这一点,Hibernate 可以创建一个占位符,直到需要获取该数据为止。您在注释中执行此操作的方法是将“optional=false”添加到您的@OneToOne 注释中。

不过要注意!这有一些问题;包括我现在想弄清楚的那个(以及我是如何在这里偶然发现你的问题的)。这个 optional=false 使 Hibernate 做一些额外的验证,似乎混淆了 Hibernate 应该如何执行插入。因此,您可能希望远离这种懒惰的获取技术。