Spring Boot JPA 错误:无法处理托管/反向引用“defaultReference”:从类型中找不到反向引用属性
Posted
技术标签:
【中文标题】Spring Boot JPA 错误:无法处理托管/反向引用“defaultReference”:从类型中找不到反向引用属性【英文标题】:Spring boot JPA error : Cannot handle managed/back reference 'defaultReference': no back reference property found from type 【发布时间】:2018-10-08 06:01:11 【问题描述】:我有以下 3 个域模型对象,其中 appuser 的排名和培训状态如下。获取调用在返回 JSON 对象的情况下工作正常,但在 JPA 中添加模型对象时出现错误。
Cannot handle managed/back reference 'defaultReference': no back reference property found from type [simple type, class com.springboot.model.Rank
`
package com.springboot.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonManagedReference;
@Entity
@Table(name = "app_user", catalog = "testdb")
public class AppUser implements java.io.Serializable
private Integer id;
private Rank rank;
private Trainingstatus trainingstatus;
private String name;
private int age;
private double salary;
public AppUser()
public AppUser(Rank rank, Trainingstatus trainingstatus, String name, int age, double salary)
this.rank = rank;
this.trainingstatus = trainingstatus;
this.name = name;
this.age = age;
this.salary = salary;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
public Integer getId()
return this.id;
public void setId(Integer id)
this.id = id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "rankId", nullable = false)
@JsonManagedReference
public Rank getRank()
return this.rank;
public void setRank(Rank rank)
this.rank = rank;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "trainingStatusId", nullable = false)
@JsonManagedReference
public Trainingstatus getTrainingstatus()
return this.trainingstatus;
public void setTrainingstatus(Trainingstatus trainingstatus)
this.trainingstatus = trainingstatus;
@Column(name = "name", nullable = false, length = 30)
public String getName()
return this.name;
public void setName(String name)
this.name = name;
@Column(name = "age", nullable = false)
public int getAge()
return this.age;
public void setAge(int age)
this.age = age;
@Column(name = "salary", nullable = false, precision = 22, scale = 0)
public double getSalary()
return this.salary;
public void setSalary(double salary)
this.salary = salary;
package com.springboot.model;
// Generated 28 Apr, 2018 5:35:48 PM by Hibernate Tools 4.3.5.Final
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonManagedReference;
/**
* Trainingstatus generated by hbm2java
*/
@Entity
@Table(name = "trainingstatus", catalog = "testdb")
public class Trainingstatus implements java.io.Serializable
private Integer trainingStatusId;
private String trainingStatus;
private String lastUpdatedBy;
private Date lastUpdatedDate;
private Set<AppUser> appUsers = new HashSet<AppUser>(0);
public Trainingstatus()
public Trainingstatus(String trainingStatus, String lastUpdatedBy, Date lastUpdatedDate)
this.trainingStatus = trainingStatus;
this.lastUpdatedBy = lastUpdatedBy;
this.lastUpdatedDate = lastUpdatedDate;
public Trainingstatus(String trainingStatus, String lastUpdatedBy, Date lastUpdatedDate, Set<AppUser> appUsers)
this.trainingStatus = trainingStatus;
this.lastUpdatedBy = lastUpdatedBy;
this.lastUpdatedDate = lastUpdatedDate;
this.appUsers = appUsers;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "trainingStatusId", unique = true, nullable = false)
public Integer getTrainingStatusId()
return this.trainingStatusId;
public void setTrainingStatusId(Integer trainingStatusId)
this.trainingStatusId = trainingStatusId;
@Column(name = "trainingStatus", nullable = false, length = 45)
public String getTrainingStatus()
return this.trainingStatus;
public void setTrainingStatus(String trainingStatus)
this.trainingStatus = trainingStatus;
@Column(name = "lastUpdatedBy", nullable = false, length = 45)
public String getLastUpdatedBy()
return this.lastUpdatedBy;
public void setLastUpdatedBy(String lastUpdatedBy)
this.lastUpdatedBy = lastUpdatedBy;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "lastUpdatedDate", nullable = false, length = 19)
public Date getLastUpdatedDate()
return this.lastUpdatedDate;
public void setLastUpdatedDate(Date lastUpdatedDate)
this.lastUpdatedDate = lastUpdatedDate;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "trainingstatus")
@JsonBackReference
// @JsonIgnore
public Set<AppUser> getAppUsers()
return this.appUsers;
public void setAppUsers(Set<AppUser> appUsers)
this.appUsers = appUsers;
package com.springboot.model;
// Generated 28 Apr, 2018 5:35:48 PM by Hibernate Tools 4.3.5.Final
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import com.fasterxml.jackson.annotation.JsonBackReference;
@Entity
@Table(name = "rank", catalog = "testdb")
public class Rank implements java.io.Serializable
private Integer rankId;
private String rank;
private String lastUpdatedBy;
private Date lastUpdatedDate;
private Set<AppUser> appUsers = new HashSet<AppUser>(0);
public Rank()
public Rank(String rank, String lastUpdatedBy, Date lastUpdatedDate)
this.rank = rank;
this.lastUpdatedBy = lastUpdatedBy;
this.lastUpdatedDate = lastUpdatedDate;
public Rank(String rank, String lastUpdatedBy, Date lastUpdatedDate, Set<AppUser> appUsers)
this.rank = rank;
this.lastUpdatedBy = lastUpdatedBy;
this.lastUpdatedDate = lastUpdatedDate;
this.appUsers = appUsers;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "rankId", unique = true, nullable = false)
public Integer getRankId()
return this.rankId;
public void setRankId(Integer rankId)
this.rankId = rankId;
@Column(name = "rank", nullable = false, length = 45)
public String getRank()
return this.rank;
public void setRank(String rank)
this.rank = rank;
@Column(name = "lastUpdatedBy", nullable = false, length = 45)
public String getLastUpdatedBy()
return this.lastUpdatedBy;
public void setLastUpdatedBy(String lastUpdatedBy)
this.lastUpdatedBy = lastUpdatedBy;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "lastUpdatedDate", nullable = false, length = 19)
public Date getLastUpdatedDate()
return this.lastUpdatedDate;
public void setLastUpdatedDate(Date lastUpdatedDate)
this.lastUpdatedDate = lastUpdatedDate;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "rank")
@JsonBackReference
// @JsonIgnore
public Set<AppUser> getAppUsers()
return this.appUsers;
public void setAppUsers(Set<AppUser> appUsers)
this.appUsers = appUsers;
从我的其余应用程序中,我添加 AppUser 父对象,如下所示:
@RequestMapping(value = "/user/", method = RequestMethod.POST)
public ResponseEntity<?> createUser(@RequestBody AppUser user, UriComponentsBuilder ucBuilder)
logger.info("Creating AppUser : ", user);
if (userService.isUserExist(user))
logger.error("Unable to create. A AppUser with name already exist", user.getName());
return new ResponseEntity(new CustomErrorType("Unable to create. A AppUser with name " +
user.getName() + " already exist."),HttpStatus.CONFLICT);
userService.saveUser(user);
HttpHeaders headers = new HttpHeaders();
headers.setLocation(ucBuilder.path("/api/user/id").buildAndExpand(user.getId()).toUri());
return new ResponseEntity<String>(headers, HttpStatus.CREATED);
这是我的 json 对象,它是从 UI 创建用户操作构建的。
"age": 24,
"name": "Amit",
"salary": 15000,
"rank":
"rank": "Clark"
,
"trainingstatus":
"trainingStatus": "Completed"
但这会导致使用 JPA 持久化对象时出错。
.MappingJackson2HttpMessageConverter : Failed to evaluate Jackson deserialization for type [simple type, class com.springboot.model.AppUser]
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot handle managed/back reference 'defaultReference': no back reference property found from type [simple type, class com.springboot.model.Rank]
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67) ~[jackson-databind-2.9.3.jar:2.9.3]
at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1451) ~[jackson-databind-2.9.3.jar:2.9.3]
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase._resolveManagedReferenceProperty(BeanDeserializerBase.java:766) ~[jackson-databind-2.9.3.jar:2.9.3]
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.resolve(BeanDeserializerBase.java:474) ~[jackson-databind-2.9.3.jar:2.9.3]
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:293) ~[jackson-databind-2.9.3.jar:2.9.3]
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244) ~[jackson-databind-2.9.3.jar:2.9.3]
at com.fasterxml.jackson.databind.deser.DeserializerCache.hasValueDeserializerFor(DeserializerCache.java:191) ~[jackson-databind-2.9.3.jar:2.9.3]
at com.fasterxml.jackson.databind.DeserializationContext.hasValueDeserializerFor(DeserializationContext.java:422) ~[jackson-databind-2.9.3.jar:2.9.3]
at com.fasterxml.jackson.databind.ObjectMapper.canDeserialize(ObjectMapper.java:2863) ~[jackson-databind-2.9.3.jar:2.9.3]
【问题讨论】:
你能提供你的模型结构吗? 嗨@Novy,您现在可以检查一下吗?对您有很大帮助吗? 我已经在 Github 中添加了我的测试项目:github.com/harshalpatil2012/Springboot 【参考方案1】:我已经通过从我的父类 AppUser 中删除注释 @JsonManagedReference 解决了这个问题。只是将@JsonBackReference 保留在子类中并添加 之后所有 3 个类的 JsonIdentityInfo 注释我的休息 getUser 和创建用户操作完美运行,并且它为这两个操作返回有效的 JSON。
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
【讨论】:
以上是关于Spring Boot JPA 错误:无法处理托管/反向引用“defaultReference”:从类型中找不到反向引用属性的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot - Mysql Driver - JPA - 在服务器运行发布请求很长时间后显示无法打开 JPA EntityManager 进行事务处理
java - 如何在spring boot java中编写一个函数来处理JPA存储库中的自定义查询?
无法将 Spring Data MongoDB + Spring Data JPA 与 Spring Boot 一起使用
无法访问托管在 EBS 上的 Spring Boot 应用程序