对于任何类型的实体的列表属性,我都有一个“奇怪”的行为。
当我尝试将非空列表设置为具有空列表值的检索实体(因为未获取)时,该实体不会“反映”我设置的新非空值。
脚步
- 从具有标准的 ejb 中的数据库中检索任何实体(例如用户)。
- 默认情况下,检索到的实体具有 OneToMany 属性(角色)是惰性的,这就是为什么如果我不执行提取(我不执行)列表为空的原因
- 然后尝试用 NON-EMPTY 列表填充角色列表
- 这里我设置的列表有值,但用户列表在角色列表属性中有一个空值,即使我在步骤 3 中设置了它
我不知道为什么会发生这种情况,我可以解决这个问题的唯一方法是克隆(使用来自 Apache commons.lang3 的 SerializationUtils)用户实体(参见步骤)和这项工作,但我不知道为什么。
- 从具有标准的 ejb 中的数据库中检索任何实体(例如用户)。
- 克隆检索到的实体并分配给新用户 clonedUser = SerializationUtils.clone(originalRetrivedUser);
- 然后尝试用非空列表填充角色列表给 clonedUser
- clonedUser 的列表具有正确的值
为什么我需要克隆?如果没有克隆,为什么我不能为实体设置列表?
我正在使用 Apache TomEE 1.6.0-SNAPSHOT(嵌入了 openjpa 版本)
***** ENTITIES *****
@Entity
public class User implements Serializable{
@Id
private int id;
private String userName;
private String password;
@OneToMany(mappedBy = "user")
private List<Role> roles;
//getters and setters..
}
@Entity
public class Role implements Serializable{
@Id
private int id;
private String roleName;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
//getters and setters..
}
**** EJB INTERFACE LOCAL ****
@Local
public interface MyEJBLocal{
public User getUserWithRoles();
}
**** EJB CLASS ****
@Stateless
public class MyEJB implements MyEJBLocal{
@PersistenceContext(unitName ="ANY_NAME")
private EntityManager em;
@Override
public User getUserWithRoles(){
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> cq = cb.createQuery(User.class);
Root<User> root = cq.from(User.class);
cq.where(cb.equal(root.get(User_.userName),"john"));
User userJohn = em.createQuery(cq).getSingleResult(); // if I want this work I have to do User userJohn = SerializationUtils.clone(em.createQuery(cq).getSingleResult()); [1*]
//I will create a list of role just for try to set any role the userJohn
List<Role> roleList = new ArrayList<Role>(2);
roleList.add(new Role(1,'ADMIN'); //creating and adding role 1
roleList.add(new Role(2,'DEVELOPER');//creating and adding role 2
//setting the list of roles created to the user, as you can see the list has 2 values but the value roles of userJohn always is set to null, my setters and getters are correct
userJohn.setRoles(roleList);
return userJohn;
}
}
*** MANAGED BEAN ****
@Named
public class MyBean implements Serializable{
@EJB
private MyEJBLocal ejb;
public void anyMethod(){
User user = ejb.getUserWithRoles();
user.getRoles(); //<---- HERE THE LIST IS ALWAYS NULL but if I use clone in the ejb method (see 1*) I can get the corrected values.
}
}
我知道我可以通过获取来获取值,但我试图不这样做。
在前面的示例中,我尝试在 ejb 中设置列表,但如果我删除然后将列表放入托管 bean,我会得到相同的行为
我只想检索一个实体并添加一些信息,但我不想保留该新信息。
我正在尝试使用 detach 方法,但没有任何改变。
我不想使用@Transient,因为有时我需要持久化数据,这个想法很简单,我想检索一个实体,然后在 managedbean 中我想添加一个新列表,但无论我在列表中设置什么(实体(用户)的角色) 实体上的列表始终设置为空,就像实体中的列表以某种方式受到保护一样。