我有一个名为 Track 的实体与我的源实体关联。如果我的 Track 实体中有数据并且它与 Source 关联,我无法在 Source Repository 中使用 findById 或 findAll 查询,并且会收到如下错误
我收到此错误:
Servlet.service() for servlet \[dispatcherServlet\] in context with path \[\] threw exception \[Handler dispatch failed: java.lang.StackOverflowError\] with root cause
java.lang.StackOverflowError: null at com.encode.atlas.encoder.entity.track.Track.toString(Track.java:7) \~\[classes!/:0.0.1-SNAPSHOT\] at java.base/java.lang.String.valueOf(String.java:4220) \~\[na:na\] at java.base/java.lang.StringBuilder.append(StringBuilder.java:173) \~\[na:na\] at java.base/java.util.AbstractCollection.toString(AbstractCollection.java:457) \~\[na:na\] at org.hibernate.collection.spi.PersistentBag.toString(PersistentBag.java:585) \~\[hibernate-core-6.1.7.Final.jar!/:6.1.7.Final\] at java.base/java.lang.StringConcatHelper.stringOf(StringConcatHelper.java:453) \~\[na:na\] at com.encode.atlas.encoder.entity.track.Source.toString(Source.java:9) \~\[classes!/:0.0.1-SNAPSHOT\] at java.base/java.lang.StringConcatHelper.stringOf(StringConcatHelper.java:453) \~\[na:na\] at com.encode.atlas.encoder.entity.track.Track.toString(Track.java:7) \~\[classes!/:0.0.1-SNAPSHOT\] at java.base/java.lang.String.valueOf(String.java:4220) \~\[na:na\] at java.base/java.lang.StringBuilder.append(StringBuilder.java:173) \~\[na:na\] at java.base/java.util.AbstractCollection.toString(AbstractCollection.java:457) \~\[na:na\] at org.hibernate.collection.spi.PersistentBag.toString(PersistentBag.java:585) \~\[hibernate-core-6.1.7.Final.jar!/:6.1.7.Final\] at java.base/java.lang.StringConcatHelper.stringOf(StringConcatHelper.java:453) \~\[na:na\] at com.encode.atlas.encoder.entity.track.Source.toString(Source.java:9) \~\[classes!/:0.0.1-SNAPSHOT\] at java.base/java.lang.StringConcatHelper.stringOf(StringConcatHelper.java:453) \~\[na:na\] at com.encode.atlas.encoder.entity.track.Track.toString(Track.java:7) \~\[classes!/:0.0.1-SNAPSHOT\] at java.base/java.lang.String.valueOf(String.java:4220) \~\[na:na\] at java.base/java.lang.StringBuilder.append(StringBuilder.java:173) \~\[na:na\] at java.base/java.util.AbstractCollection.toString(AbstractCollection.java:457) \~\[na:na\] at org.hibernate.collection.spi.PersistentBag.toString(PersistentBag.java:585) \~\[hibernate-core-6.1.7.Final.jar!/:6.1.7.Final\] at java.base/java.lang.StringConcatHelper.stringOf(StringConcatHelper.java:453) \~\[na:na\] at com.encode.atlas.encoder.entity.track.Source.toString(Source.java:9) \~\[classes!/:0.0.1-SNAPSHOT\] at java.base/java.lang.StringConcatHelper.stringOf(StringConcatHelper.java:453) \~\[na:na\] at com.encode.atlas.encoder.entity.track.Track.toString(Track.java:7) \~\[classes!/:0.0.1-SNAPSHOT\] at java.base/java.lang.String.valueOf(String.java:4220) \~\[na:na\]
我的源实体:
@Data
@Entity
public class Source {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
private String name;
private String path;
private Integer duration;
@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
private List\<Track\> tracks = new ArrayList\<\>();
}
我的追踪实体:
@Data
@Entity
public class Track {
@Id
@GeneratedValue
(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(cascade = CascadeType.ALL)
@JsonBackReference
private Source source;
private Integer index;
private String codecType;
private String pixelFormat;
private Integer width;
private Integer height;
private Integer bitrate;
private Double fps;
private String codec;
private Integer sampleRate;
private String channel;
}
查询=
`源源 = sourceRepository.findById(job.getSource().getId()).orElseThrow();`
我使用的是java 17和spring 3.0.7版本
我已经尝试使用 FetchType.LAZY 和 FetchType.EAGER 以及 @JsonBackReference 但它不起作用。
您正在使用 Lombok Data 注释,它将生成 equals/hashCode/toString,并且由于您具有双向关系,这将导致 StackOverFlowError。其中一种方法被调用。
你必须用 Lombok 打破这个循环。对于 toString 你可以使用
@ToString.Exclude
排除循环的一侧。
IMO 你不应该将 @Data 与 JPA 一起使用,因为生成的 equals/hashCode 方法不正确。
在这里阅读更多内容: https://thorben-janssen.com/lombok-hibernate-how-to-avoid-common-pitfalls/