英文:
Jpa bidirectional many to one mapping going into infinite loop even with @JsonManagedReference
问题
I am using JPA with Oracle databases and need to implement a bidirectional one-to-many and many-to-one mapping for the tables scheme_code_template and multilingual_template_v2 respectively.
MultilingualTemplateV2 Entity
@Entity
@Table(name = "multilingual_template_v2")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@ToString
public class MultilingualTemplateV2 {
    @NotNull()
    String language;
    @NotNull()
    @Nationalized
    String template;
    @Id
    @Column(name="template_code")
    @NotNull()
    String templateCode;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "associated_schemecode")
    @JsonManagedReference
    SchemeCode schemeCode;
}
SchemeCode Entity
@Entity
@Table(name = "scheme_code_templates")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@ToString
public class SchemeCode {
    @Column(name="associated_pushcode")
    Integer associatedPushcode;
    @NotNull
    String description;
    @Id
    @NotNull()
    String schemeCode;
    @OneToMany(mappedBy = "schemeCode", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JsonBackReference
    List<MultilingualTemplateV2> multilingualTemplates;
}
Database:
Below is scheme_code_templates. It has the scheme_code as a primary key which is used as the foreign key in multilingual_template_v2 table.
Name Null? Type
ASSOCIATED_PUSHCODE          NUMBER
SCHEME_CODE         NOT NULL VARCHAR2(6)
DESCRIPTION         NOT NULL VARCHAR2(200)
Below is multilingual_template_v2. It has the ASSOCIATED_SCHEMECODE as a foreign key referencing the scheme_code in scheme_code_templates. Template_code is the primary key.
Name Null? Type
ASSOCIATED_SCHEMECODE          VARCHAR2(6)
TEMPLATE_CODE         NOT NULL VARCHAR2(9)
LANGUAGE              NOT NULL VARCHAR2(30)
TEMPLATE              NOT NULL NCLOB
Used the below query to set the foreign key in multilingual_template_v2
ALTER TABLE multilingual_template_v2
ADD CONSTRAINT fk_scheme_code_templates
  FOREIGN KEY (associated_schemecode)
  REFERENCES scheme_code_templates(scheme_code);
I have created a JpaRepository for scheme_code called SchemeCodeRepository through which I am using findAll(). Currently, I am getting the below error when getMultilingualTemplates() is called.
Error:
at org.hibernate.collection.spi.PersistentBag.toString(PersistentBag.java:585) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
...
Any help or suggestion is greatly appreciated.
英文:
I am using JPA with oracle databases and need to implement a bidirectional one to many and many to one mapping for the tables scheme_code_template and multilingual_template_v2 respectively.
MultilingualTemplateV2 Entity
@Entity
@Table(name = "multilingual_template_v2")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@ToString
public class MultilingualTemplateV2 {
	
	@NotNull()
	String language;
	
	
	@NotNull()
	@Nationalized
	String template;
	
	@Id
	@Column(name="template_code")
	@NotNull()
	String templateCode;
	
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "associated_schemecode")
	@JsonManagedReference
	SchemeCode schemeCode;
}
SchemeCode Entity
@Entity
@Table(name = "scheme_code_templates")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@ToString
public class SchemeCode {
	
	@Column(name="associated_pushcode")
	Integer associatedPushcode;
	
	@NotNull
	String description;
		
