Hibernate和Jackson的多对多关系,带有额外字段。

huangapple go评论120阅读模式
英文:

Hibernate and Jackson manyToMany relation with extra fields

问题

最近我一直在尝试通过多对多关系链接一个Module表和一个Activity表。这种关系引入了一个额外的字段,如下所示。

  1. -------------------------------------------------------------
  2. | Module | ModuleHasActivities | Activities |
  3. -------------------------------------------------------------
  4. | id | Module_idModule | id |
  5. | Name | Activity_idActivity | Name |
  6. | Observations | Day | Price |
  7. -------------------------------------------------------------

我使用JsonManagedReference和JsonBackReference来避免无限循环。不幸的是,结果并不是预期的,因为我无法从activities获取到modules列表,反之亦然。返回的唯一信息是实体字段。

  1. @Entity
  2. @Table(name = "Module")
  3. public class Module implements Serializable {
  4. @Id
  5. @GeneratedValue
  6. @Column(name = "idModule")
  7. private int id;
  8. // 其他字段加上getter和setter
  9. @OneToMany(mappedBy = "module", cascade = CascadeType.ALL)
  10. @JsonBackReference
  11. private Set<ModuleHasActivities> moduleHasActivities = new HashSet<>();
  12. }
  1. @Entity
  2. @Table(name = "Activite")
  3. public class Activite implements Serializable {
  4. @Id
  5. @GeneratedValue
  6. @Column(name = "idActivite")
  7. private int id;
  8. // 其他字段
  9. @OneToMany(mappedBy = "activite", cascade = CascadeType.ALL)
  10. @JsonBackReference
  11. private Set<ModuleHasActivities> moduleHasActivities = new HashSet<>();
  12. }
  1. @Entity
  2. @Table(name = "Module_has_Activite")
  3. public class ModuleHasActivities implements Serializable {
  4. @Id
  5. @ManyToOne
  6. @JoinColumn(name = "Module_idModule")
  7. @JsonManagedReference
  8. private Module module;
  9. @Id
  10. @ManyToOne
  11. @JoinColumn(name = "Activite_idActivite")
  12. @JsonManagedReference
  13. private Activite activite;
  14. @Column(name = "IdJour")
  15. private int jour;
  16. }

查询模块的响应:

  1. [
  2. {
  3. "id": 1,
  4. "code": "TT1",
  5. "title": "Test 1",
  6. "description": "Nothing",
  7. "observations": "Nothing"
  8. }
  9. ]

我期望的结果(类似于这样):

  1. [
  2. {
  3. "id": 1,
  4. "code": "TT1",
  5. "title": "Test 1",
  6. "description": "Nothing",
  7. "observations": "Nothing",
  8. "activities": [
  9. "day1": {
  10. // activities的字段
  11. },
  12. "day2": {
  13. // activities的字段
  14. }
  15. ]
  16. }
  17. ]

当我调试Hibernate的SQL查询时,我们可以看到连接从未执行。这正是我所关心的!连接到模块表的连接丢失了。

对此有一点帮助将不胜感激,

谢谢

已访问链接:
Extra fields for many to many relations

英文:

Recently I've been trying to link a Module table and an Activity table by a Many to Many relationship.
This relation welcomes an additional field as below.

  1. -------------------------------------------------------------
  2. | Module | ModuleHasActivities | Activities |
  3. -------------------------------------------------------------
  4. | id | Module_idModule | id |
  5. | Name | Activity_idActivity | Name |
  6. | Observations | Day | Price |
  7. -------------------------------------------------------------

I use JsonManagedReference and JsonBackReference to avoid infinite loops. Unfortunately the result is not the expected one since I don't get the list of modules from the activities and vice versa. The only information returned are the entity fields.

  1. @Entity
  2. @Table(name = &quot;Module&quot;)
  3. public class Module implements Serializable {
  4. @Id
  5. @GeneratedValue
  6. @Column(name = &quot;idModule&quot;)
  7. private int id;
  8. // Other fields plus getter and setter
  9. @OneToMany(mappedBy = &quot;module&quot;, cascade = CascadeType.ALL)
  10. @JsonBackReference
  11. private Set&lt;ModuleHasActivities&gt; moduleHasActivities = new HashSet&lt;&gt;();
  12. }
  1. @Entity
  2. @Table(name = &quot;Activite&quot;)
  3. public class Activite implements Serializable {
  4. @Id
  5. @GeneratedValue
  6. @Column(name = &quot;idActivite&quot;)
  7. private int id;
  8. // Other fields
  9. @OneToMany(mappedBy = &quot;activite&quot;, cascade = CascadeType.ALL)
  10. @JsonBackReference
  11. private Set&lt;ModuleHasActivities&gt; moduleHasActivities = new HashSet&lt;&gt;();
  12. }
  1. @Entity
  2. @Table(name = &quot;Module_has_Activite&quot;)
  3. public class ModuleHasActivities implements Serializable {
  4. @Id
  5. @ManyToOne
  6. @JoinColumn(name = &quot;Module_idModule&quot;)
  7. @JsonManagedReference
  8. private Module module;
  9. @Id
  10. @ManyToOne
  11. @JoinColumn(name = &quot;Activite_idActivite&quot;)
  12. @JsonManagedReference
  13. private Activite activite;
  14. @Column(name = &quot;IdJour&quot;)
  15. private int jour;
  16. }

