2

I'm working on spring boot with jpa, I try to use onetomany and for some reason when I try to post the request on postman it creates my parent object but does not use the child foreign key, and for that I'm getting null.

1 more thing: once I played with my code and somehow I got it to work but it's succeeded only one time and now it's not working anymore. I tried to follow a lot of tutorials online but none of them helped me to fix this problem.

@Entity
@Table(name = "company")
public class Company {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    @Basic(optional = false)
    @Column(nullable = false)
    private String comp_Name;

    @Basic(optional = false)
    @Column(nullable = false)
    private String password;

    @Basic(optional = false)
    @Column(nullable = false)
    private String email;

    @OneToMany(cascade = CascadeType.ALL)
    private List<Coupon> coupons;

    public Company() {

    }

    public Company(int id, String comp_name, String password, String email) {

        setId(id);
        setComp_Name(comp_name);
        setPassword(password);
        setEmail(email);
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getComp_Name() {
        return comp_Name;
    }

    public void setComp_Name(String comp_name) {
        this.comp_Name = comp_name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public List<Coupon> getCoupons() {
        return coupons;
    }

    public void setCoupons(List<Coupon> coupons) {
        this.coupons = coupons;
    }

    @Override
    public String toString() {
        return "Company [id=" + id + ",comp_name=" + comp_Name + ", password=" + password + ", email=" + email
                + "] \n\"";
    }

}
@Entity
@Table(name = "coupon")
public class Coupon {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(nullable = false)
    @Basic(optional = false)
    private String title;

    @Column(nullable = false)
    @Basic(optional = false)
    private int amount;

    @Column(nullable = false)
    @Basic(optional = false)
    private Date startDate;

    @Column(nullable = false)
    @Basic(optional = false)
    private Date endDate;

    @Column(nullable = false)
    @Enumerated(EnumType.STRING)
    private CouponType type;

    @Column(nullable = false)
    @Basic(optional = false)
    private String msg;

    @Column(nullable = false)
    @Basic(optional = false)
    private double price;

    @Column(nullable = false)
    @Basic(optional = false)
    private String picture;

     public Coupon() {

    }

    public Coupon(int id, String title, int amount, Date startDate, Date endDate, CouponType type, String msg,
            double price, String picture) {

        this.id = id;
        this.title = title;
        this.amount = amount;
        this.startDate = startDate;
        this.endDate = endDate;
        this.type = type;
        this.msg = msg;
        this.price = price;
        this.picture = picture;

    }

    public int getid() {
        return id;
    }

    public void setid(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public int getAmount() {
        return amount;
    }

    public void setAmount(int amount) {
        this.amount = amount;
    }

    public Date getStartDate() {
        return startDate;
    }

    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }

    public Date getEndDate() {
        return endDate;
    }

    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }

    public CouponType getType() {
        return type;
    }

    public void setType(CouponType type) {
        this.type = type;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public String getPicture() {
        return picture;
    }

    public void setPicture(String picture) {
        this.picture = picture;
    }

    @Override
    public String toString() {
        return "Coupon [id=" + id + ", title=" + title + ", amount=" + amount + ", startDate=" + startDate
                + ", endDate=" + endDate + ", type=" + type + ", msg=" + msg + ", price=" + price + ", picture="
                + picture + "]";
    }

}
@PostMapping("/createCoupon")
    public ResponseEntity<String> createCoupon(@RequestBody Coupon coupon) {
            try {
                companyService.createCoupon(coupon);
                return new ResponseEntity<>("coupon created" + coupon, HttpStatus.OK);
            } catch (Exception e) {
                return new ResponseEntity<>(e.getMessage() + e.getStackTrace(), HttpStatus.UNAUTHORIZED);
            }


    }

public boolean checkIfTitleAlreadyExists(String title) {
        if (couponRepo.findByTitle(title) != null) {
            return true;
        }
        return false;
    }

    public Coupon createCoupon(Coupon coupon) throws Exception {
        if (checkIfTitleAlreadyExists(coupon.getTitle()) == false) {
            couponRepo.save(coupon);
            Company comp = companyRepo.findById(this.company.getId());
            comp.getCoupons().add(coupon);
            companyRepo.save(comp);


        } else {
            throw new Exception("The title " + coupon.getTitle() + " already exist, please try another title");
        }
        return coupon;
    }

@Repository
public interface CouponRepo extends JpaRepository<Coupon, Integer> {

    @Query("Select c from Coupon c where c.id = :id")
    Coupon findById(int id);

    @Query("Select c from Coupon c where c.type = :type")
    List<Coupon> findByType(String type);

    @Transactional
    @Modifying
    @Query("DELETE FROM Coupon c WHERE c.id = :id")
    void removeCoupon(@Param("id") int id);

    public List<Coupon> findByEndDate(Date endDate);

    @Query("Select c from Coupon c where c.title = :title")
    Coupon findByTitle(String title);

    Customer save(int id);
}
@Repository
public interface CompanyRepo extends JpaRepository<Company, Integer> {

    @Query("Select c from Company c where c.id = :id")
    Company findById(int id);

    @Query("Select c from Company c where c.comp_Name = :compName")
    Company findCompanyByCompName(String compName);

    @Query("select c from Coupon c where c.endDate = :endDate")
    List<Coupon> findCouponsByDate(Date endDate);

    @Query("select c from Company c where c.comp_Name = :name And c.password = :password")
    Company findByCompanyNameAndPassword(String name, String password);

    @Query("select c from Coupon c where c.price = :price")
    List<Coupon> findCouponsByPrice(double price);

    @Query("select c from Coupon c where c.type = :type")
    List<Coupon> findCouponsByType(CouponType type);
}
im getting this msg on postman:

null[Ljava.lang.StackTraceElement;@75cf8323

and on eclipse this:

WebConfig; /company/createCoupon
Request Method: POST
Hibernate: select coupon0_.id as id1_2_, coupon0_.amount as amount2_2_, coupon0_.end_date as end_date3_2_, coupon0_.msg as msg4_2_, coupon0_.picture as picture5_2_, coupon0_.price as price6_2_, coupon0_.start_date as start_da7_2_, coupon0_.title as title8_2_, coupon0_.type as type9_2_ from coupon coupon0_ where coupon0_.title=?
Hibernate: select coupon0_.id as id1_2_0_, coupon0_.amount as amount2_2_0_, coupon0_.end_date as end_date3_2_0_, coupon0_.msg as msg4_2_0_, coupon0_.picture as picture5_2_0_, coupon0_.price as price6_2_0_, coupon0_.start_date as start_da7_2_0_, coupon0_.title as title8_2_0_, coupon0_.type as type9_2_0_ from coupon coupon0_ where coupon0_.id=?
Hibernate: update coupon set amount=?, end_date=?, msg=?, picture=?, price=?, start_date=?, title=?, type=? where id=?
curiousMinded
  • 336
  • 3
  • 16
boxser
  • 25
  • 1
  • 5

2 Answers2

0

In your Company class

@Entity
@Table(name = "company")
public class Company {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    @OneToMany(cascade = CascadeType.ALL,
        mappedBy = "company", orphanRemoval=true)
    @JsonManagedReference
    private List<Coupon> coupons= new ArrayList<>( 0 );

    .....
}

In your Coupon Class

@Entity
@Table(name = "coupon")
public class Coupon {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @ManyToOne
    @JoinColumn(name = "company_id")
    @JsonBackReference
    private Company company;

    ...
}

And whenever you are creating an coupon you have to set your company otherwise it will be null. See your company database. Your company column in the Coupon table is null if you havent set company manually. So you have to pass company id to your controller..

dasunse
  • 2,839
  • 1
  • 14
  • 32
  • see this answer and question. https://stackoverflow.com/a/52435853/9427395 – dasunse Oct 30 '19 at 04:32
  • dasunse i tried what you posted: and i got this error on postman JSON parse error: Cannot construct instance of `com.Spring.CouponSystem.Beans.Company` (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (1); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.Spring.CouponSystem.Beans.Company` (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (1)\ – boxser Oct 30 '19 at 11:17
  • @boxser could you please show me the json object which you are trying to send.. – dasunse Oct 30 '19 at 11:20
  • { "id": 1, "title": "wqdqwrthrergd", "amount": 1, "startDate": 1569888000000, "endDate": 1571097600000, "type": "CLOTHING", "msg": "aaa", "price": 22, "picture": "https://analyticsindiamag.com/wp-content/uploads/2019/07/image_rec_lib_banner.jpg", "company":1 } – boxser Oct 30 '19 at 11:24
  • btw i managed to post once 2 days ago without manytoone and joincol on company class but i changed somthing and now its not work any more i forgot to save it – boxser Oct 30 '19 at 11:25
  • @boxser here you are sending `"company":1 ` the company object is not like this. I said you to send companyId as a path variable and then you can set the `couponObject.setCompany(companyRepository.findById(YourPathVariable).orElase(null));` – dasunse Oct 30 '19 at 11:29
  • public ResponseEntity createCoupon(@RequestBody Coupon coupon,@PathVariable("companyId") int companyId) { try { companyService.createCoupon(coupon, companyId); – boxser Oct 30 '19 at 11:45
  • public Coupon createCoupon(Coupon coupon,int companyId) throws Exception { if (checkIfTitleAlreadyExists(coupon.getTitle()) == false) { coupon.setCompany(companyRepo.findById(companyId).orElase(null)); couponRepo.save(coupon); Company comp = companyRepo.findById(this.company.getId()); comp.getCoupons().add(coupon); companyRepo.save(comp); – boxser Oct 30 '19 at 11:46
  • company/coupon/1 { "id": 1, "title": "wqdqwrthrdergd", "amount": 1, "startDate": 1569888000000, "endDate": 1571097600000, "type": "CLOTHING", "msg": "aaa", "price": 22, "picture": "https://analyticsindiamag.com/wp-content/uploads/2019/07/image_rec_lib_banner.jpg" } – boxser Oct 30 '19 at 11:46
  • on postman null[Ljava.lang.StackTraceElement;@1c357de1 but its still creating the coupon just not add a refrrence to any company – boxser Oct 30 '19 at 11:59
  • @boxser firstly coupon.setCompany(). Then save coupon. You have saved coupon before setting the company. And also you don't need company to save again because it is already saved. – dasunse Oct 30 '19 at 12:05
  • that how its set firstly coupon.setCompany(). and Then save coupon coupon.setCompany(companyRepo.findById(companyId).orElase(null)); couponRepo.save(coupon); Company comp = companyRepo.findById(this.company.getId()); comp.getCoupons().add(coupon); companyRepo.save(comp); – boxser Oct 30 '19 at 12:15
  • just `coupon.setCompany(companyRepo.findById(companyId).orElase(null)); couponRepo.save(coupon);` . Why do you need to save company again???? . – dasunse Oct 30 '19 at 12:18
  • ok worked kind of im using only those lines public Coupon createCoupon(Coupon coupon,int companyId) throws Exception { if (checkIfTitleAlreadyExists(coupon.getTitle()) == false) { coupon.setCompany(companyRepo.findById(companyId).orElase(null)); couponRepo.save(coupon); %%%%%%%%%%%%%%%%%%%% and posting like this @PostMapping(value = "/coupon/{companyId}") @ResponseBody public ResponseEntity createCoupon(@RequestBody Coupon coupon,@PathVariable("companyId") int id) { try { companyService.createCoupon(coupon,id); – boxser Oct 30 '19 at 12:23
  • its create the coupon and give me the http.ok but on the db its not give any refrrence to company id the id is still blank – boxser Oct 30 '19 at 12:24
  • @boxser could you please answer yourself. It will helpful someone who see this question later. – dasunse Oct 31 '19 at 04:14
0

this is how to fix the code need to initiate the Company in Coupon class

Coupon.class
@Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
@ManyToOne
    @JoinColumn(name = "company_id")
    @JsonBackReference
    private Company company;

public Coupon(int id, String title, int amount, Date startDate, Date endDate, CouponType type, String msg,
            double price, String picture, Company company) {

        this.id = id;
        this.title = title;
        this.amount = amount;
        this.startDate = startDate;
        this.endDate = endDate;
        this.type = type;
        this.msg = msg;
        this.price = price;
        this.picture = picture;
        this.company = company;

    }
getters+setters

Company.class 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "company", orphanRemoval = true)
    @JsonManagedReference
    private List<Coupon> coupons = new ArrayList<>(0);
getters+setters

CompanyController.class

what to post on postman:

//  http://localhost:8080/company/coupon/{companyId}
//  {
//      "title": "adaddd333dad",
//      "amount": 1,
//      "startDate": 1569888000000,
//      "endDate": 1571097600000,
//      "type": "CLOTHING",
//      "msg": "aaa",
//      "price": 22,
//      "picture": "https://analyticsindiamag.com/wp-content/uploads/2019/07/image_rec_lib_banner.jpg"
//  }

    @PostMapping(value = "/coupon/{companyId}")
    @ResponseBody
    public ResponseEntity<String> createCoupon(@RequestBody Coupon coupon, @PathVariable("companyId") int id) {
        try {
            companyService.createCoupon(coupon, id);
            return new ResponseEntity<>("coupon created", HttpStatus.OK);
        } catch (Exception e) {
            return new ResponseEntity<>(e.getMessage() + e.getStackTrace(), HttpStatus.UNAUTHORIZED);
        }

    }

CompanyService.class

    public boolean checkIfTitleAlreadyExists(String title) {
        if (couponRepo.findByTitle(title) != null) {
            return true;
        }
        return false;
    }

    public boolean checkIfCompanyExists(int id) {
        if (companyRepo.findById(id) != null) {
            return true;
        }
        return false;
    }

    public Coupon createCoupon(Coupon coupon, int companyId) throws Exception {
        if (checkIfTitleAlreadyExists(coupon.getTitle()) == false) {
            coupon.setCompany(companyRepo.findById(companyId));
            if (checkIfCompanyExists(companyId)) {
                couponRepo.save(coupon);
            } else {
                throw new Exception("This Company is not exists");
            }


        } else {
            throw new Exception("The title " + coupon.getTitle() + " already exist, please try another title");
        }
        return coupon;
    }

and it works!

TylerH
  • 20,799
  • 66
  • 75
  • 101
boxser
  • 25
  • 1
  • 5