简体   繁体   English

如何解决lazyinitializationexception不使用fetch = FetchType.EAGER?

[英]how to solve lazyinitializationexception not using fetch=FetchType.EAGER?

Iam still getting the exception lazyinitializationexception. 我仍然得到异常lazyinitializationexception。 Yes, i know that it means, that the session is closed while I or something else is trying to access the collection. 是的,我知道这意味着会话在我或其他人试图访问该集合时关闭。 No, the OpenEntityManagerInViewFilter did not work. 不,OpenEntityManagerInViewFilter不起作用。 Yes, @ManyToOne(fetch=FetchType.EAGER) helped but i dont want to use it, cause it will fecth aumotically all the time. 是的,@ ManyToOne(fetch = FetchType.EAGER)有所帮助,但我不想使用它,因为它会一直在fumh fecth。

How Else can i do that ? 我怎么能这样做?

PS : I am using HibernateEntityManger with jpa with annotated class. PS:我正在使用带有注释类的jpa的HibernateEntityManger。

UPADATE here is my code, first of all I have 4 tables : users(id,first_name,last_name,email....) roles(id,name,comment....) users_roles(user_id,role_id) mails(id,user_id,subject,message,to_id...) UPADATE这里是我的代码,首先我有4个表:users(id,first_name,last_name,email ....)role(id,name,comment ....)users_roles(user_id,role_id)mails(id, USER_ID,主题,邮件,to_id ...)

An user can have mutiples roles .... Users Entity 用户可以拥有多个角色......用户实体

@Entity
@Table(name = "USERS")
public class User implements GenericDomain{

    public static final String  _ID = "id";
private Long    id;
private String  firstName;
private String  lastName;
private String  email;  
private Set<Role> roles = new HashSet<Role>(0);

/* Constructors */  
public User() {
}

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name = "ID", unique = true, nullable = false)
public Long getId() { return this.id; }
public void setId(Long id) { this.id = id; }

@Column(name="FIRST_NAME", nullable = false, length = 64)
@NotEmpty
@Length(min = 4, max = 45)
public String getFirstName() { return this.firstName;   }
public void setFirstName(String firstname) { this.firstName = firstname; }

@Column(name="LAST_NAME", nullable = false, length = 64)
@NotEmpty
@Length(min = 4, max = 45)
public String getLastName() { return this.lastName; }
public void setLastName(String lastname) { this.lastName = lastname; }

@Column(name="EMAIL", unique = false, length = 64)
@Email
@NotEmpty
@Length(min = 4, max = 45)
public String getEmail() { return this.email; }
public void setEmail(String email) { this.email = email; }

@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(name = "USERS_ROLES"
    , joinColumns = { @JoinColumn(name = "user_id") }
    , inverseJoinColumns = { @JoinColumn(name = "role_id") }
)
public Set<Role> getRoles() {
    return this.roles;
}
public void setRoles(Set<Role> roles) {
    this.roles = roles;
}

/*@Override toString/equals/hascode  */

} }

Role Entity 角色实体

@Entity
@Table(name = "ROLES")
public class Role implements GenericDomain {
private Long    id;
private String  name;
private String  comment;
private Set<User> users = new HashSet<User>(0);

public Role() {
}

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name = "ID", unique = true, nullable = false)
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }

@Column(name="NAME", nullable = false, length = 64)
@NotEmpty
@Length(min = 1, max = 32)
public String getName() { return name; }
public void setName(String name) { this.name = name; }

@Column(name="COMMENT", nullable = true, length = 256)
@Length(min = 0, max = 255)
public String getComment() { return this.comment; }
public void setComment(String comment) { this.comment = comment;}

@ManyToMany(cascade=CascadeType.REFRESH,fetch=FetchType.EAGER)
@JoinTable(
    name = "USERS_ROLES"
    , joinColumns = { @JoinColumn(name = "role_id") }
    , inverseJoinColumns = { @JoinColumn(name = "user_id") }
)
public Set<User> getUsers() {
    return this.users;
}
public void setUsers(Set<User> users) {
    this.users = users;
}

/*@Override toString/equals/hascode  */

} }

mails 邮件

