简体   繁体   中英

JPA mapping unidirectional @ManyToMany with struts2

Hy guys,

I have a problem with the @OneToMany unidirectional association. Basically in my model I have two entities: Player and Role . I map this relationship with a @ManyToMany cause: One player can have more Role and a Role can be associated with multiple Players.

Player.java

@Entity
public class Player implements Serializable {
    ...
    @ManyToMany
    private List<Role> roles;
    ...
}

Role.java

@Entity
public class Role implements Serializable {
    ...
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String roleName;
    ...
}

I print my player list with struts2 like this:

<table>
...
   <s:iterator value="players" status="player">
     <tr>
     <td><s:property value="name"/></td>
     <td><s:property value="price"/></td>
     <td>
         <s:iterator value="roles" status="role">
             <s:property value="roleName"/>
         </s:itetator>
     </td>
  </s:iterator>
...
</table>

And I get this error:

org.hibernate.LazyInitializationException - failed to lazily initialize a collection of role: no session or session was closed.

Why I'm getting this error? It is wrong the JPA mapping? I tried to remove (just for a check) the role inner iterator and I can see the players table well, but obviously without roles that I need.

NOTE: I tried to debug the application and when I was in the action, I got the List<Player> , I expanded one Player and I saw the List<Roles> with a Persistent Bag variable, I tried to maximized again but I was unable to get the roleName variable.

Can someone help me to figure out the problem? Thanks in advance.

You are trying to access hibernate result which is lazy initialized after closing your hibernate session. That's why you are getting this error. Change initialization type to eager by fetchType.

Actually, if the EAGER solution does not work, I think your only option is to keep the transaction open while you fetch all the data. So basically:

  1. open transaction.

2.- Query the database.

3.- fetch all data and move it to another data structure (some DTO) that will containt only the data that you want. This will go to the roles as well.

4.- close transaction.

5.- generate response using the DTO structure

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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