Java 休眠对象不分离
我有一个从hibernate会话中提取的用户对象。用户对象有一组Car对象,我正在检索这些对象并将其转换为JSON。问题是,当我返回要转换为JSON的集合时,它进入了一个无限的解析循环,这似乎是因为hibernate会话仍然处于活动状态 代码如下所示:Java 休眠对象不分离,java,json,hibernate,parsing,hibernate-mapping,Java,Json,Hibernate,Parsing,Hibernate Mapping,我有一个从hibernate会话中提取的用户对象。用户对象有一组Car对象,我正在检索这些对象并将其转换为JSON。问题是,当我返回要转换为JSON的集合时,它进入了一个无限的解析循环,这似乎是因为hibernate会话仍然处于活动状态 代码如下所示: public Set<Car> getUserCurrentCar(User user) { user = (User) session.get(User.class, user.get
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;
}
公共设置getUserCurrentCar(用户){
user=(user)session.get(user.class,user.getId());
Set retrievedCars=(Set)user.getCars();
session.close();
归还找回的汽车;
}
但是,当我在没有会话的情况下将对象值移动到对象中时,一切都可以正常解析,不会出现错误:
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;
}
公共设置getUserCurrentCar(用户){
user=(user)session.get(user.class,user.getId());
Set Cars=new HashSet();
Set retrievedCars=(Set)user.getCars();
用于(汽车:回收汽车){
新车=新车();
newCar.setTitle(car.getTitle());
汽车。添加(新车);
}
session.close();
返回车辆;
}
虽然这是可行的,但我希望在将来修改我的对象,避免所有这些看起来重复的对象传输
此外,my Car对象在hibernate映射中具有对用户的多对一反向引用:
<many-to-one name="user"
column="userId"
not-null="true"/>
如何避免这种情况,并使用真正分离的对象解析为JSON?您遇到的问题与Hibernate会话无关。相反,JSON框架在序列化循环引用时遇到问题,导致堆栈溢出。一种解决方案是在Restlet框架中启用,然后使用序列化对象。启用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;
}
}
公共类用户实现可序列化{
公共静态最终字符串引用\u CARS=“user.CARS”;
私家车;
//建设者等
@JsonManagedReference(参考车)
公共设置getCars(){
返回车辆;
}
}
公共类Car实现可序列化{
私人用户;
//建设者等
@JsonBackReference(User.REFERENCE\u CARS)
公共用户getUser(){
返回用户;
}
}
请注意,
User
是此关系的拥有方,因此它包含的任何汽车都将在其JSON中序列化。另一方面,Car
是关系的拥有方,因此用户
对象不会*出现在其JSON中。正如我在问题中提到的,我只想从hibernte中提取一个对象并将其转换为JSON。因为Car对象在其嵌套对象中有一个对User对象的反向引用,所以像Restlets和googlegson这样的JSON框架进入了一个无限循环
我想避免它,但我必须从hibernate中提取对象,然后手动循环对象,并用我需要的东西填充新创建的对象
当这些对象上的值发生变化时,这将导致将来的维护工作,但它最终会起作用
回答:从休眠状态中拉出对象。创建单独的java对象。循环对象并用hibernate对象值填充新创建的对象。您使用什么JSON库来序列化这些对象?您的
Car
对象不会恰好有对User
的反向引用,是吗?是的,我的Car对象有对User的反向引用。我正在使用RESTlet。我已经添加了上面的参考内容。我该怎么办?不幸的是,我不熟悉Restlet的框架。但真正的问题是循环引用,许多JSON框架根本不知道如何处理循环引用。如果您使用的是Jackson,我可以给您一个解决方案,但实际上您需要了解在Restlet框架中通常如何处理此问题。看起来Restlet支持Jackson。我已经发布了一个可能的解决方案。从您的观点来看,我必须进行手动迭代。如果是这样,在复杂和关键的web应用程序中,更多的迭代和保存新对象实际上是一个占用内存和时间的过程。难道hibernate没有提供更好的解决方案吗!现在,当JAXB为REST服务对我的表对象进行封送时,我也遇到了同样的问题。