Java OneToMany双向映射未保存其外键
我在员工和电话实体之间有一对多关系,如下所示:Java OneToMany双向映射未保存其外键,java,hibernate,Java,Hibernate,我在员工和电话实体之间有一对多关系,如下所示: @Entity public class Employee { @Id @Column(name = "EMP_ID") private long id; private String name; @OneToMany(mappedBy = "owner") private List<Phone> phones = new ArrayList<Phone>(); } @E
@Entity
public class Employee {
@Id
@Column(name = "EMP_ID")
private long id;
private String name;
@OneToMany(mappedBy = "owner")
private List<Phone> phones = new ArrayList<Phone>();
}
@Entity
public class Phone {
@Id
private long id;
private String phoneNumber;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "OWNER_ID")
private Employee owner;
}
然后我查看并插入查询以保存员工,然后插入查询以保存电话,然后更新查询以更新电话表中的所有者id
因此,为了避免在电话表上插入和更新,我在我的电话实体中添加了以下映射:
@Entity
public class Phone {
...
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "OWNER_ID", insertable=false, updatable=false)
private Employee owner;
}
在本例中,我在Employee上看到insert,然后在Phone上看到insert,但所有者id为null
如何确保在保存实体时所有者id不为空?我想在我的代码中保存Phone然后再保存Employee,而不是相反。因为Phone是一个子实体,所以需要引用Employee进行保存。 通过使用cascadeType注释电话,您的电话将与您的员工实体一起保存。您修改的实体如下所示:
@Entity
public class Employee {
@Id
@Column(name = "EMP_ID")
private long id;
private String name;
@OneToMany(mappedBy = "owner",cascade = CascadeType.ALL)
private List<Phone> phones = new ArrayList<Phone>();
/*getters and setters*/
}
@Entity
public class Phone {
@Id
private long id;
private String phoneNumber;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "OWNER_ID", insertable=false, updatable=false,nullable=false)
private Employee owner;
/*getters and setters*/
}
@实体
公营雇员{
@身份证
@列(name=“EMP\u ID”)
私人长id;
私有字符串名称;
@OneToMany(mappedBy=“owner”,cascade=CascadeType.ALL)
私有列表电话=新的ArrayList();
/*接球手和接球手*/
}
@实体
公用电话{
@身份证
私人长id;
私有字符串电话号码;
@manytone(fetch=FetchType.LAZY)
@JoinColumn(name=“OWNER\u ID”,insertable=false,updateable=false,nullable=false)
私人雇员业主;
/*接球手和接球手*/
}
并且必须修改您的保存逻辑,如下所示:
Employee emp = new Employee();
private List<Phone> phones = new ArrayList<Phone>();
Phone phone = new Phone();
phone.setOwner(emp);
phones.add(phone);
emp.setPhones(phones);
session.save(emp);
Employee emp=新员工();
私有列表电话=新的ArrayList();
电话=新电话();
设置所有者(emp);
电话。添加(电话);
电磁波固定电话(电话);
会话保存(emp);
根据您的要求,无需使用双向。尝试以下步骤
@ManyToOne
。因此,从员工实体中删除@OneToMany
声明session.save(obj)
返回对象的id。所以,只需先保存Phone并捕获id
,然后保存employee即可。参见示例
session.save(phone);
long phoneOneId = phone.getId();
Phone phoneOne = new Phone();
phoneOne.setId(phoneOneId);
// You can also add another phone like phoneTwo, phoneThree, ...
List<Phone> phones = new ArrayList<Phone>();
phones.add(phoneOne);
employee.setPhones(phones);
session.save(电话);
long phoneOneId=phone.getId();
Phone phoneOne=新手机();
phoneOne.setId(phoneOneId);
//您还可以添加另一部手机,如phoneTwo、phoneTwo等。。。
列表电话=新的ArrayList();
phones.add(phoneOne);
员工。设置电话(电话);
我不想在这里使用cascade,您正在保存员工,但我想先保存电话,然后再显式保存员工。所以我的方法不可能吗?@user3181365我猜不可能,因为您说过在保存手机时需要
OWNER\u ID
作为非空字段。在这种情况下,Phone
将不会首先保存,并将抛出错误,因为OWNER\u ID
为空。因此,必须先保存员工,然后保存电话。
session.save(phone);
long phoneOneId = phone.getId();
Phone phoneOne = new Phone();
phoneOne.setId(phoneOneId);
// You can also add another phone like phoneTwo, phoneThree, ...
List<Phone> phones = new ArrayList<Phone>();
phones.add(phoneOne);
employee.setPhones(phones);