Home > Back-end >  Error while trying save entity to database: not-null property references a null or transient value
Error while trying save entity to database: not-null property references a null or transient value

Time:11-26

I have a two entities conntected with relation one-to-one(Agency-Address). I am trying to save these two entities to database using one controller. I can save address but I can't save agency entity.

Here is my exception :

There was an unexpected error (type=Internal Server Error, status=500). not-null property references a null or transient value : com.example.demo.agency.Agency.address; nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value : com.example.demo.agency.Agency.address org.springframework.dao.DataIntegrityViolationException: not-null property references a null or transient value : com.example.demo.agency.Agency.address; nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value : com.example.demo.agency.Agency.address

Agency.java


package com.example.demo.agency;

import com.example.demo.address.Address;
import lombok.*;

import javax.persistence.*;

@Entity(name = "agency")
@Table(name = "agency")
@Data
@ToString
@EqualsAndHashCode
@NoArgsConstructor
@AllArgsConstructor
public class Agency {


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id",nullable = false)
    private Long id;
    @Column(name = "phoneNumber")
    private String phoneNumber;
    @Column(name = "openHours")
    private String openHours;
    @Column(name = "email")
    private String email;
    @OneToOne(fetch = FetchType.EAGER,optional = false)
    @JoinColumn(name="addressid",referencedColumnName = "id",nullable = false)
    private Address address;

    public Agency(String phoneNumber,String openHours, String email) {
         this.phoneNumber = phoneNumber;
         this.openHours = openHours;
         this.email = email;
    }
}


Address.java



package com.example.demo.address;

import com.example.demo.agency.Agency;
import lombok.*;

import javax.persistence.*;

@Entity(name = "address")
@Table(name = "address")
@Data
@ToString
@EqualsAndHashCode
@NoArgsConstructor
@AllArgsConstructor
public class Address {


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id",nullable = false)
    private Long id;
    @Column(name = "postalCode")
    private String postalCode;
    @Column(name = "street")
    private String street;
    @Column(name = "streetNumber")
    private int streetNumber;
    @OneToOne(mappedBy = "address",fetch = FetchType.LAZY,cascade = CascadeType.ALL)
    private Agency agency;


    public Address(String postalCode,String street,int streetNumber) {
        this.postalCode = postalCode;
        this.street = street;
        this.streetNumber = streetNumber;
    }


}


AgencyController.java



package com.example.demo.agency;


import com.example.demo.address.Address;
import com.example.demo.address.AddressService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
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.PostMapping;

import javax.swing.*;

@Controller
public class AgencyController {

    private AgencyService agencyService;
    private AddressService addressService;


    @Autowired
    public AgencyController(AgencyService agencyService,AddressService addressService) {
        this.agencyService = agencyService;
        this.addressService = addressService;

    }

    @GetMapping("/agencies")
    public String getAgencies(Model model) {
        model.addAttribute("agencies",agencyService.getAgencies());
        return "agencies";
    }

    /*  GET HTTP Request for form to add new agency to database */
    @GetMapping("/agencies/new")
    public String newAgencyPage(Model model) {
           Agency newAgency = new Agency();
           Address newAddress = new Address();
           model.addAttribute("agency",newAgency);
           model.addAttribute("address",newAddress);
           return "newAgency";
    }

    /* POST HTTP Request for put data to database*/
    @PostMapping("/agencies/save")
    public String saveAgency(@ModelAttribute("agency") Agency agency,@ModelAttribute("address") Address address) {

        agencyService.saveAgency(agency);
        addressService.saveAddress(address);

        return "redirect:/agencies";
    }

}

newAgency.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="ISO-8859-1">
    <title>Agencies</title>
    <link rel="stylesheet"
          href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
          integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO"
          crossorigin="anonymous">
</head>
<body>
<div class="container">

    <h2>Save Agency</h2>

    <form action="#" th:action="@{/agencies/save}"
          method="POST">
        <input type="text" th:value="*{agency.phoneNumber}" name="phoneNumber"
               placeholder="Agency Phone Number" class="form-control mb-4 col-4" >

        <input type="text" th:value="*{agency.openHours}" name="openHours"
               placeholder="Agency OpenHours" class="form-control mb-4 col-4">

        <input type="text" th:value="*{agency.email}" name="email"
               placeholder="Agency Email" class="form-control mb-4 col-4">

        <input type="text" th:attr="data-department=${agency.address!=null}?${agency.address.street}:'not specified'" name="street"
               placeholder="Street" class="form-control mb-4 col-4">

        <input type="text" th:attr="data-department=${agency.address!=null}?${agency.address.streetNumber}:'not specified'" name="streetNumber"
               placeholder="Street Number" class="form-control mb-4 col-4">

        <input type="text" th:attr="data-department=${agency.address!=null}?${agency.address.postalCode}:'not specified'" name="postalCode"
               placeholder="Postal Code" class="form-control mb-4 col-4">

        <button type="submit" class="btn btn-info col-2"> Save Agency</button>
    </form>

    <hr>

    <a th:href = "@{/agencies}"> Back to Agency List</a>
</div>
</body>
</html>

CodePudding user response:

As the exception message says, the Agency.address property is null, although it's marked with nullable=false attribute. Probably it's null because you don't set it anywhere to point to the address instance.

Since your relation is bidirectional, you have to set it from both sides. I suppose you need to add something like this to your saveAgency method:

agency.setAddress(address);
address.setAgency(agency);
agencyService.saveAgency(agency);
addressService.saveAddress(address);
  • Related