My relationship like this which is shown in image :
enter image description here
I'm having troubling with insert data in database because of bill id saved little bit late and that time also buybill save simultaneously in database and which want to bill id to save in relationship and throw exception like invoice id not found and only my bill data saved in database and buybill thrwo exception of not found bill id so please help me out.
Thanks,
And one more thing that i include that my postmapping of :
This--->
#PostMapping(value="/customers/{customerId}/bills/{InvoiceNo}/buyBills",produces="application/json",consumes="application/json")
and
This--->
#PostMapping(value="/customers/{customerId}/bills/{InvoiceNo}/bills",produces="application/json",consumes="application/json")
by two $http.post() simultaneously with one angularjs submit button in html.
This is my javascript code of post two http request by angular.js onclick of $scope.purchase function where there i post two url which mapped above URL1 and URL2 with json data and BillData, buyBillFormss.html code :
<script type="text/javascript">
var invoice = angular.module('invoice', []);
invoice.controller('InvoiceController', function($scope,$window,$http){
$scope.purchase = function(){
if(!$scope.myForm.$valid){
console.log("Invalid")
$scope.err = "Invaid Transaction Please Insert valid field or Refresh!!!";
}
if($scope.myForm.$valid){
angular.forEach($scope.invoice.items, function(item){
var Bill = [];
$scope.am = (((item.qty * item.price)+((item.qty * item.price)*item.gst)/100)-item.dis).toFixed(2);
angular.forEach($scope.invoice.items, function (value, key) {
var am = (((value.qty * value.price)+((value.qty * value.price)*value.gst)/100)-value.dis).toFixed(2);
Bill.push({
"proId" : value.proId,
"name" : value.name,
"description" : value.description,
"qty" : value.qty,
"unit" : value.unit,
"price" : value.price,
"dis" : value.dis,
"gst" : value.gst,
"amount" : am
});
});
console.log("Bill ::");
console.log(Bill);
localStorage.setItem("data",JSON.stringify(Bill));
///////////////////////////////////////////////////////
var id = document.getElementById("ids").innerText;
var InvoiceNo = document.getElementById("InvoiceNo").innerText;
var data={
"proId" : item.proId,
"name" : item.name,
"description" : item.description,
"qty" : item.qty,
"unit" : item.unit,
"price" : item.price,
"dis" : item.dis,
"gst" : item.gst,
"amount" : $scope.am
};
console.log("Data ::");
console.log(data);
$scope.CustomerId = id;
$scope.InvoiceNo = InvoiceNo;
var URL1 = "http://localhost:8083/cust/customers/"+$scope.CustomerId+"/bills/"+$scope.InvoiceNo+"/buyBills";
$http.post(URL1, data);
});
//angular.forEach($scope.invoice.items, function(item){
var id = document.getElementById("ids").innerText;
var name = document.getElementById("name").innerText;
var InvoiceNo = document.getElementById("InvoiceNo").innerText;
var address = document.getElementById("address").innerText;
var mobileNo = document.getElementById("mobileNo").innerText;
var note = document.getElementById("n").value;
var InterestRate = document.getElementById("i").value;
var CredibilityStatus = "very Good";
var guarantorName = document.getElementById("g").value;
var BillData={
"invoiceNo" : InvoiceNo,
"name" : name,
"address" : address,
"mobileNo" : mobileNo,
"totalGSTAmount" : ($scope.GST()).toFixed(2),
"totalDiscountAmount" : $scope.Dis(),
"guarantorName" : guarantorName,
"totalAmount" : ($scope.TotalAmount()).toFixed(2),
"paidAmount" : ($scope.PaidAmount()).toFixed(2),
"dueAmount" : ($scope.DueAmount()).toFixed(2),
"status" : $scope.Status(),
"interestRate" : InterestRate,
"credibilityStatus" : CredibilityStatus,
"note" : note
};
console.log("BillData ::");
console.log(BillData);
$scope.CustomerId = id;
$scope.InvoiceNo = InvoiceNo;
var URL2 = "http://localhost:8083/cust/customers/"+$scope.CustomerId+"/bills/"+$scope.InvoiceNo+"/bills";
$http.post(URL2, BillData);
localStorage.setItem("dataAct",JSON.stringify(BillData));
//});
$window.location.href = "/Bill"
}
}
});
</script>
My code is here :
This is my customer.java entity :
package com.alpha.demo.model;
import java.io.Serializable;
import java.util.Date;
import java.util.Set;
import java.util.UUID;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.hibernate.annotations.CreationTimestamp;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
#Entity
#Table(name = "customers")
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Customer implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "uniqueId", updatable = false, nullable = false)
private UUID uniqueId = UUID.randomUUID();
#Column(columnDefinition = "TEXT")
private String photos;
private String fullName;
private String aadhaarNo;
private String guarantor;
private String address;
private String mobileNo;
private String note;
#CreationTimestamp
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "create_date",updatable=false)
private Date createDate;
#OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<Bill> Bill;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public UUID getUniqueId() {
return uniqueId;
}
public void setUniqueId(UUID uniqueId) {
this.uniqueId = uniqueId;
}
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public String getPhotos() {
return photos;
}
public void setPhotos(String photos) {
this.photos = photos;
}
public String getAadhaarNo() {
return aadhaarNo;
}
public void setAadhaarNo(String aadhaarNo) {
this.aadhaarNo = aadhaarNo;
}
public String getGuarantor() {
return guarantor;
}
public void setGuarantor(String guarantor) {
this.guarantor = guarantor;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getMobileNo() {
return mobileNo;
}
public void setMobileNo(String mobileNo) {
this.mobileNo = mobileNo;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
public Set<Bill> getBill() {
return Bill;
}
public void setBill(Set<Bill> bill) {
Bill = bill;
}
public Customer(String photos, String fullName, String aadhaarNo, String guarantor, String address, String mobileNo,
String note, Date createDate) {
super();
this.photos = photos;
this.fullName = fullName;
this.aadhaarNo = aadhaarNo;
this.guarantor = guarantor;
this.address = address;
this.mobileNo = mobileNo;
this.note = note;
this.createDate = createDate;
}
public Customer() {
}
}
This is my Bill.java entity :
package com.alpha.demo.model;
import java.io.Serializable;
import java.util.Date;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.hibernate.annotations.CreationTimestamp;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
#Entity
#Table(name = "bills")
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Bill implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long invoiceNo;
private String guarantorName;
private String TotalGSTAmount;
private String TotalDiscountAmount;
private String TotalAmount;
private String PaidAmount;
private String DueAmount;
private String InterestRate;
private String TotalInterestAmount;
private String Status;
private String CredibilityStatus;
private String Note;
#CreationTimestamp
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "billing_date",updatable=false)
private Date BillingDate;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "customer_id", nullable = false)
#JsonIgnore
private Customer customer;
#OneToMany(mappedBy = "bill", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<BuyBill> BuyBill;
public Bill() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getInvoiceNo() {
return invoiceNo;
}
public void setInvoiceNo(Long invoiceNo) {
this.invoiceNo = invoiceNo;
}
public String getGuarantorName() {
return guarantorName;
}
public void setGuarantorName(String guarantorName) {
this.guarantorName = guarantorName;
}
public String getTotalAmount() {
return TotalAmount;
}
public void setTotalAmount(String totalAmount) {
TotalAmount = totalAmount;
}
public String getPaidAmount() {
return PaidAmount;
}
public void setPaidAmount(String paidAmount) {
PaidAmount = paidAmount;
}
public String getDueAmount() {
return DueAmount;
}
public void setDueAmount(String dueAmount) {
DueAmount = dueAmount;
}
public String getInterestRate() {
return InterestRate;
}
public void setInterestRate(String interestRate) {
InterestRate = interestRate;
}
public String getTotalInterestAmount() {
return TotalInterestAmount;
}
public void setTotalInterestAmount(String totalInterestAmount) {
TotalInterestAmount = totalInterestAmount;
}
public String getStatus() {
return Status;
}
public void setStatus(String status) {
Status = status;
}
public String getTotalGSTAmount() {
return TotalGSTAmount;
}
public void setTotalGSTAmount(String totalGSTAmount) {
TotalGSTAmount = totalGSTAmount;
}
public String getTotalDiscountAmount() {
return TotalDiscountAmount;
}
public void setTotalDiscountAmount(String totalDiscountAmount) {
TotalDiscountAmount = totalDiscountAmount;
}
public Date getBillingDate() {
return BillingDate;
}
public void setBillingDate(Date billingDate) {
BillingDate = billingDate;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
public Set<BuyBill> getBuyBill() {
return BuyBill;
}
public void setBuyBill(Set<BuyBill> buyBill) {
BuyBill = buyBill;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
public String getCredibilityStatus() {
return CredibilityStatus;
}
public void setCredibilityStatus(String credibilityStatus) {
CredibilityStatus = credibilityStatus;
}
public String getNote() {
return Note;
}
public void setNote(String note) {
Note = note;
}
public Bill(Long id, Long invoiceNo, String guarantorName, String totalGSTAmount, String totalDiscountAmount,
String totalAmount, String paidAmount, String dueAmount, String interestRate, String totalInterestAmount,
String status, String credibilityStatus, String note, Date billingDate, Customer customer,
Set<com.alpha.demo.model.BuyBill> buyBill) {
super();
this.id = id;
this.invoiceNo = invoiceNo;
this.guarantorName = guarantorName;
TotalGSTAmount = totalGSTAmount;
TotalDiscountAmount = totalDiscountAmount;
TotalAmount = totalAmount;
PaidAmount = paidAmount;
DueAmount = dueAmount;
InterestRate = interestRate;
TotalInterestAmount = totalInterestAmount;
Status = status;
CredibilityStatus = credibilityStatus;
Note = note;
BillingDate = billingDate;
this.customer = customer;
BuyBill = buyBill;
}
#Override
public String toString() {
return "Bill [id=" + id + ", invoiceNo=" + invoiceNo + ", guarantorName=" + guarantorName + ", TotalGSTAmount="
+ TotalGSTAmount + ", TotalDiscountAmount=" + TotalDiscountAmount + ", TotalAmount=" + TotalAmount
+ ", PaidAmount=" + PaidAmount + ", DueAmount=" + DueAmount + ", InterestRate=" + InterestRate
+ ", TotalInterestAmount=" + TotalInterestAmount + ", Status=" + Status + ", CredibilityStatus="
+ CredibilityStatus + ", Note=" + Note + ", BillingDate=" + BillingDate + ", customer=" + customer
+ ", BuyBill=" + BuyBill + "]";
}
}
This is my BuyBill entity :
package com.alpha.demo.model;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
#Entity
#Table(name = "buyBills")
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class BuyBill implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long proId;
private String name;
private String description;
private String qty;
private String unit;
private String price;
private String dis;
private String gst;
private String amount;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "bill_id", nullable = false)
#JsonIgnore
private Bill bill;
public BuyBill(Long id, Long proId, String name, String description, String qty, String unit, String price,
String dis, String gst, String amount, Bill bill) {
super();
this.id = id;
this.proId = proId;
this.name = name;
this.description = description;
this.qty = qty;
this.unit = unit;
this.price = price;
this.dis = dis;
this.gst = gst;
this.amount = amount;
this.bill = bill;
}
public BuyBill() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getQty() {
return qty;
}
public void setQty(String qty) {
this.qty = qty;
}
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getDis() {
return dis;
}
public void setDis(String dis) {
this.dis = dis;
}
public String getGst() {
return gst;
}
public void setGst(String gst) {
this.gst = gst;
}
public String getAmount() {
return amount;
}
public void setAmount(String amount) {
this.amount = amount;
}
public Bill getBill() {
return bill;
}
public void setBill(Bill bill) {
this.bill = bill;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
public Long getProId() {
return proId;
}
public void setProId(Long proId) {
this.proId = proId;
}
}
This is my JPA Repositories of bill :
package com.alpha.demo.Repository;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import com.alpha.demo.model.Bill;
public interface BillRepository extends JpaRepository<Bill, Long>{
List<Bill> findByCustomerId(Long custoemrId);
#Query(value = "SELECT MAX(id) FROM bills", nativeQuery = true)
Long getNextSeriesId();
Optional <Bill> findByinvoiceNo(Long invoiceNo);
}
This is my bill Controller where i perform crud operations :
package com.alpha.demo.controller;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import com.alpha.demo.Repository.BillRepository;
import com.alpha.demo.Repository.BuyBillRepository;
import com.alpha.demo.Repository.CustomerRepository;
import com.alpha.demo.exception.NotFoundException;
import com.alpha.demo.model.Bill;
import com.alpha.demo.model.BuyBill;
import com.alpha.demo.model.Customer;
#RestController
#RequestMapping("/cust")
public class BillController {
#Autowired
private BillRepository BillRepository;
#Autowired
private BuyBillRepository buyBillRepository;
#Autowired
private CustomerRepository customerRepository;
#GetMapping("/customersBuyBill/{id}")
public ModelAndView showUpdateForm(#PathVariable("id") long id, #ModelAttribute #Valid #RequestBody Bill bill,
#ModelAttribute #Valid #RequestBody BuyBill buyBill, Model model) {
ModelAndView mv = new ModelAndView("buyBillFormss.html");
Customer ct = customerRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("Invalid user Id:" + id));
model.addAttribute("ct", ct);
model.addAttribute("bill", bill);
model.addAttribute("buyBill", buyBill);
//BillRepository.getNextSeriesId();
if(BillRepository.getNextSeriesId()==null) {
Long InvoiceNo = (long) 1;
model.addAttribute("invoiceNo", InvoiceNo);
}
if(BillRepository.getNextSeriesId()!=null) {
Long InvoiceNo = BillRepository.getNextSeriesId() + 1;
model.addAttribute("invoiceNo", InvoiceNo);
}
return mv;
}
#PostMapping(value="/customers/{customerId}/bills/{invoiceNo}/bills",produces="application/json",consumes="application/json")
#ResponseBody
public ModelAndView addBillRequest(#PathVariable Long customerId, #PathVariable Long invoiceNo,#Valid #RequestBody Bill bill) {
return customerRepository.findById(customerId) .map(customer -> {
bill.setCustomer(customer);
BillRepository.save(bill);
ModelAndView mv = new ModelAndView("redirect:/cust/customersBuyBill/{customerId}");
return mv;
}).orElseThrow(() -> new NotFoundException("Customer not found!"));
}
#PostMapping(value="/customers/{customerId}/bills/{invoiceNo}/buyBills",produces="application/json",consumes="application/json")
#ResponseBody
public ModelAndView addBuyBillRequest(#PathVariable Long customerId, #PathVariable Long invoiceNo,#Valid #RequestBody BuyBill buyBill){
System.out.println(invoiceNo);
System.out.println(BillRepository.findByinvoiceNo(invoiceNo));
return BillRepository.findByinvoiceNo(invoiceNo).map(bills -> {
buyBill.setBill(bills);
buyBillRepository.save(buyBill);
ModelAndView mv = new ModelAndView("redirect:/cust/customersBuyBill/{customerId}"); return mv;
}).orElseThrow(() -> new NotFoundException("Invoice No not found!"));
}
}
Throw this exception :
5
Hibernate: select bill0_.id as id1_0_, bill0_.billing_date as billing_2_0_, bill0_.credibility_status as credibil3_0_, bill0_.due_amount as due_amou4_0_, bill0_.interest_rate as interest5_0_, bill0_.note as note6_0_, bill0_.paid_amount as paid_amo7_0_, bill0_.status as status8_0_, bill0_.total_amount as total_am9_0_, bill0_.total_discount_amount as total_d10_0_, bill0_.totalgstamount as totalgs11_0_, bill0_.total_interest_amount as total_i12_0_, bill0_.customer_id as custome15_0_, bill0_.guarantor_name as guarant13_0_, bill0_.invoice_no as invoice14_0_ from bills bill0_ where bill0_.invoice_no=?
Optional.empty
Hibernate: select bill0_.id as id1_0_, bill0_.billing_date as billing_2_0_, bill0_.credibility_status as credibil3_0_, bill0_.due_amount as due_amou4_0_, bill0_.interest_rate as interest5_0_, bill0_.note as note6_0_, bill0_.paid_amount as paid_amo7_0_, bill0_.status as status8_0_, bill0_.total_amount as total_am9_0_, bill0_.total_discount_amount as total_d10_0_, bill0_.totalgstamount as totalgs11_0_, bill0_.total_interest_amount as total_i12_0_, bill0_.customer_id as custome15_0_, bill0_.guarantor_name as guarant13_0_, bill0_.invoice_no as invoice14_0_ from bills bill0_ where bill0_.invoice_no=?
2021-01-27 16:58:05.945 WARN 7652 --- [nio-8083-exec-9] .w.s.m.a.ResponseStatusExceptionResolver : Resolved [com.alpha.demo.exception.NotFoundException: Invoice No not found!]
Hibernate: select customer0_.id as id1_3_0_, customer0_.aadhaar_no as aadhaar_2_3_0_, customer0_.address as address3_3_0_, customer0_.create_date as create_d4_3_0_, customer0_.full_name as full_nam5_3_0_, customer0_.guarantor as guaranto6_3_0_, customer0_.mobile_no as mobile_n7_3_0_, customer0_.note as note8_3_0_, customer0_.photos as photos9_3_0_, customer0_.unique_id as unique_10_3_0_ from customers customer0_ where customer0_.id=?
Hibernate: insert into bills (billing_date, credibility_status, due_amount, interest_rate, note, paid_amount, status, total_amount, total_discount_amount, totalgstamount, total_interest_amount, customer_id, guarantor_name, invoice_no) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Main problem ::
In Brief Bill id in "BillRepository.findById(InvoiceNo)" is empty when both bill and buybill save simultaneously.
I notice that in Bill you have #generatedValue on invoiceId. I don't think you can use #generatedValue on a non #Id field. See this post.
I assume your exception occurs at this point?
// return BillRepository.findById(InvoiceNo).map(bills -> {
// buyBill.setBill(bills);
// buyBillRepository.save(buyBill);
// ModelAndView mv = new ModelAndView("redirect:/cust/customersBuyBill/{customerId}"); return mv;
// }).orElseThrow(() -> new NotFoundException("Invoice No not found!"));
If so then you try to find a Bill by id (BillRepository.findById) but providing a invoiceNo instead of the concrete id
repository.findById refers to the #Id annotated column. In your case:
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Therefore you need to use / implement the method findByInvoiceNo to get your concrete Bill by the provided invoiceNo instead of findById
Edit
Your Bill repository shall contain this method
public interface BillRepository extends JpaRepository<Bill, Long> {
Bill findByInvoiceNo(String invoiceNo);
}
and then
return BillRepository.findB<InvoiceNo(InvoiceNo).map(bills -> {
buyBill.setBill(bills);
buyBillRepository.save(buyBill);
ModelAndView mv = new ModelAndView("redirect:/cust/customersBuyBill/{customerId}"); return mv;
}).orElseThrow(() -> new NotFoundException("Invoice No not found!"));
Edit #2
#PostMapping(value="/customers/{customerId}/bills/{invoiceNo}/buyBills",produces="application/json",consumes="application/json")
#ResponseBody
public ModelAndView addBuyBillRequest(#PathVariable Long customerId, #PathVariable Long invoiceNo,#Valid #RequestBody BuyBill buyBill){
System.out.println(invoiceNo);
System.out.println(BillRepository.findByinvoiceNo(invoiceNo));
return BillRepository.findByinvoiceNo(invoiceNo).map(bills -> {
buyBill.setBill(bills);
buyBillRepository.save(buyBill);
ModelAndView mv = new ModelAndView("redirect:/cust/customersBuyBill/{customerId}"); return mv;
}).orElseThrow(() -> new NotFoundException("Invoice No not found!"));
}
Shouldn't it be
return BillRepository.findByinvoiceNo(invoiceNo).map(bills -> {
bills.addBuyBill(buyBill);
billsRepository.save(bills);
and in the Bill class:
public class Bill implements Serializable {
public void addBuyBill(BuyBill buyBill) {
this.BuyBill.add(buyBill);
buyBill.setBill(this)
}
}
Same goes for this part
return customerRepository.findById(customerId) .map(customer -> {
bill.setCustomer(customer);
BillRepository.save(bill);
ModelAndView mv = new ModelAndView("redirect:/cust/customersBuyBill/{customerId}");
return mv;
}).orElseThrow(() -> new NotFoundException("Customer not found!"));
}
As customer holds none or more bills you need to add a synchronization method like before:
return customerRepository.findById(customerId) .map(customer -> {
customer.addBill(bill);
CustomerRepository.save(customer);
ModelAndView mv = new ModelAndView("redirect:/cust/customersBuyBill/{customerId}");
return mv;
}).orElseThrow(() -> new NotFoundException("Customer not found!"));
}
And in customer
public class Customer implements Serializable {
public void addBill(Bill newBill) {
this.Bill.add(newBill);
newBill.setCustomer(this)
}
}
As you are using a bi-directional association you should keep them synchronized. Otherwise the state transitions of the entities may not work.
Sorry for the long term investigation. But the code makes it hard to identify.
You should definitely think about some refactoring. But this would go beyond the scope of this question.
I have two Classes, Fount and Criterions, the first one is one to many and the other many to one. When i call delete i get the error mentioned in the title.
I tried a lot of solutions here in stackoverflow and other sites about the same problem, but i can't do it right, i'll be glad if someone find out
Solutions i tried:
Cascade - as you can see, i'm already using the annotation, and i tried a lot of different annotations that i found in the internet
Remove the object Criterion from the object Fount and then the Fount from the Criterion before deleting the Criterion from the database
Remove from Fount object and updating the database right after it
The error:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
Cannot delete or update a parent row: a foreign key constraint fails
(mydb.fount_criterion, CONSTRAINT
FK5p3wsropwaokyta6cmy3edvcv FOREIGN KEY (criterions_id) REFERENCES
criterion (id))
my classes Fount and Criterion:
package br.com.engcon.entities;
import javax.persistence.*;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
#Entity
#Table(name = "fount")
//#SequenceGenerator(name="SEQUENCE", sequenceName="fount_id_seq")
public class Fount {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Column(nullable=false, name="url")
private String url;
#OneToMany(fetch = FetchType.LAZY, targetEntity = Criterion.class)
#Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE})
private List<Criterion> criterions;
//
// #OneToMany(fetch = FetchType.LAZY, targetEntity = Text.class, orphanRemoval = true)
// #Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE})
// private List<Text> texts;
#Column(nullable=false, name="isUsed")
private boolean isUsed = false;
#Column(nullable=false, name="isActive")
private boolean isActive = true;
#Column(nullable=false, name="isDeleted")
private boolean isDeleted = false;
public Fount(String url) throws URISyntaxException {
this.url = url;
this.criterions = new ArrayList<Criterion>();
new URI(url);
}
public Fount(String url, List<Criterion> criterions) {
this.url = url;
this.criterions = criterions != null? criterions : new ArrayList<Criterion>();
}
public Fount() {
this.criterions = new ArrayList<Criterion>();
}
public URI getURI() {
if(!url.isEmpty()) {
try {
return new URI(url);
} catch (URISyntaxException e) {
return null;
}
}
return null;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public List<Criterion> getCriterions() {
return criterions;
}
public void setCriterions(List<Criterion> criterions) {
this.criterions = criterions;
}
public void setUrl(String url) {
this.url = url;
}
public void addCriterions(List<Criterion> criterions){
this.criterions = this.criterions != null? this.criterions : new ArrayList<Criterion>();
this.criterions.addAll(criterions);
}
public void addCriterions(Fount fount) {
this.criterions = criterions != null? criterions : new ArrayList<Criterion>();
for(Criterion criterion : fount.getCriterions()) {
Criterion newCriterion = criterion.clone();
newCriterion.setFount(this);
criterions.add(newCriterion);
}
}
public Criterion addCriterion(Criterion criterion) {
this.criterions = criterions != null? criterions : new ArrayList<Criterion>();
Criterion newCriterion = criterion.clone();
newCriterion.setFount(this);
this.criterions.add(newCriterion);
return criterion;
}
public Criterion addCriterion(String criterionTxt) {
return this.addCriterion(new Criterion(criterionTxt));
}
public String getUrl() {
return this.url;
}
#Override
public String toString() {
return this.getUrl();
}
public boolean isUsed() {
return isUsed;
}
public void setUsed(boolean used) {
isUsed = used;
}
public boolean isActive() {
return isActive;
}
public void setActive(boolean active) {
isActive = active;
}
public boolean isDeleted() {
return isDeleted;
}
public void setDeleted(boolean isDeleted) {
this.isDeleted = isDeleted;
}
}
Criterion:
package br.com.engcon.entities;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
#Entity
#Table(name = "criterion")
//#SequenceGenerator(name="SEQUENCE", sequenceName="criterion_id_seq")
public class Criterion {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#ManyToOne(fetch=FetchType.EAGER)
#OnDelete(action = OnDeleteAction.CASCADE)
#JoinColumn(name="fount_id", nullable=false)
private Fount fount;
#Column(nullable=true, name="word_filter")
private String word;
#Column(nullable=false, name="case_sensitive")
private boolean caseSensitive;
public Criterion() {
// TODO Auto-generated constructor stub
caseSensitive = false;
}
public Criterion(String word) {
this.word = word;
this.caseSensitive = false;
}
public Criterion(String word, boolean caseSensitive) {
this.word = word;
this.caseSensitive = caseSensitive;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getWord() {
return word;
}
#Override
public Criterion clone(){
return new Criterion(this.word, this.caseSensitive);
}
public void setWord(String word) {
this.word = word;
}
public boolean isCaseSensitive() {
return caseSensitive;
}
public void setCaseSensitive(boolean caseSensitive) {
this.caseSensitive = caseSensitive;
}
public Fount getFount() {
return fount;
}
public void setFount(Fount fount) {
this.fount = fount;
}
#Override
public String toString() {
return this.word;
}
}
You need to synchronize both end of the bidirectional association.
If you have only 1 bidirectional association (in your example - Criterion-Fount and Fount-Criterion), the following helper methods (for disassociating the parent from all child entities) would solve the problem:
public void addCriterion(Criterion criterion) {
criterions.add(comment);
criterion.setFount(this);
}
public void removeCriterion(Criterion criterion) {
criterions.remove(criterion);
criterion.setFount(null);
}
And make sure you're using cascading:
#OneToMany(mappedBy = "fount", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Criterion> criterions;
I had write a restful interface in NetbeansIDE8.2 ,and i have debug it with the PostMan App in chorme, and then an exception have experenced I will show the image down here :
the HTTP ERROR 500
and my code is here ,I have return a arryList to browser
#Path("/getStu")
#GET
public List<TfFreshstudent> queryStudentNoDomitory()
{
List<TfFreshstudent> studentList= cq.queryFreshstudentNoDomitory();
if (studentList.isEmpty()) {
return studentList;
}
return null;
}
and I have tried other sub of the automatic create code ,and the error is also happened:
#GET
public List<TfDormitory> getAllTfDormitories() {
log.debug("REST request to get all TfDormitories");
List<TfDormitory> tfDormitories = tfDormitoryFacade.findAll();
return tfDormitories;
}
I have think that it maybe the return type error maybe ArryList can't be show on browser, maybe I must parse it to json type or response
This is the entity which Jeddic was create
package com.freshV3.cart.model;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "tf_dormitory")
public class TfDormitory {
#Column(name = "id", table = "tf_dormitory", nullable = false, length = 22)
#Id
private String id;
#Column(name = "buildName", table = "tf_dormitory", length = 50)
#Basic
private String buildName;
#Column(name = "comment", table = "tf_dormitory")
#Basic
private String comment;
#Column(name = "freshStudentId", table = "tf_dormitory", length = 22)
#Basic
private String freshStudentId;
#Column(name = "isDelete", table = "tf_dormitory")
#Basic
private Integer isDelete;
#Column(name = "operator", table = "tf_dormitory", length = 20)
#Basic
private String operator;
#Column(name = "roomCode", table = "tf_dormitory", length = 32)
#Basic
private String roomCode;
#Column(name = "roomId", table = "tf_dormitory")
#Basic
private String roomId;
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
public String getBuildName() {
return this.buildName;
}
public void setBuildName(String buildName) {
this.buildName = buildName;
}
public String getComment() {
return this.comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public String getFreshStudentId() {
return this.freshStudentId;
}
public void setFreshStudentId(String freshStudentId) {
this.freshStudentId = freshStudentId;
}
public Integer getIsDelete() {
return this.isDelete;
}
public void setIsDelete(Integer isDelete) {
this.isDelete = isDelete;
}
public String getOperator() {
return this.operator;
}
public void setOperator(String operator) {
this.operator = operator;
}
public String getRoomCode() {
return this.roomCode;
}
public void setRoomCode(String roomCode) {
this.roomCode = roomCode;
}
public String getRoomId() {
return this.roomId;
}
public void setRoomId(String roomId) {
this.roomId = roomId;
}
}
here is my query where I'm trying to get id and userNotes from Job Class.
#Query("SELECT j.id, j.userNotes FROM Job j WHERE j.bookingTime BETWEEN :stDate AND :edDate")
List<Job> getDriverCalendar(#Param("stDate") Timestamp stDate, #Param("edDate") Timestamp edDate);
Job.java
package com.housecar.model;
import java.math.BigDecimal;
import java.sql.Timestamp;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
#Entity
#EntityListeners(AuditingEntityListener.class)
#Table(name = "hc_job")
public class Job{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "ride_time")
private Timestamp rideTime;
#Column(name = "booking_time")
private Timestamp bookingTime;
#Column(name = "guest_id")
private Long guestId;
#Column(name = "booked_user_id")
private Long bookedUserId;
#Column(name = "car_id")
private Long carId;
#Column(name = "pickup_location")
private String pickupLocation;
#Column(name = "drop_location")
private String dropLocation;
#Column(name = "trip_type")
private Character tripType;
#Column(name = "is_private_job")
private Boolean isPrivateJob;
#Column(name = "estimated_fare")
private BigDecimal estimatedFare;
#Column(name = "actual_fare")
private BigDecimal actualFare;
#Column(name = "tip")
private BigDecimal tip;
#Column(name = "payment_status")
private Character paymentStatus;
#Column(name = "user_notes")
private String userNotes;
#Column(name = "cancellation_notes")
private String cancellationNotes;
#Column(name = "status")
private Character status;
#OneToOne
#JoinColumn(name = "id", referencedColumnName = "id", insertable = false, updatable = false)
private JobDriverRating jobDriverRating;
#OneToOne
#JoinColumn(name = "id", referencedColumnName = "id", insertable = false, updatable = false)
private JobCostSplit jobCostSplit;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getGuestId() {
return guestId;
}
public void setGuestId(Long guestId) {
this.guestId = guestId;
}
public Long getBookedUserId() {
return bookedUserId;
}
public void setBookedUserId(Long bookedUserId) {
this.bookedUserId = bookedUserId;
}
public Long getCarId() {
return carId;
}
public void setCarId(Long carId) {
this.carId = carId;
}
public String getPickupLocation() {
return pickupLocation;
}
public void setPickupLocation(String pickupLocation) {
this.pickupLocation = pickupLocation;
}
public String getDropLocation() {
return dropLocation;
}
public void setDropLocation(String dropLocation) {
this.dropLocation = dropLocation;
}
public Character getTripType() {
return tripType;
}
public void setTripType(Character tripType) {
this.tripType = tripType;
}
public Boolean getIsPrivateJob() {
return isPrivateJob;
}
public void setIsPrivateJob(Boolean isPrivateJob) {
this.isPrivateJob = isPrivateJob;
}
public BigDecimal getEstimatedFare() {
return estimatedFare;
}
public void setEstimatedFare(BigDecimal estimatedFare) {
this.estimatedFare = estimatedFare;
}
public BigDecimal getActualFare() {
return actualFare;
}
public void setActualFare(BigDecimal actualFare) {
this.actualFare = actualFare;
}
public BigDecimal getTip() {
return tip;
}
public void setTip(BigDecimal tip) {
this.tip = tip;
}
public Character getPaymentStatus() {
return paymentStatus;
}
public void setPaymentStatus(Character paymentStatus) {
this.paymentStatus = paymentStatus;
}
public String getUserNotes() {
return userNotes;
}
public void setUserNotes(String userNotes) {
this.userNotes = userNotes;
}
public String getCancellationNotes() {
return cancellationNotes;
}
public void setCancellationNotes(String cancellationNotes) {
this.cancellationNotes = cancellationNotes;
}
public Character getStatus() {
return status;
}
public void setStatus(Character status) {
this.status = status;
}
public JobDriverRating getJobDriverRating() {
return jobDriverRating;
}
public void setJobDriverRating(JobDriverRating jobDriverRating) {
this.jobDriverRating = jobDriverRating;
}
public Timestamp getRideTime() {
return rideTime;
}
public void setRideTime(Timestamp rideTime) {
this.rideTime = rideTime;
}
public Timestamp getBookingTime() {
return bookingTime;
}
public void setBookingTime(Timestamp bookingTime) {
this.bookingTime = bookingTime;
}
public JobCostSplit getJobCostSplit() {
return jobCostSplit;
}
public void setJobCostSplit(JobCostSplit jobCostSplit) {
this.jobCostSplit = jobCostSplit;
}
}
#Query("SELECT j.id, j.userNotes FROM Job j WHERE j.bookingTime BETWEEN :stDate AND :edDate") this query returned [ ].
#Query("SELECT j FROM Job j WHERE j.bookingTime BETWEEN :stDate AND :edDate") this query returned the complete Job object.
Your query doesn't select a Job. It selects two fields. Such a JPQL query returns a List<Object[]>, where each array of the list has two elements.
The return type of the method should thus be changed to List<Object[]>.
In the above query use the alias name for each value fetched
You will get the result as the list of hashmap so change the return type from List<Job> to List<Map> as shown below,
#Query("SELECT j.id as id , j.userNotes as userNotes FROM Job j WHERE j.bookingTime BETWEEN :stDate AND :edDate")
List<Map> getDriverCalendar(#Param("stDate") Timestamp stDate, #Param("edDate") Timestamp edDate);
I am new to hibernate.
My problem is to resolve multiple Foreign Keys to their Value. I am able to do it with SQL but the Hibernate Annotations makes me crazy.
I got these 2 Tables for example:
Table MoveSets
MoveSet_ID
Punch_1
Punch_2
Graple_1
Graple_2
Graple_3
Graple_4
Table Moves
Move_ID
Name
Damage
MoveType_ID
Counterchance
The Punches and Graples are all foreign keys referencing to Move_ID.
My target is to do a session.createQuery("from MoveSets").list(); and to get a Moveset with the Names of the Moves instead of the IDs.
Is this possible in Hibernate?
package hibernate;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
#Entity
#Table(name = "Moves")
public class Moves implements Serializable {
/**
*
*/
private static final long serialVersionUID = -1522367877613954187L;
private int id;
private String name;
private int damage;
private int movetype_id;
private int counterchance;
public Moves() {
}
public Moves(int id, String name, int damage, int movetype_id,
int counterchance) {
this.id = id;
this.name = name;
this.damage = damage;
this.movetype_id = movetype_id;
this.counterchance = counterchance;
}
#Id
#Column(name = "Move_ID")
#GeneratedValue(generator = "increment")
#GenericGenerator(name = "increment", strategy = "increment")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Column(name = "Name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Column(name = "Damage")
public int getDamage() {
return damage;
}
public void setDamage(int damage) {
this.damage = damage;
}
#Column(name = "MoveType_ID")
public int getMovetype_id() {
return movetype_id;
}
public void setMovetype_id(int movetype_id) {
this.movetype_id = movetype_id;
}
#Column(name = "Counterchance")
public int getCounterchance() {
return counterchance;
}
public void setCounterchance(int counterchance) {
this.counterchance = counterchance;
}
#Override
public String toString() {
return "Moves - Name: " + name;
}
}
And
package hibernate;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
#Entity
#Table(name = "MoveSets")
public class MoveSets implements Serializable {
/**
*
*/
private static final long serialVersionUID = -6488498413048804953L;
private int id;
private int punch_1;
private int punch_2;
private int graple_1;
private int graple_2;
private int graple_3;
private int graple_4;
public MoveSets() {
}
public MoveSets(int id, int punch_1, int punch_2, int graple_1,
int graple_2, int graple_3, int graple_4) {
this.id = id;
this.punch_1 = punch_1;
this.punch_2 = punch_2;
this.graple_1 = graple_1;
this.graple_2 = graple_2;
this.graple_3 = graple_3;
this.graple_4 = graple_4;
}
#ManyToOne
#JoinColumn(name = "Moves_ID")
public Moves moves;
#Id
#Column(name = "MoveSet_ID")
#GeneratedValue(generator = "increment")
#GenericGenerator(name = "increment", strategy = "increment")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Column(name = "Punch_1")
public int getPunch_1() {
return punch_1;
}
public void setPunch_1(int punch_1) {
this.punch_1 = punch_1;
}
#Column(name = "Punch_2")
public int getPunch_2() {
return punch_2;
}
public void setPunch_2(int punch_2) {
this.punch_2 = punch_2;
}
#Column(name = "Graple_1")
public int getGraple_1() {
return graple_1;
}
public void setGraple_1(int graple_1) {
this.graple_1 = graple_1;
}
#Column(name = "Graple_2")
public int getGraple_2() {
return graple_2;
}
public void setGraple_2(int graple_2) {
this.graple_2 = graple_2;
}
#Column(name = "Graple_3")
public int getGraple_3() {
return graple_3;
}
public void setGraple_3(int graple_3) {
this.graple_3 = graple_3;
}
#Column(name = "Graple_4")
public int getGraple_4() {
return graple_4;
}
public void setGraple_4(int graple_4) {
this.graple_4 = graple_4;
}
#Override
public String toString() {
return "MoveSet - ID: " + id + " Punch 1: " + punch_1;
}
}
Yes it is possible, in fact the whole point of ORM and Hibernate is to get objects (your values) insteed of plain IDs. Your mapping is wrong. You should map your relations (I assume that punches and grapples are moves) via annotations like #OneToOne,#OneToMany and so one along with #JoinColumn, so your fields insteed of this
#Column(name = "Graple_1")
public int getGraple_1() {
return graple_1;
}
should be like
#ManyToOne
#JoinColumn(name="Graple1")
public Move getGraple_1() {
return graple_1;
}
This way you will get relevant Move objects and get any data you want from them, along with the requested name