10

我有 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;

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

编辑 必须补充一点,我只是创建一个 UserPicture 并插入它们(使用现有的 userId)-也许我需要在 UserPicture 中级联“用户”?

4

3 回答 3

19

你必须映射你的类。

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

public class UserPicture {
    ...
    @OneToOne
    @JoinColumn (name="user")
    private User user;
    ...
}
于 2012-10-24T08:06:51.507 回答
5

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

“一切都清楚了!只有一个问题,是否有可能使用户中的 userPicture 变得懒惰? – user1731299 2012-10-24 10:44:07

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

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

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

于 2013-08-06T17:56:15.617 回答
2

即使我们在 JoinColumn 注释中将字段指定为不可为空,一对一的延迟加载仍然有效。然而,在双向一对一中,延迟加载在我们使用 mappedBy='' 的实体上不起作用。例如,如果我们有两个实体 Contract 和 House,其中 Contract 表包含 House 的外键。当我们在这里使用双向 OneToOne 并尝试加载合同时,然后延迟加载工作(即 House 没有立即加载)但是当我们尝试加载 House(使用 House 存储库)时,合同总是被急切地获取。有人知道为什么会这样吗?

Public class Contract {
  .....
  @onetoone(lazy)
  @JoinColumn(name='houseid', nullable=false)
  Private House house
  .....
}

Public class House {
  .....
  @onetoone(lazy, mappedBy='house')
  Private Contract contract
  .....
}

我知道这只是部分答案,兼问题。但这与这里的讨论非常相关。

于 2016-07-25T23:28:52.817 回答