Query modules response:

  1. [
  2. {
  3. &quot;id&quot;: 1,
  4. &quot;code&quot;: &quot;TT1&quot;,
  5. &quot;title&quot;: &quot;Test 1&quot;,
  6. &quot;description&quot;: &quot;Nothing&quot;,
  7. &quot;observations&quot;: &quot;Nothing&quot;,
  8. }
  9. ]

What I expect (something like this) :

  1. [
  2. {
  3. &quot;id&quot;: 1,
  4. &quot;code&quot;: &quot;TT1&quot;,
  5. &quot;title&quot;: &quot;Test 1&quot;,
  6. &quot;description&quot;: &quot;Nothing&quot;,
  7. &quot;observations&quot;: &quot;Nothing&quot;,
  8. &quot;activities&quot;: [
  9. &quot;day1&quot;:
  10. {
  11. //fields of activities
  12. },
  13. &quot;day2&quot;:
  14. {
  15. //fields of activities
  16. },
  17. ]
  18. }
  19. ]

When I debug hibernate's SQL queries, we see that the join is never done. And that's what interests me! Joints to the module table are missing.
Hibernate和Jackson的多对多关系,带有额外字段。

A little help would be appreciated,

Thank you

Already visited links :
Extra fields for many to many relations

答案1

得分: 0

你需要理解 JsonManagedReferenceJsonBackReference 之间的区别。详见:https://stackoverflow.com/a/37394318/607637。

  1. @Entity
  2. public class Module {
  3. @JsonBackReference
  4. private Set<ModuleHasActivities> moduleHasActivities = new HashSet<>();
  5. }
  6. @Entity
  7. public class ModuleHasActivities implements Serializable {
  8. @JsonManagedReference
  9. private Module module;
  10. }

在这里,如果你序列化 Module 对象,你的 JSON 中将不会包含 moduleHasActivities 字段,但是如果你序列化 ModuleHasActivities 对象,你将会得到 module 字段。

所以,解决方案是将 @JsonBackReference@JsonManagedReference 进行调换,如下所示:

  1. @Entity
  2. public class Module {
  3. @JsonManagedReference
  4. private Set<ModuleHasActivities> moduleHasActivities = new HashSet<>();
  5. }
  6. @Entity
  7. public class ModuleHasActivities implements Serializable {
  8. @JsonBackReference
  9. private Module module;
  10. }
英文:

You need to understand the differences between JsonManagedReference and JsonBackReference. See this: https://stackoverflow.com/a/37394318/607637 for more info.

  1. @Entity
  2. public class Module {
  3. @JsonBackReference
  4. private Set&lt;ModuleHasActivities&gt; moduleHasActivities = new HashSet&lt;&gt;();
  5. }
  6. @Entity
  7. public class ModuleHasActivities implements Serializable {
  8. @JsonManagedReference
  9. private Module module;
  10. }

Here, if you serialize Module object, you will not get moduleHasActivities field in json but if you serialize ModuleHasActivities object you will get module field.

So, the solution is to flip the @JsonBackReference and @JsonManagedReference as below:

  1. @Entity
  2. public class Module {
  3. @JsonManagedReference
  4. private Set&lt;ModuleHasActivities&gt; moduleHasActivities = new HashSet&lt;&gt;();
  5. }
  6. @Entity
  7. public class ModuleHasActivities implements Serializable {
  8. @JsonBackReference
  9. private Module module;
  10. }

答案2

得分: 0

终于,我解决了我的问题。我不再使用复合键,而是将我的数据库模型更改为使用主 id 键和两个指向我关注的表的引用。映射更简单,我可以获取到所需信息。

英文:

Finally, I solved my problem. Instead of using a composite key, I changed my database model to use a primary id key and 2 references to my concerned tables. Mapping is easier and I get my information.

huangapple
  • 本文由 发表于 2020年10月22日 22:06:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/64484008.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定