0

我有一个从休眠会话中提取的用户对象。User 对象有一组 Car 对象,我正在检索这些对象并将其转换为 JSON。问题是,当我返回要转换为 JSON 的 Set 时,它会进入一个无限循环的解析,这似乎是因为休眠会话仍然处于活动状态。

代码如下所示:

        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 对象在休眠映射中具有对 User 的多对一反向引用:

<many-to-one name="user" 
    column="userId"
    not-null="true"/>

如何避免这种情况,并使用真正分离的对象解析为 JSON?

4

2 回答 2

1

您遇到的问题与 Hibernate 会话无关。相反,您的 JSON 框架在序列化循环引用时遇到问题,从而导致堆栈溢出。一种解决方案是在您的 Restlet 框架中启用Jackson 扩展,然后使用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 中。

于 2012-12-20T06:11:35.163 回答
0

正如我的问题中提到的,我想简单地从休眠中提取一个对象并将其转换为 JSON。由于 Car 对象在其嵌套对象中具有对 User 对象的反向引用,因此 Restlets 和 google GSON 等 JSON 框架进入了无限循环。

我想避免它,但我必须从休眠中拉出对象,然后手动循环遍历对象并用我需要的内容填充新创建的对象。

当这些对象的值发生变化时,这将导致未来的维护工作,但它最终确实有效。

答案:从休眠中拉出对象。创建单独的 java 对象。循环遍历对象并使用休眠对象值填充新创建的对象。

于 2013-01-04T22:17:32.523 回答