JPA OneToMany Cacade.ALL为父级创建两个条目
我们在项目中使用JPA Hibernate 我们有一个实体,比如a,它有一个实体B的列表 在A中,B的列表上有一个“一家公司” 在B中,a上有一个多音 在A中,对于B的列表,我已经放置了CascadeType.ALL,并且有一个将B添加到A中的方法 我只通过A保存所有B实体 假设我创建A1并添加两个B。。B1和B2插入A并保存AJPA OneToMany Cacade.ALL为父级创建两个条目,jpa,cascade,one-to-many,Jpa,Cascade,One To Many,我们在项目中使用JPA Hibernate 我们有一个实体,比如a,它有一个实体B的列表 在A中,B的列表上有一个“一家公司” 在B中,a上有一个多音 在A中,对于B的列表,我已经放置了CascadeType.ALL,并且有一个将B添加到A中的方法 我只通过A保存所有B实体 假设我创建A1并添加两个B。。B1和B2插入A并保存A A a1 = createA(...); B b1 = createB(....); B b2 = createB(....); a1.addB(b1); //I
A a1 = createA(...);
B b1 = createB(....);
B b2 = createB(....);
a1.addB(b1); //Internally does b1.setA(this) as well
a1.addB(b2); //Internally does b1.setA(this) as well
a1 = ADao.save(a1);
但是,当数据库中的条目被创建时,将创建一个数据库的两个条目
一个id=0,一个id=1。。b1和b2的条目是指id为0的A条目
但是,如果我们先保存a1,然后将b1、b2添加到a1,然后再次保存a1,则效果很好,并且只为A创建了一个id为1的条目
请让我知道我做错了什么,或者它的工作方式应该是什么
谢谢
此处实体A=票据,B=BillLineitem
类的代码:
@Entity
@Table(name = "bills")
public class Bill implements Serializable {
private static final long serialVersionUID = -6523700369290034565L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private long id;
...
@Basic
@Column(name = "bill_number", nullable = false)
private String billNumber;
@Basic
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "date", nullable = false)
private Date billDate;
@Basic
@Column(name = "bill_amount", nullable = false)
private float billAmount;
..
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
//@JoinColumn(referencedColumnName = "id")
@JoinColumn(name = "bill_id", nullable = true)
private List<BillLineitem> billLineitems;
/**
* @return the id
*/
public long getId() {
return id;
}
...
/**
* @return the billLineitems
*/
public List<BillLineitem> getBillLineitems() {
return billLineitems;
}
/**
* @param billLineitems the billLineitems to set
*/
public void setBillLineitems(final List<BillLineitem> billLineitems) {
this.billLineitems = billLineitems;
for (BillLineitem billLineitem : this.billLineitems) {
billLineitem.setBill(this);
billLineitem.setBillDate(this.getBillDate());
billLineitem.setOrganization(this.getOrganization());
billLineitem.setStore(this.getStore());
billLineitem.setUser(this.getUser());
}
}
public void addBillLineitem(BillLineitem billLineitem)
{
billLineitem.setBill(this);
billLineitem.setBillDate(this.getBillDate());
billLineitem.setOrganization(this.getOrganization());
billLineitem.setStore(this.getStore());
billLineitem.setUser(this.getUser());
if(this.billLineitems == null)
this.billLineitems = new ArrayList<BillLineitem>();
this.billLineitems.add(billLineitem);
}
....
}
@Entity
@Table(name = "bill_lineitems")
public class BillLineitem implements Serializable {
private static final long serialVersionUID = -4094587645624924794L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private long id;
@ManyToOne
@JoinColumn(name = "bill_id", nullable = false)
private Bill bill;
@Basic
@Column(name = "item_code", nullable = false)
private String itemCode;
@Basic
@Column(name = "amount", nullable = false)
private float amount;
/**
* @return the id
*/
public long getId() {
return id;
}
/**
* @return the bill
*/
public Bill getBill() {
return bill;
}
/**
* @param bill the bill to set
*/
public void setBill(final Bill bill) {
this.bill = bill;
}
..
/**
* @return the serial
*/
public int getSerial() {
return serial;
}
/**
* @param serial the serial to set
*/
public void setSerial(final int serial) {
this.serial = serial;
}
/**
* @return the itemCode
*/
public String getItemCode() {
return itemCode;
}
/**
* @param itemCode the itemCode to set
*/
public void setItemCode(final String itemCode) {
this.itemCode = itemCode;
}
...
}
@实体
@表(name=“bills”)
公共类法案实现了可序列化{
私有静态最终长serialVersionUID=-6523700369290034565L;
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
@列(name=“id”,nullable=false)
私人长id;
...
@基本的
@列(name=“bill\u number”,nullable=false)
私有字符串billNumber;
@基本的
@时态(TemporalType.TIMESTAMP)
@列(name=“date”,null=false)
私人日期;
@基本的
@列(name=“bill\u amount”,nullable=false)
私人浮动票据金额;
..
@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL)
//@JoinColumn(referencedColumnName=“id”)
@JoinColumn(name=“bill\u id”,nullable=true)
私人清单项目;
/**
*@返回id
*/
公共长getId(){
返回id;
}
...
/**
*@返回billLineitems
*/
公共列表getBillLineitems(){
返回billLineitems;
}
/**
*@param billLineitems要设置的billLineitems
*/
公共无效设置billLineitems(最终列表billLineitems){
this.billLineitems=billLineitems;
对于(BillLineitem BillLineitem:this.billLineitems){
billLineitem.setBill(本);
billLineitem.setBillDate(this.getBillDate());
billLineitem.setOrganization(this.getOrganization());
billLineitem.setStore(this.getStore());
billLineitem.setUser(this.getUser());
}
}
公共无效添加BillLineitem(BillLineitem BillLineitem)
{
billLineitem.setBill(本);
billLineitem.setBillDate(this.getBillDate());
billLineitem.setOrganization(this.getOrganization());
billLineitem.setStore(this.getStore());
billLineitem.setUser(this.getUser());
如果(this.billLineitems==null)
this.billLineitems=新建ArrayList();
此.billLineitems.add(billLineitem);
}
....
}
@实体
@表(name=“bill\u行项目”)
公共类BillLineitem实现可序列化{
私有静态最终长serialVersionUID=-4094587645624794L;
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
@列(name=“id”,nullable=false)
私人长id;
@许多酮
@JoinColumn(name=“bill\u id”,nullable=false)
私人法案;
@基本的
@列(name=“item\u code”,null=false)
私有字符串项代码;
@基本的
@列(name=“amount”,nullable=false)
私人浮动金额;
/**
*@返回id
*/
公共长getId(){
返回id;
}
/**
*把账单还回去
*/
公共条例草案{
退票;
}
/**
*@param bill要设置的账单
*/
公共票据(最终票据){
this.bill=比尔;
}
..
/**
*@返回序列号
*/
public int getSerial(){
返回序列号;
}
/**
*@param serial要设置的序列号
*/
公共无效设置序列(最终整数序列){
this.serial=serial;
}
/**
*@返回项目代码
*/
公共字符串getItemCode(){
返回项目代码;
}
/**
*@param itemCode要设置的itemCode
*/
public void setItemCode(最终字符串itemCode){
this.itemCode=itemCode;
}
...
}
这是因为您映射了两次相同的双向关联:一次在账单中(在项目列表中使用@JoinColumn(name=“Bill\u id”,nullable=true)
),一次在账单行项目中(在账单字段中使用@JoinColumn(name=“Bill\u id”,nullable=false)
)
OneToMany侧应标记为多个单侧的反向关联,项目列表应仅用@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL,mappedBy=“bill”)
注释。删除@JoinColumn
注释。您能发布A类、B类和ADao类的代码吗?很抱歉响应太晚。谢谢。这很有效。在任何地方都会这样做。另外,当我执行a1.add(b1)和a1=aDao.save(a1)时,b1.id仍然是0,但它的1位于a1中的同一b1中。既然b1和a1中的一个都指向同一个实例,为什么b1的id没有更新?你应该问另一个问题。合并不会使实体持久化。它返回所传递实体的持久副本。合并之后,您就有了实例:作为参数传递的实例是暂时的,而merge方法返回的实例是持久的和附加的。