休眠关系:列“ purchaseId”不能为空

时间:2019-07-19 07:42:55

标签: java spring hibernate spring-boot foreign-keys

我与“购买到详细信息”之间存在“一对多”关系。购买实体具有基本详细信息,而PurchaseDetails将具有已购买项目的列表。我要实现的是将数据保存到购买项目的“购买表”(父项)列表中时,也将自动保存在“购买明细表”(“子项”)中。

  

2019-07-19 13:05:53.581 WARN 8868 --- [nio-8060-exec-2]   o.h.engine.jdbc.spi.SqlExceptionHelper:SQL错误:1048,SQLState:   23000       2019-07-19 13:05:53.581错误8868--[nio-8060-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper:列'purchaseId'无法   为空

Purchase.java

@Entity
@Table(name = "purchase")
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Purchase {

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    @Column(name = "purchaseId")
    private BigInteger purchaseId;

    @ManyToOne(cascade = CascadeType.MERGE)
    @JoinColumn(name="accountId", nullable = false)
    private Account account;

    @JsonBackReference
    @OneToMany(mappedBy="purchase",fetch=FetchType.LAZY,cascade = CascadeType.PERSIST)
    private List<PurchaseDetails> purchaseDetails = new ArrayList<PurchaseDetails>();

    private Date purchaseDate;
    private String name;
    private String address;
    private String whatsapp;
    private String payStatus;
    private int creditDays;
    private Float loading;
    private BigInteger purchaseAmount;
    private BigInteger receivedAmount;
    private String remarks;
    private Date creation;
    private Date lastedit;
    private Boolean isDeleted;

    @PrePersist
    protected void onCreate() {
        creation  = new Date();
        lastedit = new Date();
        isDeleted = false;
    }

}

PurchaseDetails.java

@Entity
@Table(name = "purchaseDetails")
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class PurchaseDetails {

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    private BigInteger purchaseDetailId;

    @ManyToOne(fetch = FetchType.LAZY, targetEntity = Purchase.class)
    @JoinColumn(name="purchaseId", referencedColumnName = "purchaseId", nullable = false)
//  @MapsId(value = "purchaseId")
    private Purchase purchase;

    @OneToOne(cascade = CascadeType.MERGE)
    @JoinColumn(name = "itemId", nullable = false)
    private Item item;

    private Float quantity;
    private Float rate;
    private Float rateGST;
    private Float subTotal;
    private Float subTotalGST;
    private Date creation;
    private Date lastedit;
    private Boolean isDeleted;

    @PrePersist
    protected void onCreate() {
        creation  = new Date();
        lastedit = new Date();
        isDeleted = false;
    }

}

PurchaseService.java

@Service
public class PurchaseService {

    @Autowired PurchaseRepository purchaseRepository;

    public boolean newPurchase(Purchase purchase, StringResponseDTO response)
    {
        if(isValidPurchaseData(purchase))
        {
            System.out.println("Service: "+purchase.toString());
            purchase.setPurchaseDetails(purchase.getPurchaseDetails());
            purchaseRepository.save(purchase);
            response.setMessage("Purchase of "+ purchase.getName() + " is added successfuly");
            return true;
    }
        else
        {
            response.setMessage("Please Provide Valid Data");
            return false;
        }
    }
}

JSON用于邮递员的输入 (值仅用于测试,因此请忽略subTotal等)

{
    "purchaseDate":"2019-07-18T08:37:41.000+0000",
    "name":"PersonName",
    "address":"Besides xyz Hotel, NH - 5, India",
    "whatsapp":"1234567899",
    "payStatus":"Paid",
    "creditDays":"0",
    "purchaseAmount":"2600",
    "receivedAmount":"2600",
    "loading":"100",
    "remarks":"Not Any",
    "purchaseDetails":[
        {

            "quantity":"523.6",
            "rate":"67",
            "rateGST":"70",
            "subTotal":"35081",
            "subTotalGST":"36652",
            "item":{
                "itemId":"14"
            }
        },
        {
            "quantity":"222.6",
            "rate":"67",
            "rateGST":"70",
            "subTotal":"35081",
            "subTotalGST":"36652",
            "item":{
                "itemId":"16"
            }
        }],
    "account":{
        "accountId":"4"
    }
}

2 个答案:

答案 0 :(得分:1)

您与父母和孩子建立了双向关系。如果要使用级联保存父级及其子级,则还需要将父级设置在子级上,否则会出现错误。请尝试:

for (PurchaseDetail purchaseDetail : purchase.getPurchaseDetails()) {
    purchaseDetail.setPurchase(purchase);
}
purchase.setPurchaseDetails(purchase.getPurchaseDetails());
purchaseRepository.save(purchase);

答案 1 :(得分:0)

您需要在Purchase和PurchaseDetails之间建立许多关系,然后应在PurchaseDetails中传递Purchase ID来建立关系,因此:
1)在服务层中,您应该首先添加购买,而无需设置PurchaseDetails
2)添加所有与第1步中添加的购买相同的PurchaseDetails。

@Service
public class PurchaseService {

@Autowired 
PurchaseRepository purchaseRepository;


@Autowired 
PurchaseDetailsRepository purchaseDetailsRepository;


public boolean newPurchase(Purchase purchase, StringResponseDTO response)
{
    if(!isValidPurchaseData(purchase))
    {
        System.out.println("Service: "+purchase.toString());
       //yo should have all PurchaseDetails in a list pay attention this list not null
       List<PurchaseDetails> purchaseDetails=purchase.getPurchaseDetails();
       //step 1
        purchase=purchaseRepository.save(purchase);
        response.setMessage("Purchase of "+ purchase.getName() + " is added successfuly");
        for(PurchaseDetails adddetail:purchaseDetails){
            //step 2
            adddetail.setPurchase(purchase);
            purchaseDetailsRepository.save(adddetail);
        }
        return true;
}
    else
    {
        response.setMessage("Please Provide Valid Data");
        return false;
    }
}
}