无法保存到数据库外 table 新记录生成休眠 jpa
cannot save to database foreign table new record generate hibernate jpa
两个实体:人、宠物。
一个人拥有多只宠物,由 ownerId 链接。 Owner
class 扩展 Person
class。 Person
class 扩展 BaseEntity
。 BaseEntity
用于生成唯一的id值。使用 thymeleaf web 部件 input/insert 一个特定主人的更多宠物。宠物确实插入到 h2 数据库中。但 ownerId 是 null.That 的问题。
存储库代码:
public interface OwnerRepository extends JpaRepository<Owner, Long>{}
public interface PetRepository extends JpaRepository<Pet, Long> {}
完整代码:https://github.com/jianheMark/springpetsimplified
BaseEntity 代码:
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@MappedSuperclass
public class BaseEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
public boolean isNew() {
return this.id == null;
}
}
PetController部分代码:
@GetMapping("/pets/new")
public String initCreationForm(Owner owner, Model model) {
Pet pet = new Pet();
owner.getPets().add(pet);
pet.setOwner(owner);
model.addAttribute("pet", pet);
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
}
@PostMapping("/pets/new")
public String processCreationForm(Owner owner, Pet pet, BindingResult result, ModelMap model) {
if (StringUtils.hasLength(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null){
result.rejectValue("name", "duplicate", "already exists");
}
owner.getPets().add(pet);
if (result.hasErrors()) {
model.put("pet", pet);
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
} else {
petService.save(pet);
return "redirect:/owners/" + owner.getId();
}
}
所有者部分代码:
@Setter
@Getter
@NoArgsConstructor
@Entity
@Table(name = "owners")
public class Owner extends Person {
@Builder
public Owner(Long id, String firstName, String lastName, String address, String city,
String telephone, Set<Pet> pets) {
super(id, firstName, lastName);
this.address = address;
this.city = city;
this.telephone = telephone;
if(pets != null) {
this.pets = pets;
}
}
@Column(name = "address")
private String address;
@Column(name = "city")
private String city;
@Column(name = "telephone")
private String telephone;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
private Set<Pet> pets = new HashSet<>();
宠物代码:
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "pets")
public class Pet extends BaseEntity{
@Builder
public Pet(Long id, String name, Owner owner, LocalDate birthDate) {
super(id);
this.name = name;
this.owner = owner;
this.birthDate = birthDate;
}
@Column(name = "name")
private String name;
@ManyToOne
@JoinColumn(name = "owner_id")
private Owner owner;
@Column(name = "birth_date")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate birthDate;
}
问题:
在Pet Controller中你保存了pet
但是你没有设置宠物的owner
。
更改您的代码:
@PostMapping("/pets/new")
public String processCreationForm(Owner owner, Pet pet, BindingResult result, ModelMap model) {
if (StringUtils.hasLength(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null){
result.rejectValue("name", "duplicate", "already exists");
}
owner.getPets().add(pet);
if (result.hasErrors()) {
model.put("pet", pet);
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
} else {
pet.setOwner(owner) // This line here was missing!
petService.save(pet);
return "redirect:/owners/" + owner.getId();
}
}
你也说owner.getPets().add(pet)
。你还是不坚持这个。您不将此信息保存在数据库中,您只是在内部为您的代码保存。
您应该尝试在代码上调试和设置断点,以便检查保存的内容和实际收到的内容。
并尝试将所有业务逻辑委托给服务。因此控制器仅用于处理特定端点调用上发生的事情。
祝你好运。
两个实体:人、宠物。
一个人拥有多只宠物,由 ownerId 链接。 Owner
class 扩展 Person
class。 Person
class 扩展 BaseEntity
。 BaseEntity
用于生成唯一的id值。使用 thymeleaf web 部件 input/insert 一个特定主人的更多宠物。宠物确实插入到 h2 数据库中。但 ownerId 是 null.That 的问题。
存储库代码:
public interface OwnerRepository extends JpaRepository<Owner, Long>{}
public interface PetRepository extends JpaRepository<Pet, Long> {}
完整代码:https://github.com/jianheMark/springpetsimplified
BaseEntity 代码:
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@MappedSuperclass
public class BaseEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
public boolean isNew() {
return this.id == null;
}
}
PetController部分代码:
@GetMapping("/pets/new")
public String initCreationForm(Owner owner, Model model) {
Pet pet = new Pet();
owner.getPets().add(pet);
pet.setOwner(owner);
model.addAttribute("pet", pet);
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
}
@PostMapping("/pets/new")
public String processCreationForm(Owner owner, Pet pet, BindingResult result, ModelMap model) {
if (StringUtils.hasLength(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null){
result.rejectValue("name", "duplicate", "already exists");
}
owner.getPets().add(pet);
if (result.hasErrors()) {
model.put("pet", pet);
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
} else {
petService.save(pet);
return "redirect:/owners/" + owner.getId();
}
}
所有者部分代码:
@Setter
@Getter
@NoArgsConstructor
@Entity
@Table(name = "owners")
public class Owner extends Person {
@Builder
public Owner(Long id, String firstName, String lastName, String address, String city,
String telephone, Set<Pet> pets) {
super(id, firstName, lastName);
this.address = address;
this.city = city;
this.telephone = telephone;
if(pets != null) {
this.pets = pets;
}
}
@Column(name = "address")
private String address;
@Column(name = "city")
private String city;
@Column(name = "telephone")
private String telephone;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
private Set<Pet> pets = new HashSet<>();
宠物代码:
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "pets")
public class Pet extends BaseEntity{
@Builder
public Pet(Long id, String name, Owner owner, LocalDate birthDate) {
super(id);
this.name = name;
this.owner = owner;
this.birthDate = birthDate;
}
@Column(name = "name")
private String name;
@ManyToOne
@JoinColumn(name = "owner_id")
private Owner owner;
@Column(name = "birth_date")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate birthDate;
}
问题:
在Pet Controller中你保存了pet
但是你没有设置宠物的owner
。
更改您的代码:
@PostMapping("/pets/new")
public String processCreationForm(Owner owner, Pet pet, BindingResult result, ModelMap model) {
if (StringUtils.hasLength(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null){
result.rejectValue("name", "duplicate", "already exists");
}
owner.getPets().add(pet);
if (result.hasErrors()) {
model.put("pet", pet);
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
} else {
pet.setOwner(owner) // This line here was missing!
petService.save(pet);
return "redirect:/owners/" + owner.getId();
}
}
你也说owner.getPets().add(pet)
。你还是不坚持这个。您不将此信息保存在数据库中,您只是在内部为您的代码保存。
您应该尝试在代码上调试和设置断点,以便检查保存的内容和实际收到的内容。
并尝试将所有业务逻辑委托给服务。因此控制器仅用于处理特定端点调用上发生的事情。
祝你好运。