我有两个实体,AP和APStatus,一对一的单向关系。只有AP需要能够访问APStatus。 APStatus唯一需要知道的是AP的id,它也将作为APStatus的主键。从本质上讲,APStatus就像一个嵌入式对象,但我想要一个单独的表。这就是我所拥有的:
我的实体
@Entity
public class AP {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="ID", nullable=false)
private int id;
@OneToOne
private APStatus apStatus;
//Getters and setters
}
@Entity
public class APStatus {
@Id
@Column(name="AP_ID", nullable=false)
private int apId;
//Getters and setters
}
我的测试
public class APRepositoryTest {
@Autowired
APRepository repository;
@Autowired
APStatusRepository statusRepository;
@Test
public void test() {
AP ap = new AP();
APStatus status = new APStatus();
statusRepository.save(status);
ap.setApStatus(status);
repository.save(ap);
status.setApId(ap.getId());
AP dbAp = repository.findOne(ap.getId());
assertNotNull(dbAp);
assertNotNull(dbAp.getApStatus());
assertEquals(dbAp.getId(), dbAp.getApStatus().getApId());
}
}
assertEquals失败,预期:< 1>但是< 0>。我已经知道为什么,在我已经保存状态和ap之后,我正在设置状态的apId字段。但是在我保存之前设置它的问题是我将字段设置为零,因为在执行repository.save(ap)
之后,ap的id被自动生成为新值(在这种情况下为1)。我已经尝试过将关系设为双向并添加级联效果,但到目前为止我还没有成功。有人可以指出我正确的方向或告诉我如何解决这个问题?提前致谢。
编辑:现在我要将关系建立为双向关系,并在APStatus类中为apId属性设置getter方法,如下所示。如果有人有更好的答案,请分享。
public int getApId() {
return ap.getId();
}
答案 0 :(得分:0)
首先,您无法更改实体ID。它只设置一次以识别实体。之后,您强制实例引用完全不同的内容,这在JPA中是不受支持的。
这意味着如果status.setApId调用更改了apId字段,则只能使用实际值进行设置。
其次,我不太了解AP的apStatus参考。您的AP是否有APStatus的外键,或者您是否打算使用AP.ID APStatus.AP_ID关系?我的猜测是它打算重用AP.ID APStatus.AP_ID关系,因为这似乎更常见,但只影响你映射的方式。
您可以通过首先保存AP,在ApStatus中使用其ID并保存,然后更新关系来更改映射,从而无需更改映射:
AP ap = new AP();
APStatus status = new APStatus();
repository.save(ap);
status.setApId(ap.getId());
statusRepository.save(status);
ap.setApStatus(status);
repository.save(ap);
或者您可以使用JPA 2.0的原始身份更改您的映射,设置级联设置,然后只保存AP或AP状态:
@Entity
public class AP {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="ID", nullable=false)
private int id;
@OneToOne(mappedBy = "ap", cascade=CascadeType.ALL, orphanRemoval = true)
private APStatus apStatus;
//Getters and setters
}
@Entity
public class APStatus {
@Id
@OneToOne
@JoinColumn(name="AP_ID")
private AP ap;
//Getters and setters
}
然后你可以简单地使用:
AP ap = new AP();
APStatus status = new APStatus();
status.setAp(ap);
ap.setApStatus(status);
repository.save(ap);