#java #spring #hibernate #spring-mvc
Вопрос:
У меня есть две сущности, связанные отношением один к одному(Адрес агентства). Я пытаюсь сохранить эти две сущности в базе данных с помощью одного контроллера. Я могу сохранить адрес, но я не могу сохранить сущность агентства.
Вот мое исключение :
Произошла неожиданная ошибка (тип=Внутренняя ошибка сервера, статус=500). Свойство not-null ссылается на нулевое или переходное значение : com.example.demo.agency.Адрес агентства; вложенным исключением является org.hibernate.Исключение PropertyValueException: свойство not-null ссылается на нулевое или переходное значение : com.example.demo.agency.Агентство.адрес организации.springframework.dao.DataIntegrityViolationException: свойство not-null ссылается на нулевое или переходное значение : com.example.demo.agency.Адрес агентства; вложенным исключением является org.hibernate.Исключение PropertyValueException: свойство not-null ссылается на нулевое или переходное значение : com.example.demo.agency.Агентство.адрес
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
lt;!DOCTYPE htmlgt; lt;html lang="en" xmlns:th="http://www.thymeleaf.org"gt; lt;headgt; lt;meta charset="ISO-8859-1"gt; lt;titlegt;Agencieslt;/titlegt; lt;link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"gt; lt;/headgt; lt;bodygt; lt;div class="container"gt; lt;h2gt;Save Agencylt;/h2gt; lt;form action="#" th:action="@{/agencies/save}" method="POST"gt; lt;input type="text" th:value="*{agency.phoneNumber}" name="phoneNumber" placeholder="Agency Phone Number" class="form-control mb-4 col-4" gt; lt;input type="text" th:value="*{agency.openHours}" name="openHours" placeholder="Agency OpenHours" class="form-control mb-4 col-4"gt; lt;input type="text" th:value="*{agency.email}" name="email" placeholder="Agency Email" class="form-control mb-4 col-4"gt; lt;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"gt; lt;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"gt; lt;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"gt; lt;button type="submit" class="btn btn-info col-2"gt; Save Agencylt;/buttongt; lt;/formgt; lt;hrgt; lt;a th:href = "@{/agencies}"gt; Back to Agency Listlt;/agt; lt;/divgt; lt;/bodygt; lt;/htmlgt;
Ответ №1:
Как говорится в сообщении об исключении, Agency.address
свойство равно нулю, хотя оно помечено nullable=false
атрибутом. Вероятно, он равен нулю, потому что вы нигде не устанавливаете его, чтобы указать на address
экземпляр.
Поскольку ваше отношение является двунаправленным, вы должны установить его с обеих сторон. Я полагаю, вам нужно добавить что-то подобное в свой saveAgency
метод:
agency.setAddress(address); address.setAgency(agency); agencyService.saveAgency(agency); addressService.saveAddress(address);
Комментарии:
1. Я попробовал эту комбинацию:
addressService.saveAddress(address); agency.setAddress(address); agencyService.saveAgency(agency);
и сработало