Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JPA OneToMany Cacade.ALL为父级创建两个条目_Jpa_Cascade_One To Many - Fatal编程技术网

JPA OneToMany Cacade.ALL为父级创建两个条目

JPA 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

我们在项目中使用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);  //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方法返回的实例是持久的和附加的。