我有两个类: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',但用户不会加载'userPicture' - 我错了什么?
修改 必须补充说我只是创建一个UserPicture并插入它们(使用现有的userId) - 也许我需要在UserPicture中级联'user'?
答案 0 :(得分:16)
你必须映射你的课程。
public class User {
...
@OneToOne (mappedBy="user")
private UserPicture userPicture;
...
}
public class UserPicture {
...
@OneToOne
@JoinColumn (name="user")
private User user;
...
}
答案 1 :(得分:3)
关于你的问题:(因为我没有足够的声誉来回复评论)
“一切都清楚!只有一个问题,是否有可能让用户图片在用户懒惰? - user1731299 12月24日在10:44”
是的,它可以使它变得懒惰。但是,只是说“fetchType = FetchType.Lazy”将不起作用。原因是,Hibernate需要检查连接表以查看它是否为空值,或者是否有记录。由于它是OneToOne映射,Hibernate认为它可以通过撤回那里的任何数据来保存数据库调用,因为它必须检查它是否为null。对于x-to-many-mappings,情况并非如此,因为Hibernate知道'many'意味着有一个列表在另一个表上等待...无论是空列表还是填充列表,它仍然是一个列表。对于单个值,它必须区分实际数据和空值。
解决这个问题的方法是告诉Hibernate总是会有一个值,而且永远不会是null值。知道了这一点,Hibernate可以创建一个占位符,直到获取数据为止。在注释中执行此操作的方法是在@OneToOne注释中添加“optional = false”。
但请注意!这有一些问题;包括我现在想弄清楚的那个(以及我如何在这里偶然发现你的问题)。这个可选的= false使得Hibernate做了一些额外的验证,似乎让Hibernate对如何执行插入感到困惑。所以,你可能想要远离这种懒惰的抓取技术。
答案 2 :(得分:1)
即使我们在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
.....
}
我知道这只是一个部分答案,暨问题。但这与此处的讨论非常相关。