首页 > 解决方案 > 为什么 JpaRepository 在保存实体时尝试为空 FK 键创建实体?

问题描述

我有Person表,其中包含字段countryFK,可以为 null)。当我尝试用空的国家/地区值保存Person时,我会收到错误 500 和消息

2020-01-30 15:16:37.277 WARN 10524 --- [nio-8098-exec-1] ohengine.jdbc.spi.SqlExceptionHelper:SQL 错误:0,SQLState:23502 2020-01-30 15:16:37.277 ERROR 10524 --- [nio-8098-exec-1] ohengine.jdbc.spi.SqlExceptionHelper : ОШИБКА: нулевое значение в столбце "code" нарушает ограничение NOT NULL Подробности: Ошибочная строка содержит (42, null, null, null). 2020-01-30 15:16:37.299 错误 10524 --- [nio-8098-exec-1] ozproblem.spring.common.AdviceTraits:内部服务器错误

org.springframework.dao.DataIntegrityViolationException:无法执行语句;SQL [不适用];约束[空];嵌套异常是 org.hibernate.exception.ConstraintViolationException:无法执行语句

粗略的错误翻译:

错误:“代码”列中的空值打破了 NOT NULL 限制详细信息:错误字符串包含 (42, null, null, null)。

Person.java

@Entity
@Table(name = "t_person")
@Data
public class Person {
    @Id
    @Column(name = "person_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String surname;
    private String name;
    private String patronymic;

    @Column(name = "surname_rus")
    private String surnameRus;

    @Column(name = "name_rus")
    private String nameRus;

    @Column(name = "surname_eng")
    private String surnameEng;

    @Column(name = "name_eng")
    private String nameEng;

    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "country_id")
    private Country country;

    private String settlement;
    private String occupation;

    @ManyToMany
    @JoinTable(
            name = "person_link",
            joinColumns = @JoinColumn(name = "person_id", referencedColumnName = "person_id"),
            inverseJoinColumns = @JoinColumn(name = "link_id", referencedColumnName = "link_id"))
    private List<UrlLink> linkList;

    @ManyToMany
    @JoinTable(
            name = "org_actor",
            joinColumns = @JoinColumn(name = "actor_id", referencedColumnName = "person_id"),
            inverseJoinColumns = @JoinColumn(name = "org_id", referencedColumnName = "org_id"))
    private List<Org> orgList;

    private String description;

    @ManyToMany
    @JoinTable(
            name = "person_hashtag",
            joinColumns = @JoinColumn(name = "person_id", referencedColumnName = "person_id"),
            inverseJoinColumns = @JoinColumn(name = "hashtag_id", referencedColumnName = "hashtag_id"))
    private List<HashTag> hashtagList;


************
Country.java

@Entity
@Table(name="t_country")
@Data

public class Country {
    @Id
    @Column(name = "country_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)

    private Integer id;
    private String code;
    private String name;
}

create table t_country
(
    country_id serial  not null
        constraint t_country_pkey
            primary key,
    code       char(3) not null
        constraint unique_constr_code
            unique,
    name       text
        constraint unique_constr_name
            unique,
    miscellany text,
    constraint constr_name
        unique (code, name)
);

如何保存空国家的人实体?

标签: javahibernateforeign-keys

解决方案


在您所在国家/地区的数据库表定义中,字段代码定义为

code
   char(3) not null
    constraint unique_constr_code
        unique,

表示数据库级别存在非空约束。

这就是为什么你不能拯救一个国家空无一人的人。

因此,即使您在 java 代码中没有非空约束,db 也会拒绝该值。也许您在删除 java 代码中的 not null 约束后忘记迁移数据库?


推荐阅读