سؤال

i have application with OpenJPA and entity User and UserHasRoles:

public class User implements Serializable {
 @Id
 @GeneratedValue
 @Basic(optional = false)
 @Column(name = "id_user")
 private Integer idUser;
 @Size(max = 8)
 @Column(name = "login")
 private String login;
 @Size(max = 64)
 @Column(name = "password")
 private String password;
 @OneToMany(cascade = CascadeType.ALL, mappedBy = "user", fetch=FetchType.LAZY)
 private List<UserHasRoles> userHasRolesList;

 //getters, setters ...
}

public class UserHasRoles implements Serializable {
 @EmbeddedId
 protected UserHasRolesPK userHasRolesPK;
 @Basic(optional = false)
 @NotNull
 @Size(min = 1, max = 45)
 @Column(name = "role_name")
 private String roleName;
 @JoinColumn(name = "id_user", referencedColumnName = "id_user", insertable = false, updatable = false)
 @ManyToOne(optional = false)
 private User user;

 //getters, setters ...
}

when i run this code i get NullPointerException:

User user = new User(); //utworzenie użytkownika i dodanie do bazy    
user.setLogin(registerLog);
user.setPassword(registerPass);
userFacade.create(user);

UserHasRoles userHasRoles = new UserHasRoles(user.getIdUser(), new Short("2"));
userHasRoles.setRoleName("admin");
userHasRoles.setUser(user);
userHasRolesFacade.create(userHasRoles);

ArrayList<UserHasRoles> list = new ArrayList<UserHasRoles>();       //1
list.add(userHasRoles);                                             //1    
user.setUserHasRolesList(list);                                     //1 
userFacade.edit(user);                                              //1 


User u = userFacade.find(user.getIdUser());
List l = u.getUserHasRolesList();

l.get(0); //i get there NullPointerException, because l is null

why after persist and merge object (adding list of UserHasRoles - 1 in comment above) i get null when i find object ?


my persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="CollDocPU" transaction-type="JTA">
<jta-data-source>java:openejb/Resource/myDatabase</jta-data-source>
<non-jta-data-source>java:openejb/Resource/myDatabaseUnmanaged</non-jta-data-source>
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<class>model.entity.Course</class>
<class>model.entity.CourseHasLecturer</class>
<class>model.entity.File</class>
<class>model.entity.Lecturer</class>
<class>model.entity.Mail</class>
<class>model.entity.Roles</class>
<class>model.entity.Solution</class>
<class>model.entity.Student</class>
<class>model.entity.StudentAddSolution</class>
<class>model.entity.StudentAtCourse</class>
<class>model.entity.Task</class>
<class>model.entity.User</class>
<class>model.entity.UserHasRoles</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
  <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:11080/me?zeroDateTimeBehavior=convertToNull"/>
  <property name="javax.persistence.jdbc.password" value="pass"/>
  <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
  <property name="javax.persistence.jdbc.user" value="me"/>
  <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
</properties>

هل كانت مفيدة؟

المحلول 2

The problem was with life cycle of enties. All enties must be re-attached to the persistence context.

To resolve it i had to make getUserHasRolesList method at userFacade:

public List<UserHasRoles> getUserHasRolesList(User us){

    us = em.merge(us);      //here i re-attached entity

    return us.getUserHasRolesList();
}

Same problem is here: OpenJPA - lazy fetching does not work and here: What's the lazy strategy and how does it work?

نصائح أخرى

FetchType.LAZY loads the list only when you call the method getUserHasRolesList() and this method seems to be in the "User" class

@OneToMany(cascade = CascadeType.ALL, mappedBy = "user", fetch=FetchType.LAZY)
 private List<UserHasRoles> userHasRolesList;

You can change the fetch to EAGER, then the list will be loaded together with the rest of the fields.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top