Hibernate加入两个实体
Hibernate join two entities
我真的不知道我的问题到底是什么。
我的项目中有两个模型。
模型包
- 答辩伙伴
- 领主
Ansprechpartner.java
@Entity
@Table(name = "ANSPRECHPARTNER")
@EntityListeners(AuditingEntityListener.class)
@JsonIgnoreProperties(value = {"anlageAm", "updatedAt"}, allowGetters = true)
public class Ansprechpartner {
...
@NotNull
@ManyToOne
@JoinColumn(name = "lief_code", foreignKey=@ForeignKey(name = "APART_LIEF_FK"))
private Lieferanten liefCode;
public Lieferanten getLiefCode() {
return liefCode;
}
public void setLiefCode(Lieferanten liefCode) {
this.liefCode = liefCode;
}
...
}
Lieferant.java
@Entity
@Table(name = "LIEFERANTEN")
@EntityListeners(AuditingEntityListener.class)
@JsonIgnoreProperties(value = {"anlageAm"}, allowGetters = true)
public class Lieferanten {
...
@Id
private String code;
@OneToMany(mappedBy = "liefCode")
private Set<Ansprechpartner> apart;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public Set<Ansprechpartner> getApart() {
return apart;
}
public void setApart(Set<Ansprechpartner> apart) {
this.apart = apart;
}
...
}
我的控制器:
@RestController
@RequestMapping("/apart")
public class AnsprechpartnerController {
...
@GetMapping("/all/{id}")
public Ansprechpartner getApartWithId(@PathVariable("id") long id) {
Ansprechpartner apart = apartRepository.findOne(id);
return apartRepository.findOne(id);
}
}
当我尝试获取 json 数据时,出现以下问题。 Ansprechpartner 从 Lieferant 获取数据(因为该连接)。但随后 Lieferant 再次显示来自 Ansprechpartner 等的数据。
也许用下图更好地描述:
Image with explanation
编辑:
终于用@JsonIgnoreProperties注解解决了:
在我的 Ansprechpartner.java 中,我是这样做的:
@NotNull
@JsonIgnoreProperties("apart")
// @JsonManagedReference
@ManyToOne
@JoinColumn(
name = "lief_code",
foreignKey=@ForeignKey(name = "APART_LIEF_FK")
)
private Lieferanten liefCode;
在我的 Lieferanten.java 中,我是这样做的:
// @JsonBackReference
@JsonIgnoreProperties("liefCode")
@OneToMany(mappedBy = "liefCode", fetch = FetchType.LAZY)
private Set<Ansprechpartner> apart;
奇怪的行为。也许你可以试试:
1) 确保在 Lieferanten
实体中,在 equals
/ hashCode
中不要使用 Set<Ansprechpartner> apart
.
2) 您可以显式地将实体从持久性上下文中分离出来:
@NotNull
@ManyToOne
@JoinColumn(name = "lief_code"
, foreignKey=@ForeignKey(name = "APART_LIEF_FK")
, cascade={CascadeType.DETACH})
private Lieferanten liefCode;
然后在控制器中:
@GetMapping("/all/{id}")
public Ansprechpartner getApartWithId(@PathVariable("id") long id) {
Ansprechpartner apart = apartRepository.findOne(id);
apartRepository.detach(apart);
return apart;
}
您需要在存储库中实现一些 -> link 才能使其可用。
3)显式添加延迟加载:@OneToMany(mappedBy = "liefCode", fetch = FetchType.LAZY)
.
为了避免无限递归,你可以使用@JsonManagedReference & @JsonBackReference
Json 无限递归是我们序列化具有双向关系的 Java 对象时最常见的问题之一。
@JsonManagedReference:
有注解的部分会正常序列化。
@JsonBackReference:
有注解的部分会被序列化。
喜欢:
@JsonBackReference
private Set<Ansprechpartner> apart;
详情请见solution-2
根本原因是杰克逊试图在对象具有双向关系时序列化对象。
您可以通过这种方式修复它
Short way
更好的方法:
将实体直接返回到视图层不是一个好的做法。
您应该将实体转换为 DTO (Data Transfer Object) 并将 DTO 传递给视图
我真的不知道我的问题到底是什么。
我的项目中有两个模型。
模型包
- 答辩伙伴
- 领主
Ansprechpartner.java
@Entity
@Table(name = "ANSPRECHPARTNER")
@EntityListeners(AuditingEntityListener.class)
@JsonIgnoreProperties(value = {"anlageAm", "updatedAt"}, allowGetters = true)
public class Ansprechpartner {
...
@NotNull
@ManyToOne
@JoinColumn(name = "lief_code", foreignKey=@ForeignKey(name = "APART_LIEF_FK"))
private Lieferanten liefCode;
public Lieferanten getLiefCode() {
return liefCode;
}
public void setLiefCode(Lieferanten liefCode) {
this.liefCode = liefCode;
}
...
}
Lieferant.java
@Entity
@Table(name = "LIEFERANTEN")
@EntityListeners(AuditingEntityListener.class)
@JsonIgnoreProperties(value = {"anlageAm"}, allowGetters = true)
public class Lieferanten {
...
@Id
private String code;
@OneToMany(mappedBy = "liefCode")
private Set<Ansprechpartner> apart;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public Set<Ansprechpartner> getApart() {
return apart;
}
public void setApart(Set<Ansprechpartner> apart) {
this.apart = apart;
}
...
}
我的控制器:
@RestController
@RequestMapping("/apart")
public class AnsprechpartnerController {
...
@GetMapping("/all/{id}")
public Ansprechpartner getApartWithId(@PathVariable("id") long id) {
Ansprechpartner apart = apartRepository.findOne(id);
return apartRepository.findOne(id);
}
}
当我尝试获取 json 数据时,出现以下问题。 Ansprechpartner 从 Lieferant 获取数据(因为该连接)。但随后 Lieferant 再次显示来自 Ansprechpartner 等的数据。
也许用下图更好地描述: Image with explanation
编辑:
终于用@JsonIgnoreProperties注解解决了:
在我的 Ansprechpartner.java 中,我是这样做的:
@NotNull
@JsonIgnoreProperties("apart")
// @JsonManagedReference
@ManyToOne
@JoinColumn(
name = "lief_code",
foreignKey=@ForeignKey(name = "APART_LIEF_FK")
)
private Lieferanten liefCode;
在我的 Lieferanten.java 中,我是这样做的:
// @JsonBackReference
@JsonIgnoreProperties("liefCode")
@OneToMany(mappedBy = "liefCode", fetch = FetchType.LAZY)
private Set<Ansprechpartner> apart;
奇怪的行为。也许你可以试试:
1) 确保在 Lieferanten
实体中,在 equals
/ hashCode
中不要使用 Set<Ansprechpartner> apart
.
2) 您可以显式地将实体从持久性上下文中分离出来:
@NotNull
@ManyToOne
@JoinColumn(name = "lief_code"
, foreignKey=@ForeignKey(name = "APART_LIEF_FK")
, cascade={CascadeType.DETACH})
private Lieferanten liefCode;
然后在控制器中:
@GetMapping("/all/{id}")
public Ansprechpartner getApartWithId(@PathVariable("id") long id) {
Ansprechpartner apart = apartRepository.findOne(id);
apartRepository.detach(apart);
return apart;
}
您需要在存储库中实现一些 -> link 才能使其可用。
3)显式添加延迟加载:@OneToMany(mappedBy = "liefCode", fetch = FetchType.LAZY)
.
为了避免无限递归,你可以使用@JsonManagedReference & @JsonBackReference Json 无限递归是我们序列化具有双向关系的 Java 对象时最常见的问题之一。
@JsonManagedReference:
有注解的部分会正常序列化。
@JsonBackReference:
有注解的部分会被序列化。
喜欢:
@JsonBackReference
private Set<Ansprechpartner> apart;
详情请见solution-2
根本原因是杰克逊试图在对象具有双向关系时序列化对象。 您可以通过这种方式修复它 Short way
更好的方法: 将实体直接返回到视图层不是一个好的做法。 您应该将实体转换为 DTO (Data Transfer Object) 并将 DTO 传递给视图