Java 休眠对象不分离

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

我有一个从hibernate会话中提取的用户对象。用户对象有一组Car对象,我正在检索这些对象并将其转换为JSON。问题是,当我返回要转换为JSON的集合时,它进入了一个无限的解析循环,这似乎是因为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;
        }
公共设置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服务对我的表对象进行封送时,我也遇到了同样的问题。