由于多对多关系的循环引用而获得以下错误。
org.codehaus.jackson.map.JsonMappingException: Infinite recursion (StackOverflowError)
我尝试过使用 @JsonIdentityInfo , @ com.fasterxml.jackson.annotation.JsonIgnore 和 @JsonManagedReference ,但这些都不适用于我。我使用的是lombok,因此是@ getter / setter。
用户表
@Entity
@Table(name = "user")
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="user_id", scope=User.class)
public class User implements Serializable{
@Getter
@Setter
@Id
@GeneratedValue(strategy = IDENTITY, generator = "increment")
@GenericGenerator(name = "increment", strategy = "increment")
public int user_id;
@JsonManagedReference
@Getter
@Setter
@com.fasterxml.jackson.annotation.JsonIgnore
@ElementCollection(targetClass=UserInterest.class)
@OneToMany(fetch = FetchType.EAGER, mappedBy = "pk.user", cascade=CascadeType.ALL)
public Set<UserInterest> userInterestSet = new HashSet<UserInterest>();
}
兴趣表
@Entity
@Table(name = "interest")
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="interest_id", scope=Interest.class)
public class Interest implements Serializable{
@Getter
@Setter
@Id
@GeneratedValue(strategy = IDENTITY, generator = "increment")
@GenericGenerator(name = "increment", strategy = "increment")
public int interest_id;
@Getter
@Setter
@Column(name = "interest_name", nullable = false, length=100)
public String interest_name;
@Getter
@Setter
@com.fasterxml.jackson.annotation.JsonIgnore
@OneToMany(fetch = FetchType.EAGER, mappedBy = "pk.interest", cascade=CascadeType.ALL)
public Set<UserInterest> userInterestSet = new HashSet<UserInterest>();
}
UserInterest联接表
@Entity
@Table(name="user_interest")
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="pk", scope=UserInterest.class)
@AssociationOverrides({
@AssociationOverride(name="pk.user", joinColumns=@JoinColumn(name="user_id")),
@AssociationOverride(name="pk.interest", joinColumns=@JoinColumn(name="interest_id"))
})
public class UserInterest implements Serializable {
@Getter
@Setter
@com.fasterxml.jackson.annotation.JsonIgnore
@GeneratedValue(generator = "increment")
@GenericGenerator(name = "increment", strategy = "increment")
public int user_interest_id;
@EmbeddedId
@Getter
@Setter
@com.fasterxml.jackson.annotation.JsonIgnore
public UserInterestId pk;
@Transient
@Getter
@Setter
@com.fasterxml.jackson.annotation.JsonIgnore
public User user;
@Transient
@Getter
@Setter
@com.fasterxml.jackson.annotation.JsonIgnore
public Interest interest;
}
UserInterestId类
@Embeddable
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id", scope=UserInterestId.class)
public class UserInterestId implements Serializable{
@Getter
@Setter
@org.codehaus.jackson.annotate.JsonIgnore
@ManyToOne(fetch = FetchType.LAZY)
@com.fasterxml.jackson.annotation.JsonIgnore
@JsonBackReference
public User user;
@Getter
@Setter
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="interest_id")
@ManyToOne(fetch = FetchType.LAZY)
@com.fasterxml.jackson.annotation.JsonIgnore
@JsonBackReference
public Interest interest;
}
当我在加入的User对象上运行以下内容时,我收到错误:
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
ow.writeValueAsString(userSet);
我对 Hibernate 非常陌生,所以我们非常感谢任何指针。我已经阅读了5-10篇SO文章,这些文章提出了我上面提到的解决方案,但我仍然无法停止循环引用。万分感谢!
答案 0 :(得分:0)
你应该解开你的对象。来自here
的示例@SuppressWarnings("unchecked")
protected T unproxy(T entity){
if (entity == null) {
return null;
}
if (entity instanceof HibernateProxy) {
try {
Hibernate.initialize(entity);
} catch (ObjectNotFoundException e) {
return null;
}
entity = (T) ((HibernateProxy) entity).getHibernateLazyInitializer().getImplementation();
}
return entity;
}
或者这样(来自here)
public <P> List<P> unproxy(Collection<P> objects) {
Session session = sessionFactory.getCurrentSession();
List<P> result = new ArrayList<P>();
for (P t : objects) {
Object unproxied = ((SessionImplementor)session).getPersistenceContext().unproxy(t);
result.add((P) unproxied);
}
return result;
}
答案 1 :(得分:0)
找到解决方案。对于我的ObjectWriter / ObjectMapper,我切换到com.fasterxml.jackson.databind.ObjectWriter / Mapper而不是codehaus。似乎jsonIgnore和JsonIdentityInfo并没有得到codehaus.jackson.map的承认,或者至少不是我的版本。