Java “双向一通多回传”;“不允许为空”列;保存

Java “双向一通多回传”;“不允许为空”列;保存,java,spring,hibernate,spring-data,jpa-2.0,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 = FetchTy

这是实体的简化版本,我只显示相关部分

    @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> {
}   
给定以下实体和以下代码:

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);
我在日志中看到三个插页。 首先是包装器,然后是应用程序,最后是Apartment。但由于某些原因,应用程序_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后最终存储Apartment? 无法休眠一次存储所有三个?或者自己解决这个问题?

对不起,我修好了

问题是

@ManyToOne(fetch = FetchType.LAZY, optional = false)
        @JoinColumn(name = "application_id", insertable = false, updatable = false)
        private Application application;
我删除了insertable=false、updateable=false,并添加了optional=false

成功了

@JoinColumn(name = "application_id", optional = false)
试试这个:

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.setApplicationId(application.getId());
apartement2.setApplicationId(application.getId());

WrapperRepository.saveAndFlush(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.setApplicationId(application.getId());
apartement2.setApplicationId(application.getId());

WrapperRepository.saveAndFlush(wrapper);