JPA集合保存ID,但不保存其他字段

时间:2017-02-14 17:38:03

标签: mysql angularjs hibernate jpa jhipster

所以,我有一个JHipster生成的应用程序,其中包含许多实体和集合,在我拥有研究的主要实体中,它有许多集合。

其中一个是StudySites,它是ManyToMany所有者是研究:

研究中的关系和制定者:

@ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
    @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
    @JoinTable(name = "study_sites_study",
        joinColumns = @JoinColumn(name="studys_id", referencedColumnName="ID"),
        inverseJoinColumns = @JoinColumn(name="study_sitess_id", referencedColumnName="ID"))
    private Set<StudySites> studySites = new HashSet<>();

public void setStudySites(Set<StudySites> studySites) {
        studySites.stream().forEach(ss-> {
            Set<Study> setStudys=ss.getStudys();
            setStudys.add(this);
            ss.setStudys(setStudys);
        });
        this.studySites = studySites;
    }

StudySites中的关系:

@ManyToMany(mappedBy = "studySites")
    @JsonIgnore
    @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
    private Set<Study> studys = new HashSet<>();

我们处理这一切的关系和方式可能会非常复杂,并且会产生相当大的帖子,因此我会尝试将其置于底线,说我们将所有信息捆绑在DTOAngular并将其发送到后端,在那里解压缩Studys并将所有集合放在StudyDTO中,所有这些工作都很好,我在所有字段中都有所有数据,直到我们从存储库调用save方法,除了这个特定实体的字段外,它可以保存其他所有集合。

如果我将StudySite添加到研究中,Hibernate将为其分配一个id,保存它并将关系保存在连接表中,所以当我再次加载Study时,它将显示StudySite但是空地。

当我插入一个新的或者我尝试更新现有的

时会发生这种情况

我还记录了来自Hibernate的变量绑定,你可以将所有值都归结为null,但是当在连接表中保存时,它已经检索了分配的id和study_id:

Hibernate: /* insert org.wwarn.nmfisurveyor.datamanagement.domain.StudySites */ insert into study_sites (country_id, dms_lat, dms_lon, google_lat, google_lon, province_name, site_name) values (?, ?, ?, ?, ?, ?, ?)
2017-02-14 17:12:50.972 TRACE 8859 --- [nio-8080-exec-9] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [BIGINT] - [null]
2017-02-14 17:12:50.972 TRACE 8859 --- [nio-8080-exec-9] o.h.type.descriptor.sql.BasicBinder      : binding parameter [2] as [VARCHAR] - [null]
2017-02-14 17:12:50.972 TRACE 8859 --- [nio-8080-exec-9] o.h.type.descriptor.sql.BasicBinder      : binding parameter [3] as [VARCHAR] - [null]
2017-02-14 17:12:50.973 TRACE 8859 --- [nio-8080-exec-9] o.h.type.descriptor.sql.BasicBinder      : binding parameter [4] as [DOUBLE] - [null]
2017-02-14 17:12:50.973 TRACE 8859 --- [nio-8080-exec-9] o.h.type.descriptor.sql.BasicBinder      : binding parameter [5] as [DOUBLE] - [null]
2017-02-14 17:12:50.973 TRACE 8859 --- [nio-8080-exec-9] o.h.type.descriptor.sql.BasicBinder      : binding parameter [6] as [VARCHAR] - [null]
2017-02-14 17:12:50.973 TRACE 8859 --- [nio-8080-exec-9] o.h.type.descriptor.sql.BasicBinder      : binding parameter [7] as [VARCHAR] - [null]
Hibernate: /* insert collection row org.wwarn.nmfisurveyor.datamanagement.domain.Study.studySites */ insert into study_sites_study (studys_id, study_sitess_id) values (?, ?)
2017-02-14 17:12:50.980 TRACE 8859 --- [nio-8080-exec-9] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [BIGINT] - [4089]
2017-02-14 17:12:50.980 TRACE 8859 --- [nio-8080-exec-9] o.h.type.descriptor.sql.BasicBinder      : binding parameter [2] as [BIGINT] - [1629]

欢迎任何建议

PS:在我追踪错误的各种事情中,我完全删除了实体及其所有引用(liquibase,所有内容)并使用不同的名称重新创建,没有任何改变。

2 个答案:

答案 0 :(得分:0)

不确定这是否是罪魁祸首,但在我看来你的setter方法:

public void setStudySites(Set<StudySites> studySites) {
        studySites.stream().forEach(ss-> {
            Set<Study> setStudys=ss.getStudys();
            setStudys.add(this);
            ss.setStudys(setStudys);
        });
        this.studySites = studySites;
    }

应该减少到:

public void setStudySites(Set<StudySites> studySites) {
        this.studySites = studySites;
    }

遍历集合并设置Studys实体,我将留下一些Repository / Service方法来处理。

答案 1 :(得分:0)

我终于设法解决了这个问题,起初我只是将cascadeType改为ALL而不是PERSIST,它总是运行正常,不需要合并相同的同一形式的不同研究StudySite的实例。所以在经过一番思考之后,我意识到潜在的问题是在Many to Many关系中你不能指望Hibernate保存新创建的实体并且还将关系保存在连接表中,至少不是这样的我们这样做了。

所以我只是调整了设计,在用户需要创建一个新实体时打开一个模态,首先保存它,然后在用户点击整个表单保存时将其保存在连接表中

以前发生的事情是Hibernate无法保留新字段,但是在连接表中保存了关系,因此生成的id为空字段