尝试将实体保存到数据库时出错:not-null 属性 引用空值或临时值

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

我有两个实体以一对一的关系(代理地址)连接。我正在尝试使用一个控制器将这两个实体保存到数据库中。我可以保存地址,但我不能保存机构实体。


这是我的例外情况:

出现意外错误(类型=内部服务器错误,状态=500)。 not-null 属性 引用空值或瞬态值:com.example.demo.agency.Agency.address;嵌套异常是 org.hibernate.PropertyValueException: not-null 属性 引用了空值或瞬态值:com.example.demo.agency.Agency.address org.springframework.dao.DataIntegrityViolationException: not-null 属性 引用了一个 null 或临时值:com.example.demo.agency.Agency.address;嵌套异常是 org.hibernate.PropertyValueException: not-null 属性 引用空值或瞬态值: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>

如异常消息所述,Agency.address 属性 为空,尽管它标有 nullable=false 属性。可能它是 null 因为您没有将它设置在任何地方以指向 address 实例。

由于你的关系是双向的,所以你必须从两边进行设置。我想你需要在你的 saveAgency 方法中添加这样的东西:

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