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 am developing a project in which one of the many requirement is to custom validate the two objects for which I am passing both objects to the controller from a single form.
I am frequently receiving the exception on the particular statement which I don't know how to manage or solve it.
package com.practive.course.configure;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import com.practive.course.model.Credentials;
import com.practive.course.model.Student;
#Component
public class StudentValidator implements Validator {
private final Validator credentialValidator;
public StudentValidator(Validator credentialValidator) {
if (credentialValidator == null) {
throw new IllegalArgumentException(
"The supplied [Validator] is required and must not be null.");
}
if (!credentialValidator.supports(Credentials.class)) {
throw new IllegalArgumentException(
"The supplied [Validator] must support the validation of [Address] instances.");
}
this.credentialValidator = credentialValidator;
}
/**
* This Validator validates Customer instances, and any subclasses of Customer too
*/
public boolean supports(Class clazz) {
return Student.class.isAssignableFrom(clazz);
}
public void validate(Object target, Errors errors) {
Student student = (Student) target;
System.out.println(student.getMyname());
System.out.println("below");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "email", "NotEmpty"); //this line generates the exception
System.out.println("above");
//ValidationUtils.rejectIfEmptyOrWhitespace(errors, "surname", "field.required");
try {
errors.pushNestedPath("credentials");
ValidationUtils.invokeValidator(this.credentialValidator, student.getCred(), errors);
} finally {
errors.popNestedPath();
}
}
}
#PostMapping("/registration")
public String postRegister(Student student,Credentials credential,BindingResult bindingResult,RedirectAttributes redirect) {
try{
validator.validate(student,bindingResult);
}catch(Exception e) {
System.out.println("problem is here "+e.getMessage());
}
try {
if(bindingResult.hasErrors()) {
return "registration";
}
}catch(Exception e) {
System.out.println("problem is in biding "+e.getMessage());
}
appService.registerStudent(student,credential);
return "redirect:/login";
}
package com.practive.course.model;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
#Entity
public class Student {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String myname;
private String mobile;
private String email;
#OneToOne(cascade=CascadeType.ALL)
#JoinColumn(name="credid")
private Credentials cred;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getMyname() {
return myname;
}
public void setMyname(String myname) {
this.myname = myname;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Credentials getCred() {
return cred;
}
public void setCred(Credentials cred) {
this.cred = cred;
}
}
package com.practive.course.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class Credentials {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String username;
private String password;
private String usermobile;
private Role roles;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsermobile() {
return usermobile;
}
public void setUsermobile(String usermobile) {
this.usermobile = usermobile;
}
public Role getRoles() {
return roles;
}
public void setRoles(Role roles) {
this.roles = roles;
}
}
The stacktrace :
Invalid property 'email' of bean class [com.practive.course.model.Credentials]: Bean property 'email' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
The above exception is being generated when I am trying to validate
The stacktrace shows that Invalid property 'email' of bean class [com.practive.course.model.Credentials] , the validator method is trying to get the email property of the Credentials object while from your code it is visible that the "email" is part of the Student class.
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 edited this
I have an Employee class and a Sell class.
Sell has a
#ManyToOne
relationship with Employee .
So I need an employee list order by sells, in order to search for the best month seller, but I need the sells quantity too.
I made a Service class in order to do this.
I have the right beans to create the lists, that's not a problem. The problem is that I don't know how to get 2 different list out of a function or maybe use a vector or something like that.
I made my own research before doing this but there is knowledge I don't have or understand at all.
I put some domain code:
Employee
package germanAcosta.electronicaDonPepe.dominio;
import java.io.Serializable;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
#SuppressWarnings("serial")
#Entity
public class Empleado implements Serializable{
#Id
private Integer dni;
private String password;
private String nombre;
private String apellido;
#ManyToMany // 1 o +
private List <Comision> comision;
#OneToMany(cascade=CascadeType.ALL)
private List <Premio> premio;
private String tipo;
public Empleado(){
}
public Empleado(Integer dni, String password, String nombre, String apellido, List<Comision> comision,
List<Premio> premio, String tipo) {
super();
this.dni = dni;
this.password = password;
this.nombre = nombre;
this.apellido = apellido;
this.comision = comision;
this.premio = premio;
this.tipo = tipo;
}
public Integer getDni() {
return dni;
}
public void setDni(Integer dni) {
this.dni = dni;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public String getApellido() {
return apellido;
}
public void setApellido(String apellido) {
this.apellido = apellido;
}
public List<Comision> getComision() {
return comision;
}
public void setComision(List<Comision> comision) {
this.comision = comision;
}
public List<Premio> getPremio() {
return premio;
}
public void setPremio(List<Premio> premio) {
this.premio = premio;
}
public String getTipo() {
return tipo;
}
public void setTipo(String tipo) {
this.tipo = tipo;
}
}
Sell
package germanAcosta.electronicaDonPepe.dominio;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
#SuppressWarnings("serial")
#Entity
public class Venta implements Serializable {
#Id
#GeneratedValue
private Integer numero_factura;
#ManyToOne
private Empleado empleado;
#OneToMany(cascade = CascadeType.ALL)
private List<Producto> productos = new ArrayList<Producto>();
private Date fechaDeIngreso;
public Venta() {
}
public Venta(Integer numero_factura, Empleado empleado, List<Producto> productos, Date fechaDeIngreso) {
super();
this.numero_factura = numero_factura;
this.empleado = empleado;
this.productos = productos;
this.fechaDeIngreso = fechaDeIngreso;
}
#Override
public boolean equals(Object objeto) {
if (objeto == null) {
return false;
}
if (this == objeto) {
return true;
}
if (objeto instanceof Venta) {
Venta otraVenta = (Venta) objeto;
if (otraVenta.getNumero_factura() == this.numero_factura) {
return true;
}
}
return false;
}
public Integer getNumero_factura() {
return numero_factura;
}
public void setNumero_factura(Integer numero_factura) {
this.numero_factura = numero_factura;
}
public Empleado getEmpleado() {
return empleado;
}
public void setEmpleado(Empleado empleado) {
this.empleado = empleado;
}
public List<Producto> getProductos() {
return productos;
}
public void setProductos(List<Producto> productos) {
this.productos = productos;
}
public Date getFechaDeIngreso() {
return fechaDeIngreso;
}
public void setFechaDeIngreso(Date fechaDeIngreso) {
this.fechaDeIngreso = fechaDeIngreso;
}
}
Thanks in advance.
You don't want to sort the sizes of opinions. You want to sort the movies, by their size of opinions:
movies.sort(Comparator.comparingInt(movie -> movie.getOpinions().size());
You have not posted actual code atleast for domain classes, but What you are looking for is I guess
Employee emp= emList.stream().max((a,b)-> a.getSellList().size()-b.getSellList().size());
System.out.pritntf("best seller : %s , quantity : %d", emp.getName(),empty.getSellList().size());
Major edit 1 :
After i got idea of domain i am changing my code as below.I have used my own domain classes i.e. POJOs instead of JPA. I have tested this code and works fine.
package com.grs.stackOverFlow.pack02;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.PrimitiveIterator.OfDouble;
import java.util.stream.Collectors;
public class Pack02Demo{
public static void main(String []args){
List<Sell> sells = Sell.createSampleSellList(10);
Map<Employee, List<Sell>> map = sells.stream().collect(Collectors.groupingBy(Sell::getEmp));
System.out.println(map);
Employee som=null;
for(Entry<Employee, List<Sell>> entry: map.entrySet()){
if(som==null){
som=entry.getKey();
}else{
som=map.get(som).size()>entry.getValue().size()?som:(Employee) entry.getKey();
}
}
System.out.printf("Seller of month id : %d , number of sells : %s",som.getId(),map.get(som).size());
}
}
class Sell{
private int id;
private Employee emp;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Employee getEmp() {
return emp;
}
public void setEmp(Employee emp) {
this.emp = emp;
}
public String toString(){
return String.format("{sell.id : %d, emp.id: %d %n }", id,emp.getId());
}
public static List<Sell> createSampleSellList(int listSize){
List<Employee> employees=Employee.createSampleEmpList(listSize);
List<Sell> sells=new ArrayList<>(listSize);
for(int i=1; i<=listSize; i++){
int id= (int)(Math.random() * employees.size()-1);
Sell sell=new Sell();
sell.setId(i);
sell.setEmp(employees.get(id));
sells.add(sell);
}
return sells;
}
}
class Employee {
private Integer id;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Employee(Integer id) {
super();
this.id = id;
}
public String toString(){
return String.format("{employee, id : %d }", id);
}
public boolean equals(Object object){
if(object instanceof Employee){
Employee emp=(Employee)object;
return this.id==emp.getId();
}
else
return false;
}
public int hashCode(){
return new Integer(id).toString().length();
}
public static List<Employee> createSampleEmpList(int size){
List<Employee> employees=new ArrayList<>(size);
for(int i=1; i<=size; i++){
Employee employee=new Employee(i);
employees.add(employee);
}
return employees;
}
}
imagine I have a table called Photo and a table called Tag.
A Photo can have any amount of tags. Like a picture of the Brandenburg Gate in Berlin has as tags "Berlin", "Gate", ...
Now there is a second photo with the Berlin Reichstag and has also "Berlin" as one of its tags.
At the moment this would now get saved redundantly in my database, this means in my Tag table "Berlin" appears twice and in my join table that has been created by hibernate each tupel directs to its own "Berlin"-Tag.
I don't like this situation, because this means I'm saving redundant data in my database. I would much more like the case that the tag "Berlin" gets only saved once in my Tag-table and each Photo that has this tag gets the reference on this one tag object.
So summarized:
Before (I hope this now gets displayed correctly, when I send this question)
PHOTO
ID | PhotoName
1 | Brandenburg Gate
2 | Reichstag Germany
...| ...
TAG
ID | Tagname
1 | Berlin
2 | Hamster
3 | Berlin
4 | Berlin
5 | Bird
...| ...
PHOTO_TAG (join table)
photoID | tagID
1 | 1
2 | 3
3 | 4
... | ...
Hopefully afterwards:
PHOTO
ID | PhotoName
1 | Brandenburg Gate
2 | Reichstag Germany
...| ...
TAG
ID | Tagname
1 | Berlin
2 | Hamster
3 | Bird
...| ...
PHOTO_TAG (join table)
photoID | tagID
1 | 1
2 | 1
3 | 1
... | ...
As you can see Berlin only needs to get saved once in the Tag table, while there is still no information loss, since the join table references correct on the tupel.
I tried to achieve this with hibernate (I'm not a pro) on a postgresql database. My Photo-Class has an attribute photoTags, which I gave a ManyToMany relationship (I thought that this could mean that every photo can have any amount of tags while every tag can have any amount of photos they're referenced to)
#ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Set<Tag> photoTags;
But simply, this didn't work. There is a lot of redundant data in my tag table.
a
Now my question: Do you know any sufficient way for me to realize this? Thank for you for every answer and comment (If you need any further information, like my hibernate.cfg.xml, just tell me).
(This Question here is dealing with a similar problem, but the answer is not satisfying for me:
Normalize repeating values in Hibernate - Java)
EDIT: I attach now my hibernate classes:
User.java
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.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
#Entity
#Table(name = "users")
public class User {
#Id
#GeneratedValue
private Long id;
#Column(unique = true)
private String userID;
private String userName;
private String userRealName;
private int userPhotoCount;
private Date userPhotoF;
private Date userPhot_1;
private String userLocation;
private String userThumbnailURL;
private int userIsPro;
private int userIsAdmin;
private int userContact;
private int userPhotoS;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Set<Photo> photos;
public User(String userID, String userName, String userRealName, int userPhotoCount,
Date userPhotoF, Date userPhot_1, String userLocation,
String userThumbnailURL, int userIsPro, int userIsAdmin,
int userContact, int userPhotoS, Set<Photo> photos) {
this.userID = userID;
this.userName = userName;
this.userRealName = userRealName;
this.userPhotoCount = userPhotoCount;
this.userPhotoF = userPhotoF;
this.userPhot_1 = userPhot_1;
this.userLocation = userLocation;
this.userThumbnailURL = userThumbnailURL;
this.userIsPro = userIsPro;
this.userIsAdmin = userIsAdmin;
this.userContact = userContact;
this.userPhotoS = userPhotoS;
this.photos = photos;
}
// Hibernate requirement
public User() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUserID() {
return userID;
}
public void setUserID(String userID) {
this.userID = userID;
}
public String getUserRealName() {
return userRealName;
}
public void setUserRealName(String userRealName) {
this.userRealName = userRealName;
}
public int getUserPhotoCount() {
return userPhotoCount;
}
public void setUserPhotoCount(int userPhotoCount) {
this.userPhotoCount = userPhotoCount;
}
public Date getUserPhotoF() {
return userPhotoF;
}
public void setUserPhotoF(Date userPhotoF) {
this.userPhotoF = userPhotoF;
}
public Date getUserPhot_1() {
return userPhot_1;
}
public void setUserPhot_1(Date userPhot_1) {
this.userPhot_1 = userPhot_1;
}
public String getUserLocation() {
return userLocation;
}
public void setUserLocation(String userLocation) {
this.userLocation = userLocation;
}
public String getUserThumbnailURL() {
return userThumbnailURL;
}
public void setUserThumbnailURL(String userThumbnailURL) {
this.userThumbnailURL = userThumbnailURL;
}
public int getUserIsPro() {
return userIsPro;
}
public void setUserIsPro(int userIsPro) {
this.userIsPro = userIsPro;
}
public int getUserIsAdmin() {
return userIsAdmin;
}
public void setUserIsAdmin(int userIsAdmin) {
this.userIsAdmin = userIsAdmin;
}
public int getUserContact() {
return userContact;
}
public void setUserContact(int userContact) {
this.userContact = userContact;
}
public int getUserPhotoS() {
return userPhotoS;
}
public void setUserPhotoS(int userPhotoS) {
this.userPhotoS = userPhotoS;
}
public Set<Photo> getUserPhotos() {
return photos;
}
public void setUserPhotos(Set<Photo> userPhotos) {
this.photos = userPhotos;
}
public void addPhoto(Photo photo){
this.photos.add(photo);
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
Photo.java
import java.util.Date;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
#Entity
public class Photo {
#Id
#GeneratedValue
private Long id;
private Long photoID;
private String photoTitle;
private String photoUrl;
private int photoAccur;
#ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Set<Tag> photoTags;
private int photoTagsCount;
// ist das korrekt?
private int photoCommentCount;
// date objekte
private Date photoDateP;
private Date photoDateT;
private String photoDescription;
// korrekter Name?
private String photoNotes;
private int photoNot_1;
private String photoMedia;
private String photoMed_1;
private int photoLicense;
private int photoIsFam;
private int photoIsFri;
private int photoIsPri;
// x-Achse
private float photoLongitude;
// y-Achse
private float photoLatitude;
public Photo(Long photoID, String photoTitle, String photoURL,
int photoAccur, Set<Tag> photoTags, int photoTagsCount,
int photoCommentCount, Date photoDateP, Date photoDateT,
String photoDescription, String photoNotesCount, int photoNot_1,
String photoMedia, String photoMed_1, int photoLicense,
int photoIsFam, int photoIsFri, int photoIsPri, float photoLongi,
float photoLatit) {
this.photoID = photoID;
this.photoTitle = photoTitle;
this.photoUrl = photoURL;
this.photoAccur = photoAccur;
this.photoTags = photoTags;
this.photoTagsCount = photoTagsCount;
this.photoCommentCount = photoCommentCount;
this.photoDateP = photoDateP;
this.photoDateT = photoDateT;
this.photoDescription = photoDescription;
this.photoNotes = photoNotesCount;
this.photoNot_1 = photoNot_1;
this.photoMedia = photoMedia;
this.photoMed_1 = photoMed_1;
this.photoLicense = photoLicense;
this.photoIsFam = photoIsFam;
this.photoIsFri = photoIsFri;
this.photoIsPri = photoIsPri;
this.photoLongitude = photoLongi;
this.photoLatitude = photoLatit;
}
// hibernate
public Photo() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getPhotoID() {
return photoID;
}
public void setPhotoID(Long photoID) {
this.photoID = photoID;
}
public String getPhotoTitle() {
return photoTitle;
}
public void setPhotoTitle(String photoTitle) {
this.photoTitle = photoTitle;
}
public String getPhotoUrl() {
return photoUrl;
}
public void setPhotoUrl(String photoUrl) {
this.photoUrl = photoUrl;
}
public int getPhotoAccur() {
return photoAccur;
}
public void setPhotoAccur(int photoAccur) {
this.photoAccur = photoAccur;
}
public Set<Tag> getPhotoTags() {
return photoTags;
}
public void setPhotoTags(Set<Tag> photoTags) {
this.photoTags = photoTags;
}
public int getPhotoTagsCount() {
return photoTagsCount;
}
public void setPhotoTagsCount(int photoTagsCount) {
this.photoTagsCount = photoTagsCount;
}
public int getPhotoCommentCount() {
return photoCommentCount;
}
public void setPhotoCommentCount(int photoCommentCount) {
this.photoCommentCount = photoCommentCount;
}
public Date getPhotoDateP() {
return photoDateP;
}
public void setPhotoDateP(Date photoDateP) {
this.photoDateP = photoDateP;
}
public Date getPhotoDateT() {
return photoDateT;
}
public void setPhotoDateT(Date photoDateT) {
this.photoDateT = photoDateT;
}
public String getPhotoDescription() {
return photoDescription;
}
public void setPhotoDescription(String photoDescription) {
this.photoDescription = photoDescription;
}
public String getPhotoNotesCount() {
return photoNotes;
}
public void setPhotoNotesCount(String photoNotesCount) {
this.photoNotes = photoNotesCount;
}
public int getPhotoNot_1() {
return photoNot_1;
}
public void setPhotoNot_1(int photoNot_1) {
this.photoNot_1 = photoNot_1;
}
public String getPhotoMedia() {
return photoMedia;
}
public void setPhotoMedia(String photoMedia) {
this.photoMedia = photoMedia;
}
public String getPhotoMed_1() {
return photoMed_1;
}
public void setPhotoMed_1(String photoMed_1) {
this.photoMed_1 = photoMed_1;
}
public int getPhotoLicense() {
return photoLicense;
}
public void setPhotoLicense(int photoLicense) {
this.photoLicense = photoLicense;
}
public int getPhotoIsFam() {
return photoIsFam;
}
public void setPhotoIsFam(int photoIsFam) {
this.photoIsFam = photoIsFam;
}
public int getPhotoIsFri() {
return photoIsFri;
}
public void setPhotoIsFri(int photoIsFri) {
this.photoIsFri = photoIsFri;
}
public int getPhotoIsPri() {
return photoIsPri;
}
public void setPhotoIsPri(int photoIsPri) {
this.photoIsPri = photoIsPri;
}
public float getPhotoLongi() {
return photoLongitude;
}
public void setPhotoLongi(float photoLongi) {
this.photoLongitude = photoLongi;
}
public float getPhotoLatit() {
return photoLatitude;
}
public void setPhotoLatit(float photoLatit) {
this.photoLatitude = photoLatit;
}
}
Tag.java
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
#Entity
public class Tag {
#Id
#GeneratedValue
private Long id;
private String tag;
public Tag(String tag) {
this.tag = tag;
}
public Tag() {
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
My Hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
<property name="hibernate.connection.url">jdbc:postgresql://localhost:5432/GIS</property>
<property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<property name="hibernate.connection.username">postgres</property>
<property name="hibernate.connection.password">mysql15</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.hbm2ddl.auto">create</property>
<property name="hibernate.show_sql">false</property>
<mapping class="database.User" />
<mapping class="database.Photo" />
<mapping class="database.Tag" />
</session-factory>
</hibernate-configuration>
**And now some classes that are dealing my session management with hibernate. They're probably not that important, but just in case. **
DAO.java
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.stat.Statistics;
/**
* DAO provides general access methods on the database related to session
* management (opening and closing)
*
*
*
*/
public abstract class DAO {
/**
* Logs about correct behaviour of the hibernate session management
*/
public static Statistics stats = statistics();
/**
* Ensures that every client gets his correct session
*/
private static final ThreadLocal<Session> sessions = new ThreadLocal<>();
/**
* Returns the current hibernate session. Also takes care that there's
* always an open hibernate transaction when needed.
*
* #return Current hibernate session
*/
public static Session getSession() {
Session result = sessions.get();
if (result == null) {
result = HibernateUtil.getSessionFactory().openSession();
sessions.set(result);
result.beginTransaction();
}
return result;
}
/**
* Closes the current hibernate session, if there is one.
*/
public static void closeSession() {
Session sess = sessions.get();
if (sess == null || !sess.isOpen())
return;
sessions.remove();
try {
Throwable error = null;
try {
if (sess.getTransaction().isActive() == true) {
sess.getTransaction().commit();
}
} catch (Throwable e) {
sess.getTransaction().rollback();
error = e;
} finally {
try {
System.out.println("Sessions geƶffnet bisher: "
+ stats.getSessionOpenCount());
sess.close();
System.out.println("Sessions geschlossen bisher: "
+ stats.getSessionCloseCount());
} catch (Throwable th) {
if (error != null) {
error.addSuppressed(th);
} else {
throw th;
}
}
}
} catch (HibernateException ex) {
ex.printStackTrace();
}
}
public static Statistics statistics() {
Statistics stats = HibernateUtil.getSessionFactory().getStatistics();
stats.setStatisticsEnabled(true);
return stats;
}
}
UserDAO.java
import java.util.List;
import org.hibernate.Session;
public class UserDAO extends DAO {
public void createUser(User user) {
if (user == null) {
throw new IllegalArgumentException("user must be not null");
}
Session session = getSession();
// speichern des test in der datenbank
session.save(user);
closeSession();
}
public void updateUser(User user) {
if (user == null) {
throw new IllegalArgumentException("User doesnt exist");
}
Session session = getSession();
// updaten des Users in der datenbank
session.saveOrUpdate(user);
closeSession();
}
public User getUser(Long userID) {
Session session = getSession();
#SuppressWarnings("unchecked")
List<User> oneUser = session.createQuery(
"FROM User WHERE id = " + userID).list();
closeSession();
return oneUser.get(0);
}
public User getUserByUserID(String userID) {
Session session = getSession();
#SuppressWarnings("unchecked")
List<User> oneUser = session.createQuery(
"FROM User WHERE userID = '" + userID + "'").list();
closeSession();
if (oneUser.size() > 0) {
return oneUser.get(0);
} else {
// user existiert nicht
return null;
}
}
public List<User> getAllUsers() {
Session session = getSession();
#SuppressWarnings("unchecked")
List<User> allUsers = session.createQuery("FROM users").list();
closeSession();
return allUsers;
}
}
HibernateUtil.java
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/**
* HibernateUtil manages the access to the sessionFactory, which ensures that
* there's always an open database session
*
*
*
*/
#SuppressWarnings("deprecation")
public class HibernateUtil {
final private static SessionFactory sessionFactory;
static {
try {
// create the sessionfactory from standardconfig file
sessionFactory = new Configuration().configure("hibernate.cfg.xml")
.buildSessionFactory();
} catch (Throwable ex) {
// log the exception
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
/**
* Returns the current SessionFactory
*
* #return Current SessionFactory
*/
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
HibernateListener.java
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* The HibernateListener takes care that hibernate for the database connection
* management gets initialised on the server start.
*/
public class HibernateListener implements ServletContextListener {
/**
* Calls the static initializer of the HibernateUtil class
*/
public void contextInitialized(ServletContextEvent event) {
HibernateUtil.getSessionFactory(); // Just call the static initializer
// of that class
}
/**
* Frees all ressources when the server is being restarted
*/
public void contextDestroyed(ServletContextEvent event) {
HibernateUtil.getSessionFactory().close(); // Free all resources
}
}
The way you are expecting it to work is how it's supposed to work.
I don't see anything wrong in the Hibernate model classes you have posted, so I can only assume that you are setting new Tag instances to the photo instead of loading them and setting them.
When you do that hibernate doesn't know if these objects are equal or not because they don't have an ID set (you just create them remember?).
Load the Tag objects and assign them to photos or if you are hell bent on adding new instances remove cascade all option and override the equals method to consider other details than the ID if the id is not set (null).