Hibernate懒洋洋地加载字段

时间:2014-08-07 03:28:35

标签: java spring hibernate

我有这个问题与hibernate。情景是我正在改造我的项目。我之前的项目是使用JMS,它与我的POJO顺利运行。现在我正在尝试使用Google Mina(套接字编程)与Google的Gson重新创建它。

我在延迟加载我的字段时遇到问题,因为使用JMS的项目在延迟加载时运行顺畅但现在我试图在数据库中检索一些值,但总是有一个hibernate异常声明{{1}我想懒惰地加载,我不想每次都检索它。

failed to lazily initialize a collection of role: class.field, no session or session was closed

我正在我的DAO中检索它

public class User {
    @Id
    @GeneratedValue
    @Column(name = "iduser")
    private Integer             iduser;

    @Column(name = "firstname")
    private String              firstname;

    @Column(name = "lastname")
    private String              lastname;

    //     this field causes the lazy loading exception
    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    @BatchSize(size = 4)
    private Set<Transaction>    transaction;
}

我调用服务的方法

public User findByUser(String username, String pass) {
        // TODO Auto-generated method stub
        try {
            User instance = (User) getSession().createCriteria(User.class)
                    .add(Restrictions.eq(USERNAME, username))
                    .add(Restrictions.eq(PASS, pass)).uniqueResult();
            return instance;
        } catch (RuntimeException re) {
            throw re;
        }
    }

调用DAO类的signin方法

public ModelAndView processSignin(User currentUser, BindingResult result,
            HttpServletRequest request) {
User user = service.signin(currentUser);
//i try to convert it to GSON but when i comment this line of code it works fine. but when gson tries to convert it to json string it seems that the annotations are being executed
System.out.println(gson.toJson(user));
}

3 个答案:

答案 0 :(得分:0)

如果您使用Spring和Hibernate(根据问题的标签似乎就是这种情况),您可能需要配置Spring事务管理(小教程:http://www.baeldung.com/2011/12/26/transaction-configuration-with-jpa-and-spring-3-1/)。

然后,您将需要注释使用带有@Transactional的Hibernate实体的任何方法(在Spring bean上)。这将保证任何Hibernate对象都将在会话的上下文中加载,并且如果碰巧触发延迟初始化,Hibernate将能够使用该会话获取对象。

在您的情况下,您可能希望使用@Transactional注释加载和序列化User to JSON的方法。请注意,如果您有2个Spring应用程序上下文(一个根和一个用于Spring MVC),则注释很可能只适用于根应用程序上下文中定义的bean(因此注释控制器可能不起作用,请参阅@Transactional methods in @Controller class are not considred as transactional

@Transactional
public String signinAndSerialize(String username, String password) {
    User user = service.signin(username, password);
    return gson.toJson(user);
}

答案 1 :(得分:0)

使用Hibernate时,只有在加载整个对象的同一事务中调用字段的getter时,延迟加载才有效。这意味着,如果在事务完成时调用getter,并且Hibernate会话关闭,则抛出延迟加载异常。

您可以在事务处理块内进行转换,也可以按照here

中的说明从序列化中排除特定字段

答案 2 :(得分:0)

默认情况下,Hibernate支持延迟加载。你可以这样做:

  1. 首先评估您是否真的需要关系数据。如果您不需要关系数据,那么在JSON转换期间有一些方法/注释可以忽略它。例如。用@JsonIgnore注释该字段(import org.codehaus.jackson.annotate.JsonIgnore;)。

  2. 如果您真的需要数据,那么在您的休眠会话仍然打开时检索它。

  3. 通过向@OneToMany注释fetch = FetchType.EAGER添加以下属性,显式转换为EagerLoading。但是,这会对性能产生影响。