我正在尝试在两个实体之间建立一对一的映射。一个实体维护用户记录如下:
@Entity
public class ConcreteUser implements User{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String name;
private String email;
private int age;
private SEX sex;
private String accessLevel;
public ConcreteUser() {
}
public ConcreteUser(String name, String email, int age, SEX sex, String accessLevel) {
// set class properties
}
//
// Some getter and setter code
//
我想使用上述实体中的主键作为其他实体中的外键,它维护其他信息。这是另一个实体的样子:
@Entity
public class SomeOtherEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "SOME_COLUMN_NAME")
private long recordId;
//
// some other private fields here
//
@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
private ConcreteUser concreteUser;
public SomeOtherEntity () {
}
// getters and setters etc
我的示例测试用例如下:
@Test
public void testAddSomeOtherEntity() throws Exception {
/* This is the user, whose primary key will be used as a foreign key in SomeOtherEntity */
ConcreteUser user = new ConcreteUser(...);
/* Create a new SomeOtherEntity and assign a ConcreteUser to it */
SomeOtherEntity d = new SomeOtherEntity();
d.setConcreteUser(user); /* I doubt if this line has any effect at all */
// add SomeOtherEntity to table
/* addSomeOtherEntity is translated to an HTTP request and server responds with added entity */
d = myService.addSomeOtherEntity(d);
assertNotNull(d);
/* At this point, the recordId is generated and updated */
// Check if this entity was added properly
long recordId = d.getRecordId();
SomeOtherEntity d2 = myService.getSomeOtherEntityById(recordId);
assertNotNull(d2);
/* This test case passes */
assertEquals(d2.getRecordId(), d.getRecordId());
/* But this test case fails */
assertEquals(d2.getConcreteUser().getId(), d.getConcreteUser().getId());
}
总之,我创建了SomeOtherEntity对象,分配了一个ConcreteUser对象并保留了SomeOtherEntity。但是,当我重新检索SomeOtherEntity时,我获得了与之前分配的不同的ConcreteUser。特别是,我得到的ConcreteUser,与" idI;#34;具有相同的" id"。这不是我所期待的。
我对Spring很新,我确信我误解了一些东西。截至目前,我正在考虑事先将ConcreteUser分配给SomeOtherEntity意味着什么。相反,也许我应该首先创建并持久化SomeOtherEntity,然后更新ConcreteUser? 如果有人可以提供一些建议以及它在现实世界中的表现如何,我真的很感激。提前致谢。
答案 0 :(得分:0)
在SomeOtherEntity中,为ConcreteUser指定@PrimaryKeyJoinColumn映射。如果您选中the documentation of the annotation,就会发现它说:
...它可以在OneToOne映射中使用,其中主键是 引用实体用作引用的外键 实体
这意味着SomeOtherEntity的主键值用作ConcreteUser的外键值。
您想要使用@JoinColumn注释。
答案 1 :(得分:0)
因此,事实证明,在Spring中实现一对一关系有不同的方法。以下是对不同方式的简短而有用的介绍: Hibernate one-to-one mapping using annotations
这里的问题不是拥有方,而是从三者中选择一对一的方法。根据上面提到的文章,当您希望两个表的主键匹配时,使用@PrimaryKeyJoinColumn
注释,这不是这里的情况。
如问题所述,测试用例失败,因为Hibernate根据主键映射了两个表,而不是使用ConcreteUser
setConcreteUser
实体。