背景
Lombok中的@Data,其等价于:
setter/getter、equals、canEqual、hashCode、toString
在Spring Data JPA中,对于存在双向依赖的情况,类似如下:
@Entity
@Table(name="t_user")
@Data
public class User {
private Long id;
private String name;
@OneToOne(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
@JoinColumn(name="user_ext_id", referencedColumnName="id")
private UserExtEntity userExtEntity;
}
@Entity
@Table(name="t_user")
@Data
public class UserExtEntity {
private String info;
@OneToOne(mappedBy = "userExtEntity")
private UserEntity userEntity;
}
问题描述
测试代码:
@Test
public void testJsonInfinite() {
List<UserEntity> userEntities = this.userRepository.findAll();
log.info("User entities:{}", Arrays.toString(userEntities.toArray()));
}
异常信息如下:
java.lang.StackOverflowError
at sun.misc.FloatingDecimal$BinaryToASCIIBuffer.dtoa(FloatingDecimal.java:431)
at sun.misc.FloatingDecimal$BinaryToASCIIBuffer.access$100(FloatingDecimal.java:259)
at sun.misc.FloatingDecimal.getBinaryToASCIIConverter(FloatingDecimal.java:1825)
at sun.misc.FloatingDecimal.toJavaFormatString(FloatingDecimal.java:80)
at java.lang.Float.toString(Float.java:206)
at java.lang.Float.toString(Float.java:568)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at org.spb.data.dao.entity.UserExtEntity.toString(UserExtEntity.java:16)
at sun.reflect.GeneratedMethodAccessor38.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor.intercept(ByteBuddyInterceptor.java:56)
at org.hibernate.proxy.ProxyConfiguration$InterceptorDispatcher.intercept(ProxyConfiguration.java:95)
at org.spb.data.dao.entity.UserExtEntity$HibernateProxy$OYDwMbzs.toString(Unknown Source)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at org.spb.data.dao.entity.UserEntity.toString(UserEntity.java:23)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at org.spb.data.dao.entity.UserExtEntity.toString(UserExtEntity.java:16)
at sun.reflect.GeneratedMethodAccessor38.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor.intercept(ByteBuddyInterceptor.java:56)
at org.hibernate.proxy.ProxyConfiguration$InterceptorDispatcher.intercept(ProxyConfiguration.java:95)
at org.spb.data.dao.entity.UserExtEntity$HibernateProxy$OYDwMbzs.toString(Unknown Source)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at org.spb.data.dao.entity.UserEntity.toString(UserEntity.java:23)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at org.spb.data.dao.entity.UserExtEntity.toString(UserExtEntity.java:16)
at sun.reflect.GeneratedMethodAccessor38.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor.intercept(ByteBuddyInterceptor.java:56)
at org.hibernate.proxy.ProxyConfiguration$InterceptorDispatcher.intercept(ProxyConfiguration.java:95)
at org.spb.data.dao.entity.UserExtEntity$HibernateProxy$OYDwMbzs.toString(Unknown Source)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at org.spb.data.dao.entity.UserEntity.toString(UserEntity.java:23)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at org.spb.data.dao.entity.UserExtEntity.toString(UserExtEntity.java:16)
at sun.reflect.GeneratedMethodAccessor38.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor.intercept(ByteBuddyInterceptor.java:56)
at org.hibernate.proxy.ProxyConfiguration$InterceptorDispatcher.intercept(ProxyConfiguration.java:95)
at org.spb.data.dao.entity.UserExtEntity$HibernateProxy$OYDwMbzs.toString(Unknown Source)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at org.spb.data.dao.entity.UserEntity.toString(UserEntity.java:23)
使用了解决循环依赖的策略:
- @JsonManagedReference/ @JsonBackReference
- @JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = “id”)
但是上述的问题依旧。 但是在简单的Case中是可以正常工作的.
解决办法
移除其中一个@Data方法,其中默认重写了@ToString的方法,导致上述的两个方法不起作用,从异常日志上看,应该是有Proxy代理相关的内容引发的。
解决的代码:
@Entity
@Table(name="t_user")
@Data
public class User {
private Long id;
private String name;
@JsonManagedReference
@OneToOne(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
@JoinColumn(name="user_ext_id", referencedColumnName="id")
private UserExtEntity userExtEntity;
}
@Entity
@Table(name="t_user")
@Getter
@Setter
public class UserExtEntity {
private String info;
@JsonBackReference
@OneToOne(mappedBy = "userExtEntity")
private UserEntity userEntity;
}
最后
以上就是活力电脑最近收集整理的关于Spring JPA Json循环依赖的问题分析的全部内容,更多相关Spring内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复