我有OpenJPA和实体User
和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 ...
}
当我运行此代码时,我得到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
为什么在持久化并合并对象(在上面的评论中添加UserHasRoles
- 1的列表)后,当我找到对象时,我得到null?
我的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>
答案 0 :(得分:1)
FetchType.LAZY
仅在您调用方法getUserHasRolesList()
时加载列表,此方法似乎位于“用户”类
@OneToMany(cascade = CascadeType.ALL, mappedBy = "user", fetch=FetchType.LAZY)
private List<UserHasRoles> userHasRolesList;
您可以将提取更改为EAGER,然后列表将与其他字段一起加载。
答案 1 :(得分:1)
问题在于内容的生命周期。必须将所有内容重新附加到持久化上下文中。
要解决此问题,我必须在getUserHasRolesList
处制作userFacade
方法:
public List<UserHasRoles> getUserHasRolesList(User us){
us = em.merge(us); //here i re-attached entity
return us.getUserHasRolesList();
}
同样的问题在这里:OpenJPA - lazy fetching does not work和此处:What's the lazy strategy and how does it work?