尝试将实体保存到数据库时出错: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);
我有两个实体以一对一的关系(代理地址)连接。我正在尝试使用一个控制器将这两个实体保存到数据库中。我可以保存地址,但我不能保存机构实体。
这是我的例外情况:
出现意外错误(类型=内部服务器错误,状态=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);