@Entity @Table(name = "mails") public class Mail implements GenericDomain{ @Entity @Table(name =“mails”)公共类Mail实现GenericDomain {

private Long    id;
private String  mailSubject;
private String  mailContent;
private Long    receiverId;
private User    user = null;

public Mail(){  
}

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)
public Long getId(){    return this.id; }
public void setId(Long id){ this.id = id;}

@Column(name = "MAILSUBJECT", nullable = false, length = 63)
@Length(max = 63)
public String getMailSubject(){ return this.mailSubject;    }
public void setMailSubject(String mailSubject){ this.mailSubject = mailSubject; }

@Column(name = "MAILCONTENT", nullable = true, length = 255)
@Length(max = 255)
public String getMailContent(){ return this.mailContent;    }
public void setMailContent(String mailContent){ this.mailContent = mailContent; }   

@Column(name = "RECEIVERID")
public Long getReceiverId(){    return this.receiverId; }
public void setReceiverId(Long receiverId){ this.receiverId = receiverId;   }   


@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name = "USER_ID")
@NotNull
public User getUser(){ return this.user;    }
public void setUser(User user){ this.user = user;   }
}

user controller 用户控制器

@Controller
@RequestMapping("/admin/user")
@SessionAttributes("user")
public class UserController {

private UserService userService;
private RoleService roleService;

@Autowired
public UserController(UserService userService, RoleService roleService) {
    this.userService = userService;
    this.roleService = roleService;
}
@RequestMapping(value = "edit", method = RequestMethod.GET)
public String editUser(@RequestParam(value="id", required = true) Long id, ModelMap model) {

    model.addAttribute("allRoles", roleService.getAll());
    model.addAttribute("user", userService.getOne(id));
    return "/admin/user/edit";
}    }

mail controller 邮件控制器

@Controller
@SessionAttributes("mail")
@RequestMapping("/portal/mail")
public class MailController{

@Autowired
private MailService mailService;

@RequestMapping(value = "ajaxLoad", method = RequestMethod.GET)
public @ResponseBody List<Mail> list(@RequestParam(value = "type", required = true) String type){
    return mailService.getUserMails((Long) WebHelper.getPrincipal().getUser().getId(),type);
}   

} }

my web.xml 我的web.xml

<filter>
    <filter-name>SpringOpenEntityManagerInViewFilter</filter-name>
    <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>SpringOpenEntityManagerInViewFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>   

my edit.jsp for user 我的edit.jsp用户

<select >
<c:forEach items="${allRoles}" var="role">
    <option value="${role.id}" <c:if test="${fn:contains(roleSelected, role)}">selected="selected"</c:if> >${role.name}</option>
</c:forEach>
</select>

With all that, i edit.jsp for user is working fine with lazy=false. 尽管如此,我使用edit.jsp for lazy = false正常工作。 With FetchType.EAGER am not able to get any of my mails, am getting into a cycle stackovrflow, without FetchType.EAGER i got that lazy exception. 使用FetchType.EAGER我无法获取任何邮件,进入循环stackovrflow,没有FetchType.EAGER我得到了这个懒惰的异常。

OpenEntityManagerInViewFilter and OpenEntityManagerInViewInterceptor work. OpenEntityManagerInViewFilterOpenEntityManagerInViewInterceptor工作。 You are doing something wrong. 你做错了什么。

Apart from that, you can use Hibernate.initialize(..) to initialize your collections. 除此之外,您可以使用Hibernate.initialize(..)来初始化您的集合。 But doing this manually is not preferred. 但手动执行此操作并不是首选。 Give more details of why the filter/interceptor don't work. 详细说明滤波器/拦截器无法工作的原因。

Update: Instead of mapping the filter to a pattern, map it to the dispatcher servlet. 更新:不是将过滤器映射到模式,而是将其映射到调度程序servlet。 So instead of specifying <url-pattern> specfiy <servlet-name> . 因此,而不是指定<url-pattern> specfiy <servlet-name>

removing all the eager and adding this solve my problem 删除所有渴望并添加此解决我的问题

    <mvc:interceptors>
    <bean class="org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor">  
        <property name="entityManagerFactory" ref="entityManagerFactory" />  
    </bean>
</mvc:interceptors>

the filter didnt work 过滤器没有用

First of all, check if you really need Collection rather than Set . 首先,检查你是否真的需要Collection而不是Set If objects within collection are unique, declare variable as Set , which solves 90% of issues with LazyInitializationException . 如果集合中的对象是唯一的,则将变量声明为Set ,这解决了LazyInitializationException 90%问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM