javaspring-boothibernatespring-mvcthymeleaf

Why "OneToOne" relationship allow to store more than one data in database


I am working on OneToOne relationship with Spring MVC. In my code Person is parent table and Address is child table. I'm persist data in Person table after that in Address table. I put list of person dropdown in address page, List of person dropdown take reference while persist data in child table(Address). I have no problem while persist data into both table but problem is child table insert more than one data with same foreign key in Address table but, I declare OneToOne Relationship Mapping, so, Why Hibernate does not produce error while store more than one data in Address table.

Here down is my code:

Entity

public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long p_id;

    private String name;
    private String surname;

    @OneToOne(cascade = CascadeType.ALL, mappedBy = "person")
    private Address address;

    // getter setter
}
public class Address {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long a_id;

    private String district;
    private String city;

    @OneToOne(cascade = CascadeType.ALL, targetEntity = Person.class)
    @JoinColumn(name = "p_id")
    private Person person;

    // getter setter
}

Controller


// add person in database
@RequestMapping(value = "/addperson", method = RequestMethod.POST)
public String addPerson(Model mdl, @ModelAttribute("persons") Person person)
{
    pojoService.addPerson(person);
    return "redirect:/persons";
}

// add address in database
@RequestMapping(value = "/addaddress", method = RequestMethod.POST)
public String addAddress(Model mdl, @ModelAttribute("address") Address address)
{
    pojoService.addAddress(address);
    return "redirect:/address";
}

addperson(Thymeleaf)

<form th:action="@{/addperson}" th:object="${person}" method="post">
        <div class="container">
          <h1 style="text-align: center">Add Person</h1>
          <div class="row">
            <div class="col-sm-12">
                <div class="mb-3">
                  <label for="exampleFormControlInput1" class="form-label">Person name</label>
                  <input type="text" class="form-control" name="name" th:field="*{name}">
                </div>
                <div class="mb-3">
                  <label for="exampleFormControlInput1" class="form-label">Person surname</label>
                  <input type="text" class="form-control" name="surname" th:field="*{surname}">
                </div>
                
                <input class="btn btn-primary" type="submit" value="Submit">
                
                <br>
                <a th:href="@{/}">Home</a>
            </div>
          </div>
        </div>
    </form>

addaddress(Thymeleaf)

<form th:action="@{/addaddress}" th:object="${address}" method="post">
        <div class="container">
          <h1 style="text-align: center">Add Address</h1>
          <div class="row">
            <div class="col-sm-12">
                <div class="mb-3">
                  <label for="exampleFormControlInput1" class="form-label">Student Name</label>
                  <select th:field="*{person}" class="form-select" aria-label=".Default select example">
                    <th:block th:each="personList: ${person}">
                        <option th:text="${personList.name + ' ' + personList.surname}" th:value="${personList.p_id}"></option>
                    </th:block>
                  </select>
                </div>
                <div class="mb-3">
                  <label for="exampleFormControlInput1" class="form-label">District</label>
                  <input type="text" class="form-control" th:field="*{district}">
                </div>
                <div class="mb-3">
                  <label for="exampleFormControlInput1" class="form-label">City</label>
                  <input type="text" class="form-control" th:field="*{city}">
                </div>
                
                <input class="btn btn-primary" type="submit" value="Submit">
                
                <br>
                <a th:href="@{/}">Home</a>
            </div>
          </div>
        </div>
    </form>

Result

Person table:

enter image description here

Address Table:

enter image description here

Here down i would show you how my add person and add address page look:

enter image description here

enter image description here


Solution

  • In Spring Framwork, we always have to take reference to store foreign key in child table. In your case, you can't take any reference while store data in child table. You have to take reference of parent table primary key then, insert data in child table. it can check if data is already exist in record then, data is updated in record otherwise insert new data in record.

    How to take reference before insert child table?

    // add person in database
    @RequestMapping(value = "/addperson", method = RequestMethod.POST)
    public String addPerson(Model mdl, @ModelAttribute("persons") Person person)
    {
        pojoService.addPerson(person);
        return "redirect:/persons";
    }
    
    // add address in database
    @RequestMapping(value = "/addaddress", method = RequestMethod.POST)
    public String addAddress(Model mdl, @ModelAttribute("address") Address address)
    {
        Person person = address.getPerson();
        person.setAddress(address); 
        pojoService.addAddress(address);
        return "redirect:/address";
    }