Java 休眠惰性加载字段

Java 休眠惰性加载字段,java,spring,hibernate,Java,Spring,Hibernate,我对hibernate有这个问题。情况是我正在重新设计我的项目。我以前的项目是使用JMS的,它可以与我的POJO顺利运行。现在我正试图用ApacheMina(socket编程)和Google的Gson重新创建它 我在延迟加载我的字段方面遇到了问题,因为使用JMS的项目在延迟加载的情况下运行平稳,但现在我尝试检索数据库中的一些值,但总是有一个hibernate异常,说明未能延迟初始化role:class.field的集合,没有会话或会话被关闭,我想延迟加载,我不想每次都检索它 public cla

我对hibernate有这个问题。情况是我正在重新设计我的项目。我以前的项目是使用JMS的,它可以与我的POJO顺利运行。现在我正试图用ApacheMina(socket编程)和Google的Gson重新创建它

我在延迟加载我的字段方面遇到了问题,因为使用JMS的项目在延迟加载的情况下运行平稳,但现在我尝试检索数据库中的一些值,但总是有一个hibernate异常,说明
未能延迟初始化role:class.field的集合,没有会话或会话被关闭
,我想延迟加载,我不想每次都检索它

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 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));
}
调用DAO类的signin方法

public User signinDealer(User user) {
        // TODO Auto-generated method stub
        User currentUser = userDAO.signinUser(user);
        return currentUser;
    }

如果使用Spring和Hibernate(根据问题的标记,情况似乎是这样),您可能需要配置Spring事务管理(小教程:)

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

在您的情况下,您可能希望使用
@Transactional
注释将用户加载并序列化为JSON的方法。请注意,如果您有两个Spring应用程序上下文(一个根,一个用于Spring MVC),那么注释很可能只适用于根应用程序上下文中定义的bean(因此注释控制器可能不起作用,请参阅)


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


您可以在事务块内进行转换,或者按照说明从序列化中排除特定字段。默认情况下,Hibernate启用延迟加载。您可以执行以下操作:

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

  • 如果确实需要数据,请在hibernate会话仍处于打开状态时检索数据

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


  • @Transactional注释与使用AOP的事务管理不同吗?不,可能是同一件事。Spring使用AOP管理会话/事务。我已经在使用AOP事务管理,但它仍然存在。我尝试了注释,但结果还是一样,不幸的是我已经这么做了。但是,在转换过程中,似乎正在执行注释或getter。
    public User signinDealer(User user) {
            // TODO Auto-generated method stub
            User currentUser = userDAO.signinUser(user);
            return currentUser;
        }
    
    @Transactional
    public String signinAndSerialize(String username, String password) {
        User user = service.signin(username, password);
        return gson.toJson(user);
    }