我正在使用spring 4.0.1,hibernate 4.3.5,jackson 1.9.2和STS IDE
我正在创建一个RESTful Web服务,它以JSON格式返回数据
当我使用Hibernate代码生成器时,它会为@OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
生成由@ManyToOne(fetch = FetchType.LAZY)
注释的关联实体的getter和setter
和Caused by: com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError)
作为参考
这会在序列化期间导致无限递归。我尝试使用Jackson的@JsonIgnore和@JsonBackReference注释来解决这个问题,但似乎它们被完全忽略了,无限递归仍在发生。
//i get that suggestion from some sites
@JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" })
@Entity
@Table(name = "user", catalog = "someSchema")
public class User implements java.io.Serializable {
private String name;
private String password;
private String username;
private Set<Telephone> telephones = new HashSet<Telephone>(0);
@JsonManagedReference
@OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
public Set<Telephone> getTelephones() {
return this.telephones;
}
public void setTelephones(Set<Telephone> telephones) {
this.telephones = telephones;
}
}
这是我的实体课程 User.class
@Entity
@Table(name = "telephone", catalog = "someSchema")
public class Telephone implements java.io.Serializable {
private User user;
private String telephone;
@ManyToOne(fetch = FetchType.LAZY)
//tried @JsonIgnore only and both
@JsonIgnore
//tried @JsonBackReference only and both
@JsonBackReference
@JoinColumn(name = "user_id", nullable = false)
public User getUser() {
return this.user;
}
@JsonIgnore
@JsonBackReference
public void setUser(User user) {
this.user = user;
}
}
Telephone.class
<mvc:annotation-driven>
<mvc:message-converters>
<bean
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean
class="web.jsonConverters.HibernateAwareObjectMapper" />
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
关于将jackson注册到我的应用程序,我使用了xml config
public class HibernateAwareObjectMapper extends ObjectMapper {
public HibernateAwareObjectMapper() {
Hibernate4Module hm = new Hibernate4Module();
registerModule(hm);
}
}
和mapper类
{{1}}
你知道杰克逊注释被忽略的原因吗?
任何帮助将不胜感激......
答案 0 :(得分:0)
我通过@Transient
idont知道为什么但它工作正常
User.class
//i get that suggestion from some sites
@JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" })
@Entity
@Table(name = "user", catalog = "someSchema")
public class User implements java.io.Serializable {
private String name;
private String password;
private String username;
private Set<Telephone> telephones = new HashSet<Telephone>(0);
@OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
public Set<Telephone> getTelephones() {
return this.telephones;
}
public void setTelephones(Set<Telephone> telephones) {
this.telephones = telephones;
}
}
Telephone.class
@Entity
@Table(name = "telephone", catalog = "someSchema")
public class Telephone implements java.io.Serializable {
private User user;
private String telephone;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
public User getUser() {
return this.user;
}
@Transient
public void setUser(User user) {
this.user = user;
}
}
另一种天真的解决方案
我在RESTful Controller中手动解决了它
循环通过电话机并将用户设置为空
@RestController
@RequestMapping("/user")
public class UserController extends ParentController {
static final Logger logger = Logger.getLogger(UserController.class.getName());
@Autowired
IUserDao iuserdao;
@RequestMapping(value = "/signin", method = RequestMethod.POST)
public ResponseEntity<User> signin(@RequestBody LoginWrapper login) {
System.out.println("==============GET USER==============");
try {
User user = iuserdao.signin(login);
if (user == null) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.set(ERR_HEADER_NAME, "user not exist");
return new ResponseEntity<User>(httpHeaders, HttpStatus.NOT_FOUND);
} else {
List<Telephone> tels=user.getTelephones();
for (Telephone telephone : tels) {
telephone.setUser(null);
}
return new ResponseEntity<User>(user, HttpStatus.OK);
}
} catch (Exception e) {
System.out.println(e.getMessage());
return null;
}
}
关于杰克逊问题仍然需要一个更好的答案..
答案 1 :(得分:0)
使用
import com.fasterxml.jackson.annotation.JsonBackReference;
而不是
import org.codehaus.jackson.annotate.JsonBackReference;