【发布时间】:2015-02-14 04:09:20
【问题描述】:
我已经阅读了有关 stackoverflow 的几个 Q/A 以及其他几个在线教程,以找到对于下面描述的问题我到底缺少什么。
背景: 我正在学习在我的 android 应用程序中使用 RESTful API,因此,我编写了一个简单的医患管理应用程序。医生和病人之间是一对多的关系。即一个医生可以有很多病人。
问题: 我正在使用一个应该维护所有用户信息的用户表,即在此表中维护医生和患者的基本信息,并且此表还用于确定尝试登录的用户类型,以便适当的屏幕可以呈现。该表的实体如下所示:
@Entity
public class ConcreteUser implements User{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name= "USER_ID")
private long id;
private String name;
private String email;
private int age;
private SEX sex;
private String accessLevel;
public ConcreteUser() {
}
// gettersand setters here
}
此实体与维护医生和患者实体的表具有一对一的关系。如前所述,医生和患者实体具有一对一的关系。下面是这两个实体的样子:
@Entity
public class PatientEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "PATIENT_RECORD_ID")
private long recordId;
// specify this as a foreign key from ConcreteUser entity
@OneToOne(cascade = CascadeType.ALL) /*CascadeType.ALL should not be required according to almost all the tutorials I have seen - But I always get unsaved transient object error if I don't do this and try to save a patient entity */
@JoinColumn(name="USER_ID")
private ConcreteUser patient;
@ManyToOne(cascade = {CascadeType.ALL})
@JoinColumn(name = "DOCTOR_RECORD_ID")
@JsonBackReference
private DoctorEntity doctor;
public PatientEntity() {
}
public void setDoctor(DoctorEntity doctor) {
this.doctor = doctor;
//if(!doctor.getPatients().contains(this)){
// doctor.addPatient(this);
//}
/* Commented out code always leads to stack overflow error */
/* although, according to tutorial in the link below, this code is necessary */
/* http://en.wikibooks.org/wiki/Java_Persistence/OneToMany */
}
// getters and setters are not shown
}
最后,这是我的 Doctor 实体:
@Entity
public class DoctorEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "DOCTOR_RECORD_ID")
private long recordId;
// specify this as a foreign key from ConcreteUser entity
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name="USER_ID")
private ConcreteUser doctor;
@OneToMany(mappedBy = "doctor", cascade = CascadeType.ALL)
@JsonManagedReference
private Collection<PatientEntity> patients = new ArrayList<PatientEntity>();
public DoctorEntity() {
}
public boolean addPatient(PatientEntity p) {
boolean status = false;
status = patients.add(p);
//if (p.getDoctor() != this) {
// p.setDoctor(this);
//}
return status;
}
public boolean removePatient(PatientEntity p) {
boolean status = false;
status = patients.remove(p);
//if (p.getDoctor() != this) {
// p.setDoctor(null);
//}
return status;
}
// getters and setters are not shown. Same problem with the commented out code as described above
}
现在要测试一个事实,即当 PatientEntity 的 POJO 对象可以保存并保留信息时,我使用以下测试用例:
@Test
public void TestPatientDoctorManyToOne() throws Exception{
PatientEntity p1 = TestData.getPatientEntity(patient1);
DoctorEntity d = TestData.getDoctorEntity(doctor);
p1.setDoctor(d);
p1 = patientService.addPatient(p1);
assertNotNull(p1);
PatientEntity p2 = patientService.getPatientById(p1.getRecordId());
assertNotNull(p2);
assertNotNull(p2.getDoctor());
assertEquals(p1.getRecordId(), p2.getRecordId());
assertEquals(p1.getDoctor().getRecordId(), p2.getDoctor().getRecordId());
assertEquals(p1.getDoctor().getDoctor().getEmail(), p2.getDoctor().getDoctor().getEmail());
}
在上述测试用例中,assertNotNull(p2.getDoctor()); 断言失败,因为返回的患者实体根本不包含医生对象。
这是日志:
Outgoing:
"{"recordId":0,"patient":{"id":0,"name":"Patient-0ee1407e-2d2b-4c6c-a57b-e2fad24fafa5","email":"0ee1407e-2d2b-4c6c-a57b-e2fad24fafa5","age":50,"sex":"MALE","accessLevel":"patient"},"doctor":{"recordId":0,"doctor":{"id":0,"name":"Doctor-f025c8ce-8c31-4681-b673-a9e322dccf5a","email":"f025c8ce-8c31-4681-b673-a9e322dccf5a","age":50,"sex":"MALE","accessLevel":"doctor"},"patients":[]}}"
Incoming:
{"recordId":16,"patient":{"id":33,"name":"Patient-0ee1407e-2d2b-4c6c-a57b-e2fad24fafa5","email":"0ee1407e-2d2b-4c6c-a57b-e2fad24fafa5","age":50,"sex":"MALE","accessLevel":"patient"}}
如您所见,返回的对象根本没有 Doctor 实体。
但是,当我尝试保存包含患者的医生实体时,它的保存没有问题。即以下测试用例通过:
@Test
public void testDoctorPatientOneToMany() throws Exception {
PatientEntity p1 = TestData.getPatientEntity(patient1);
PatientEntity p2 = TestData.getPatientEntity(patient2);
DoctorEntity d = TestData.getDoctorEntity(doctor);
d.addPatient(p1);
d.addPatient(p2);
d = doctorService.addDoctor(d);
DoctorEntity d2 = doctorService.getDoctorById(d.getRecordId());
assertNotNull(d2);
assertEquals(d2.getRecordId(), d.getRecordId());
assertEquals(d2.getDoctor().getEmail(), d.getDoctor().getEmail());
}
上述测试用例的交易: 传出:
"{"recordId":17,"doctor":{"id":43,"name":"Doctor-e4baeee7-eaaa-443e-8845-e0b12d7be82f","email":"e4baeee7-eaaa-443e-8845-e0b12d7be82f","age":50,"sex":"MALE","accessLevel":"doctor"},"patients":[{"recordId":21,"patient":{"id":44,"name":"Patient-d8aab5ad-d3d9-4442-b8de-678de9e3b1ce","email":"d8aab5ad-d3d9-4442-b8de-678de9e3b1ce","age":50,"sex":"MALE","accessLevel":"patient"}},{"recordId":22,"patient":{"id":45,"name":"Patient-5c9cfa3c-ee79-4aea-a193-4d8762f58431","email":"5c9cfa3c-ee79-4aea-a193-4d8762f58431","age":50,"sex":"MALE","accessLevel":"patient"}}]}[\r][\n]"
Incoming:
{"recordId":17,"doctor":{"id":43,"name":"Doctor-e4baeee7-eaaa-443e-8845-e0b12d7be82f","email":"e4baeee7-eaaa-443e-8845-e0b12d7be82f","age":50,"sex":"MALE","accessLevel":"doctor"},"patients":[{"recordId":21,"patient":{"id":44,"name":"Patient-d8aab5ad-d3d9-4442-b8de-678de9e3b1ce","email":"d8aab5ad-d3d9-4442-b8de-678de9e3b1ce","age":50,"sex":"MALE","accessLevel":"patient"}},{"recordId":22,"patient":{"id":45,"name":"Patient-5c9cfa3c-ee79-4aea-a193-4d8762f58431","email":"5c9cfa3c-ee79-4aea-a193-4d8762f58431","age":50,"sex":"MALE","accessLevel":"patient"}}]}
我为沿途的帖子道歉,但我认为我已经用尽了所有资源。我绝对崇拜任何决定看一看并指出问题所在的人。在这一点上,我什至不确定我是否正确地测试了这个东西,或者我的期望是否正确。
【问题讨论】:
标签: spring hibernate jpa one-to-many