无法保存到数据库外 table 新记录生成休眠 jpa

cannot save to database foreign table new record generate hibernate jpa

两个实体:宠物
一个人拥有多只宠物,由 ownerId 链接。 Owner class 扩展 Person class。 Person class 扩展 BaseEntityBaseEntity 用于生成唯一的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)。你还是不坚持这个。您不将此信息保存在数据库中,您只是在内部为您的代码保存。

您应该尝试在代码上调试和设置断点,以便检查保存的内容和实际收到的内容。

并尝试将所有业务逻辑委托给服务。因此控制器仅用于处理特定端点调用上发生的事情。

祝你好运。