Husband.java
package com.example.demo.com.example.domain;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;
import javax.persistence.*;
//@Data
//@NoArgsConstructor
//@EqualsAndHashCode
//@ToString
@Entity
@Table(name = "t_husban")
public class Husband {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private String job;
@OneToOne
@JoinColumn(name = "wife_fk",referencedColumnName = "id")
private Wife wife;
//omitted getter/setter
}
Wife.java
package com.example.demo.com.example.domain;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;
import javax.persistence.*;
//@Data
//@NoArgsConstructor
@EqualsAndHashCode(exclude = "husband",callSuper = false)
@Entity
@Table(name = "t_wife")
public class Wife {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
@OneToOne(mappedBy = "wife",cascade = {CascadeType.ALL})
private Husband husband;
//omitted getter/setter
}
Service.java
@Service
public class TestOneToOneEitherSide {
@Autowired
private WifeRepository wifeDao;
@Autowired
private HusbandRepository husbandDao;
public Husband testCreate() {
Husband husband = husbandDao.findByName("Wang");
return husband;
}
}
当我使用spring数据jpa从数据库查询丈夫时,它会在结果中发生无限递归,看到下面的图片。使用@OneToOne注释时出了什么问题?有人能给我一些建议吗?或者我以错误的方式使用注释。
答案 0 :(得分:2)
这是一个已知的问题,当你有双向关系时,jackson将尝试序列化另一侧的每一个引用,以便它具有无限递归的逻辑。
解决方案:有很多解决方案,您可以在一侧使用@JsonIgnore以避免序列化带注释的引用,从而打破无限递归
@EqualsAndHashCode(exclude = "husband",callSuper = false)
@Entity
@Table(name = "t_wife")
@JsonIdentityInfo(generator=ObjectIdGenerators.UUIDGenerator.class, property="@id")
public class Wife {
@JsonIdentityInfo(generator=ObjectIdGenerators.UUIDGenerator.class, property="@id")
@Entity
@Table(name = "t_husban")
public class Husband {
@Id
你也可以使用@JsonManagedReference / @JsonBackReference,检查这个link以获取更多信息如何使用它们
这个答案有一个问题,如果你试图序列化妻子的方向你不会有丈夫的对象,因为解决方案是避免序列化。
有一个很好的解决方案,它在这个link中提到,想法是生成对父实体的引用,所以如果你序列化丈夫,你将有丈夫 - >妻子 - &gt ; [引用丈夫而不是丈夫],你需要做的就是用@JsonIdentityInfo注释你的实体
import { fetchPosts } from '../actions';
import React, {Component} from 'react';
import {bindActionCreators, dispatch} from 'redux';
import {connect} from 'react-redux';
import PropTypes from 'prop-types';
import map from 'lodash/fp/map';
import flatten from 'lodash/fp/flatten';
import sortBy from 'lodash/fp/sortBy';
import compose from 'lodash/fp/compose';
import take from 'lodash/fp/take';
import _ from 'lodash';
class PostsIndex extends Component {
state = {
posts: []
};
componentDidMount() {
this.props.fetchPosts();
}
displayPosts () {
//console.log(post) works, console.log(post.title) returns undefined.
return _.map(this.props.posts, (post)=>{debugger;console.log(post.title);});
}
render() {
if(this.props.posts.length === 0) {
return (<div>Loading...</div>);
}
return (<ul>{this.displayPosts()}</ul>);
}
}
function mapStateToProps(state) {
return {
posts: (state.posts) ? state.posts : []
};
}
function mapDispatchToProps (dispatch) {
return bindActionCreators({fetchPosts: fetchPosts}, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(PostsIndex);
答案 1 :(得分:1)
您应该对拥有实体使用@JsonBackReference,对包含实体类的子代使用@JsonManagedReference。
@JsonManagedReference
@Onetoone
private Queue queues;
@Onetoone
@JoinColumn(name = "qid")
// @JsonIgnore
@JsonBackReference
private Queue_group queue_group;
答案 2 :(得分:0)
可以在丈夫字段或妻子字段上使用lombok的@ToString.Exclude来打破循环引用,要么jackson会尝试无限地来回序列化每个引用。
@OneToOne(mappedBy = "wife",cascade = {CascadeType.ALL})
@ToString.Exclude
private Husband husband;
或
@OneToOne
@JoinColumn(name = "wife_fk",referencedColumnName = "id")
@ToString.Exclude
private Wife wife;