所以,我有一个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<>();
我们处理这一切的关系和方式可能会非常复杂,并且会产生相当大的帖子,因此我会尝试将其置于底线,说我们将所有信息捆绑在DTO
中Angular
并将其发送到后端,在那里解压缩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,所有内容)并使用不同的名称重新创建,没有任何改变。
答案 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为空字段