如何获取列表的大小(列表是类之间的M2M映射)

时间:2014-01-15 06:06:34

标签: java spring hibernate spring-mvc

@Entity
public class EUser {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id; 
    @Column(nullable = false)
    private String userName;

    @ManyToMany
    private List<UserRole> roles;


        //getters and setters method here

}


@Entity
public class UserRole {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    private String roleName;


        //getters and setters method here
}

现在使用该服务我试图查看roles列表

的大小
EUser approveUser = (EUser) userService.getOne(2);
System.out.println(approveUser.getRoles().size());

但是我收到以下错误

SEVERE: Servlet.service() for servlet [spring] in context with path [/Ebajar] threw exception [Request processing failed; nested exception is org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.ebajar.model.EUser.roles, no session or session was closed] with root cause
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.ebajar.model.EUser.roles, no session or session was closed

如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

将您的EUser实体类更改为

@Entity
public class EUser {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id; 
    @Column(nullable = false)
    private String userName;

    @ManyToMany(fetch=FetchType.EAGER)
    private List<UserRole> roles;


        //getters and setters method here

}

答案 1 :(得分:1)

让我向你解释一下:

由于spring将创建一个与sessionFactory相关的DB connection session,在eager从数据库获取数据的调试模式下,它可以像数据库会话那样执行没有关闭。

但是当你在lazily时,可怜session已经关闭,你无法从中获取数据。更重要的是,你会得到no session or session was closed,我第一次与ERRORspring取得联系时也得到了hibernate,这让我困惑了很长时间时间。

我认为基本问题在于,您没有会话维护者来保持您的会话在您刚刚调试时没有strutsspringmvc

要解决这个问题,我认为有三种方法:
1.整个框架的调试包括会话维护者,这是如此缓慢和沉重! 2.在web.xml中添加会话过滤器:

<filter>
     <filter-name>session</filter-name>
    <filter-class>
        org.springframework.orm.hibernate4.support.OpenSessionInViewFilter
    </filter-class>
</filter>
<filter-mapping>
    <filter-name> session </filter-name>
    <url-pattern> /* </url-pattern>
</filter-mapping>

将维护您与数据库的会话 3.或者你可以使用Mocked测试方法模仿会话维护者在做什么。

最后,我不会建议您使用eager设置所有类型,因为这可能会降低应用程序的性能。即使在测试阶段不重要,但在测试阶段模仿真实环境也很重要。