	@Id
	@NotNull()
	String schemeCode;
	
	
	@OneToMany(mappedBy = "schemeCode", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
	@JsonBackReference
	List<MultilingualTemplateV2> multilingualTemplates;
}
database:
below is scheme_code_templates. It has the scheme_code as primary key which is used as the foreign key in multilingual_template_v2 table
Name                Null?    Type          
------------------- -------- ------------- 
ASSOCIATED_PUSHCODE          NUMBER        
SCHEME_CODE         NOT NULL VARCHAR2(6)   
DESCRIPTION         NOT NULL VARCHAR2(200)
below is multilingual_template_v2 . It has the ASSOCIATED_SCHEMECODE as foreign key referencing the scheme_code in scheme_code_templates. Template_code is the primary key.
Name                  Null?    Type         
--------------------- -------- ------------ 
ASSOCIATED_SCHEMECODE          VARCHAR2(6)  
TEMPLATE_CODE         NOT NULL VARCHAR2(9)  
LANGUAGE              NOT NULL VARCHAR2(30) 
TEMPLATE              NOT NULL NCLOB 
Used the below query to set foreign key in multilingual_template_v2
ALTER TABLE multilingual_template_v2
ADD CONSTRAINT fk_scheme_code_templates
  FOREIGN KEY (associated_schemecode)
  REFERENCES scheme_code_templates(scheme_code);
I have created a JpaRepository for scheme_code called SchemeCodeRepository through which I am using findAll(). Currently I am getting below error when getMultilingualTemplates() is called.
for (SchemeCode schemeCode : schemeRepo.findAll()) {
			System.out.println(schemeCode.getMultilingualTemplates());
		}
Error
at org.hibernate.collection.spi.PersistentBag.toString(PersistentBag.java:585) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
	at java.lang.String.valueOf(String.java:4218) ~[?:?]
	at java.lang.StringBuilder.append(StringBuilder.java:173) ~[?:?]
	at com.dcb.smsbatch.dataLayer.entities.SchemeCode.toString(SchemeCode.java:34) ~[classes/:?]
	at java.lang.String.valueOf(String.java:4218) ~[?:?]
	at java.lang.StringBuilder.append(StringBuilder.java:173) ~[?:?]
	at com.dcb.smsbatch.dataLayer.entities.MultilingualTemplateV2.toString(MultilingualTemplateV2.java:30) ~[classes/:?]
	at java.lang.String.valueOf(String.java:4218) ~[?:?]
	at java.lang.StringBuilder.append(StringBuilder.java:173) ~[?:?]
	at java.util.AbstractCollection.toString(AbstractCollection.java:457) ~[?:?]
	at org.hibernate.collection.spi.PersistentBag.toString(PersistentBag.java:585) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
	at java.lang.String.valueOf(String.java:4218) ~[?:?]
	at java.lang.StringBuilder.append(StringBuilder.java:173) ~[?:?]
	at com.dcb.smsbatch.dataLayer.entities.SchemeCode.toString(SchemeCode.java:34) ~[classes/:?]
	at java.lang.String.valueOf(String.java:4218) ~[?:?]
	at java.lang.StringBuilder.append(StringBuilder.java:173) ~[?:?]
	at com.dcb.smsbatch.dataLayer.entities.MultilingualTemplateV2.toString(MultilingualTemplateV2.java:30) ~[classes/:?]
	at java.lang.String.valueOf(String.java:4218) ~[?:?]
	at java.lang.StringBuilder.append(StringBuilder.java:173) ~[?:?]
	at java.util.AbstractCollection.toString(AbstractCollection.java:457) ~[?:?]
	at org.hibernate.collection.spi.PersistentBag.toString(PersistentBag.java:585) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
	at java.lang.String.valueOf(String.java:4218) ~[?:?]
	at java.lang.StringBuilder.append(StringBuilder.java:173) ~[?:?]
	at com.dcb.smsbatch.dataLayer.entities.SchemeCode.toString(SchemeCode.java:34) ~[classes/:?]
	at java.lang.String.valueOf(String.java:4218) ~[?:?]
	at java.lang.StringBuilder.append(StringBuilder.java:173) ~[?:?]
	at com.dcb.smsbatch.dataLayer.entities.MultilingualTemplateV2.toString(MultilingualTemplateV2.java:30) ~[classes/:?]
	at java.lang.String.valueOf(String.java:4218) ~[?:?]
	at java.lang.StringBuilder.append(StringBuilder.java:173) ~[?:?]
	at java.util.AbstractCollection.toString(AbstractCollection.java:457) ~[?:?]
	at org.hibernate.collection.spi.PersistentBag.toString(PersistentBag.java:585) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
	at java.lang.String.valueOf(String.java:4218) ~[?:?]
	at java.lang.StringBuilder.append(StringBuilder.java:173) ~[?:?]
	at com.dcb.smsbatch.dataLayer.entities.SchemeCode.toString(SchemeCode.java:34) ~[classes/:?]
	at java.lang.String.valueOf(String.java:4218) ~[?:?]
	at java.lang.StringBuilder.append(StringBuilder.java:173) ~[?:?]
	at com.dcb.smsbatch.dataLayer.entities.MultilingualTemplateV2.toString(MultilingualTemplateV2.java:30) ~[classes/:?]
	at java.lang.String.valueOf(String.java:4218) ~[?:?]
	at java.lang.StringBuilder.append(StringBuilder.java:173) ~[?:?]
	at java.util.AbstractCollection.toString(AbstractCollection.java:457) ~[?:?]
	at org.hibernate.collection.spi.PersistentBag.toString(PersistentBag.java:585) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
	at java.lang.String.valueOf(String.java:4218) ~[?:?]
	at java.lang.StringBuilder.append(StringBuilder.java:173) ~[?:?]
	at com.dcb.smsbatch.dataLayer.entities.SchemeCode.toString(SchemeCode.java:34) ~[classes/:?]
	at java.lang.String.valueOf(String.java:4218) ~[?:?]
	at java.lang.StringBuilder.append(StringBuilder.java:173) ~[?:?]
	at com.dcb.smsbatch.dataLayer.entities.MultilingualTemplateV2.toString(MultilingualTemplateV2.java:30) ~[classes/:?]
	at java.lang.String.valueOf(String.java:4218) ~[?:?]
	at java.lang.StringBuilder.append(StringBuilder.java:173) ~[?:?]
	at java.util.AbstractCollection.toString(AbstractCollection.java:457) ~[?:?]
	at org.hibernate.collection.spi.PersistentBag.toString(PersistentBag.java:585) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
	at java.lang.String.valueOf(String.java:4218) ~[?:?]
	at java.lang.StringBuilder.append(StringBuilder.java:173) ~[?:?]
	at com.dcb.smsbatch.dataLayer.entities.SchemeCode.toString(SchemeCode.java:34) ~[classes/:?]
	at java.lang.String.valueOf(String.java:4218) ~[?:?]
	at java.lang.StringBuilder.append(StringBuilder.java:173) ~[?:?]
	at com.dcb.smsbatch.dataLayer.entities.MultilingualTemplateV2.toString(MultilingualTemplateV2.java:30) ~[classes/:?]
	at java.lang.String.valueOf(String.java:4218) ~[?:?]
	at java.lang.StringBuilder.append(StringBuilder.java:173) ~[?:?]
	at java.util.AbstractCollection.toString(AbstractCollection.java:457) ~[?:?]
	at org.hibernate.collection.spi.PersistentBag.toString(PersistentBag.java:585) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
	at java.lang.String.valueOf(String.java:4218) ~[?:?]
	at java.lang.StringBuilder.append(StringBuilder.java:173) ~[?:?]
	at com.dcb.smsbatch.dataLayer.entities.SchemeCode.toString(SchemeCode.java:34) ~[classes/:?]
	at java.lang.String.valueOf(String.java:4218) ~[?:?]
Any help or suggestion is greatly appreciated.
答案1
得分: 2
递归是由 @ToString lombok 注解和双向引用引起的。生成的 toString 方法不知道任何 @JsonManagedReference(用于 Jackson 序列化)。没有与 @JsonBackReference 等效的东西,但你可以用 @ToString.Exclude 注解该字段。
@OneToMany(mappedBy = "schemeCode", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JsonBackReference
@ToString.Exclude
List<MultilingualTemplateV2> multilingualTemplates;
英文:
The recursion is caused by @ToString lombok annotation and the two way reference. The generated toString methods are unaware of any @JsonManagedReference (which is for jackson serialization)
There is no such equivalent as @JsonBackReference, but you could annotate the field with @ToString.Exclude
@OneToMany(mappedBy = "schemeCode", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JsonBackReference
@ToString.Exclude
List<MultilingualTemplateV2> multilingualTemplates;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论