Home > OS >  Problem to implement bidirectional relationship in hibernate with my spring boot api
Problem to implement bidirectional relationship in hibernate with my spring boot api

Time:01-10

I want to create a spring boot rest controller with this specification :

Customers of an electricity and gas supply company can choose to receive their monthly bills either by email or by regular mail, neither or both.

My goal is to create java hibernate entities to manage these customers and their choices of sending bills.

A utility customer is identified by their email and can have multiple choice change events that change the customer choice status.

Each choice made by a customer generates a choice change event.

A choice change event relates to a customer. A customer can have multiple choice events.

Here are my java entities.

@Entity
@Table(name = "customers")
public class Customer {

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

    @Email(message="this field must respect the email format !")
    private String email;
    
    @ManyToOne
    private Choices choices;

}


@Entity
@Table(name = "choices")
public class Choices {

    @Id
    private String id;

    @Column(name = "email")
    private boolean isThisChoice;
    
    @OneToOne
    private Customer customer;

}

The resulting customer with id 24587 (GET request):
{
  "id": "24587",
  "email": "tartampion",
  "choices": [
    {
      "id": "regular mail",
      "isThisChoice": false
    },
    {
      "id": "email",
      "isThisChoice": true
    }
  ]
}

Must I have an entity of management of event of choice of the customer

CodePudding user response:

Did you mean a model more like:

@Entity
@Table(name = "customers")
public class Customer {

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

    @Email(message="this field must respect the email format !")
    private String email;
    
    @ElementCollection
    @CollectionTable(name="Choices")
    @MapKeyColumn(name="CHOICE") //an "EMAIL" or "MAIL" string. You can use an enum instead if you want, but I wouldn't for upgrade reasons.
    @Column(name="enabled")
    private Map<String, Boolean> choices;

}

This will give you a Map of choices, resulting in JSON more like:

{
  "id": "24587",
  "email": "tartampion",
  "choices": {
      "MAIL": false,
      "EMAIL": true
    }
}

It should be much more expandable if you get other options and combinations in the future.

CodePudding user response:

Here you have to use Many to Many Mapping. Because one customer can have many choices and one choice can be opted by many customers.

package com.umesh.entity;

import com.fasterxml.jackson.annotation.JsonManagedReference;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name="customer")
public class Customer {

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

    @Column(name="email")
    private String email;

    @ManyToMany(fetch=FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH })
    @JoinTable(
            name="customer_choice",
            joinColumns=@JoinColumn(name="customer_id"),
            inverseJoinColumns=@JoinColumn(name="choice_id")
    )
    @LazyCollection(LazyCollectionOption.FALSE)
    private List<Choice> choices;

    public void Customer(){}

    public int getId() {
        return id;
    }

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

    public String getEmail() {
        return email;
    }

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

    public List<Choice> getChoices() {
        return choices;
    }

    public void setChoices(List<Choice> choices) {
        this.choices = choices;
    }

    public void addChoices(Choice choice){
        if(choices == null){
            choices = new ArrayList<>();
            choices.add(choice);
        }
        choices.add(choice);
    }
}

package com.umesh.entity;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table(name="choice")
public class Choice {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id")
    private int id;

    @Column(name="choice")
    private String choice;

    @ManyToMany(fetch=FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH })
    @JoinTable(
            name="customer_choice",
            joinColumns=@JoinColumn(name="choice_id"),
            inverseJoinColumns=@JoinColumn(name="customer_id")
    )
    @LazyCollection(LazyCollectionOption.FALSE)
    private List<Customer> customers;

    public void Choics(){}

    public int getId() {
        return id;
    }

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

    public String getChoice() {
        return choice;
    }

    public void setChoice(String choice) {
        this.choice = choice;
    }

    public List<Customer> getCustomers() {
        return customers;
    }

    public void setCustomers(List<Customer> customers) {
        this.customers = customers;
    }

    public void addCustomers(Customer customer){
        if(customers == null){
            customers = new ArrayList<>();
            customers.add(customer);
        }
        customers.add(customer);
    }
}
  • Related