java - 保存时双向 OneToMany 和 ManyToOne 返回 "NULL not allowed for column"

标签 java spring hibernate spring-data jpa-2.0

这是实体的缩短版本,我仅显示相关部分。

    @Entity
    @Data
    public class Wrapper {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Integer id

        @OneToOne(mappedBy = "wrapper", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
        private Application application;

        public Wrapper(Application application) {
            this.application = application;
            application.setWrapper(this);
        }
    }

    @Data
    @Entity
    @EqualsAndHashCode(exclude = "wrapper")
    public class Application {
        @Id
        private Integer id;

        @JsonIgnore
        @OneToOne
        @JoinColumn(name = "id")
        @MapsId
        private Wrapper wrapper;

        @OneToMany(mappedBy = "application", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
        @SortNatural
        private SortedSet<Apartement> ownedApartements = new TreeSet<>();
    }

    @Entity
    @Data
    public class Apartement {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Integer id;

        @ManyToOne(fetch = FetchType.LAZY, optional = false)
        @JoinColumn(name = "application_id", insertable = false, updatable = false)
        private Application application;
    }

@Repository
public interface WrapperRepository extends JpaRepository<Wrapper, Integer> {
}   

上述实体生成以下创建表语句:

create table Wrapper (
       id int identity not null,
        primary key (id)
    )

create table Application (
       id int not null,
        primary key (id)
    )

    create table Apartement (
       id int identity not null,
        application_id int not null,
        primary key (id)
    )

     alter table Apartement 
       add constraint FKsrweh1i1p29mdjfp03or318od 
       foreign key (application_id) 
       references Application

       alter table Application
       add constraint FKgn7j3pircupa2rbqn8yte6kyc 
       foreign key (id) 
       references Wrapper

给定以下实体和以下代码:

Apartement apartement1 = new Apartement()
Apartement apartement2 = new Apartement()

Wrapper wrapper = new Wrapper(new Application());

Application application = wrapper.getApplication();
application.getOwnedApartements().addAll(Arrays.asList(apartement1, apartement2));
apartement1.setApplication(application);
apartement2.setApplication(application);

WrapperRepository.saveAndFlush(wrapper);

我在日志中看到三个插入内容。 首先是包装,然后是应用,最后是公寓。但由于某种原因,第一次保存时 application_id 为空。但我知道它有双向关系。

我得到的错误是:

Caused by: org.h2.jdbc.JdbcSQLException: NULL not allowed for column "APPLICATION_ID"; SQL statement:
insert into Apartement (id) values (null) [23502-197]

为什么会发生这种情况?我需要以正确的顺序存储所有内容吗?我是否需要首先存储包装和应用程序,然后在获得应用程序 ID 后最后存储公寓? hibernate 不能一次性存储所有三个吗?或者自己解决这个问题?

最佳答案

抱歉,我已修复它。

问题是

@ManyToOne(fetch = FetchType.LAZY, optional = false)
        @JoinColumn(name = "application_id", insertable = false, updatable = false)
        private Application application;

我删除了 insertable = false、updatable = false 并添加了 optional=false

有效

@JoinColumn(name = "application_id", optional = false)

关于java - 保存时双向 OneToMany 和 ManyToOne 返回 "NULL not allowed for column",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54475469/

相关文章:

java - 找不到类型 : java. lang.Short 的 validator

java - 如何正确显示最多两位小数(美分)的价格,包括 Java 中的尾随零?

Java - 在 Windows 7 X32 中安装包 javax.media.jai

java - 在 Apache Flink 中从 SQL 数据库读取 DataSet 时找不到 JDBC 驱动程序

java - Camel SEDA 在发送 Spring 之前对消息进行队列

java - 测试 Spring 批量作业步骤范围

java - Servlet 映射与 mvc 资源 spring 相关的问题

java - aa568 是什么样的数字以及如何在 Java 中从十进制转换为它?

mysql - 访问 Hibernate DAO 时出现 NullPointer 错误

java - 提交表单后返回上一页(Spring/Hibernate)