我有一个用户对象,我从休眠会话中提取。 User对象有一组Car对象,我正在检索它并转换为JSON。问题是,当我返回要转换为JSON的Set时,它会进入解析它的无限循环,因为hibernate会话仍处于活动状态。
代码如下所示:
public Set<Car> getUserCurrentCar(User user) {
user = (User) session.get(User.class, user.getId());
Set<Car> retrievedCars = (Set<Car>) user.getCars();
session.close();
return retrievedCars;
}
然而,当我将对象值移动到没有会话的对象时,一切都解析得很好而没有错误:
public Set<Car> getUserCurrentCar(User user) {
user = (User) session.get(User.class, user.getId());
Set<Car> Cars = new HashSet<Car>();
Set<Car> retrievedCars = (Set<Car>) user.getCars();
for(Car Car :retrievedCars){
Car newCar = new Car();
newCar.setTitle(car.getTitle());
cars.add(newCar);
}
session.close();
return cars;
}
虽然这有效,但我希望将来修改我的对象并避免所有这些看起来重复的对象转移。
此外,我的Car对象在hibernate映射中具有对用户的多对一后向引用:
<many-to-one name="user"
column="userId"
not-null="true"/>
如何避免这种情况,并使用真正的分离对象解析为JSON?
答案 0 :(得分:1)
您遇到的问题与Hibernate会话无关。相反,您的JSON框架在序列化循环引用时遇到问题,导致堆栈溢出。一个解决方案是启用Restlet框架中的Jackson extension,然后使用JacksonRepresentation序列化对象。启用Jackson后,您可以按照下面显示的方式注释对象,然后更优雅地处理循环引用:
public class User implements Serializable {
public static final String REFERENCE_CARS = "user.cars";
private Set<Car> cars;
// constructors, etc
@JsonManagedReference(REFERENCE_CARS)
public Set<Car> getCars() {
return cars;
}
}
public class Car implements Serializable {
private User user;
// constructors, etc
@JsonBackReference(User.REFERENCE_CARS)
public User getUser() {
return user;
}
}
请注意,User
是此关系的拥有方,因此它包含的任何汽车都将以其JSON序列化。另一方面,Car
是关系的拥有方,因此User
对象将不 *出现在其JSON中。
答案 1 :(得分:0)
正如我在问题中所提到的,我想简单地从hibernte中提取一个对象并将其转换为JSON。由于Car对象在其嵌套对象中有一个后向引用,因此像Restlets和google GSON这样的JSON框架进入了无限循环。
我想避免它,但是我不得不从休眠中拉出对象然后我手动循环遍历对象并填充新创建的对象,正是我需要的东西。
当这些对象的值发生变化时,这将导致未来的维护工作,但最终确实有效。
回答:从hibernate拉取对象。创建单独的java对象。循环遍历对象并使用休眠对象值填充新创建的对象。