2

对于任何类型的实体的列表属性,我都有一个“奇怪”的行为。

当我尝试将非空列表设置为具有空列表值的检索实体(因为未获取)时,该实体不会“反映”我设置的新非空值。

脚步

  1. 从具有标准的 ejb 中的数据库中检索任何实体(例如用户)。
  2. 默认情况下,检索到的实体具有 OneToMany 属性(角色)是惰性的,这就是为什么如果我不执行提取(我不执行)列表为空的原因
  3. 然后尝试用 NON-EMPTY 列表填充角色列表
  4. 这里我设置的列表有值,但用户列表在角色列表属性中有一个空值,即使我在步骤 3 中设置了它

我不知道为什么会发生这种情况,我可以解决这个问题的唯一方法是克隆(使用来自 Apache commons.lang3 的 SerializationUtils)用户实体(参见步骤)和这项工作,但我不知道为什么。

  1. 从具有标准的 ejb 中的数据库中检索任何实体(例如用户)。
  2. 克隆检索到的实体并分配给新用户 clonedUser = SerializationUtils.clone(originalRetrivedUser);
  3. 然后尝试用非空列表填充角色列表给 clonedUser
  4. 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 中我想添加一个新列表,但无论我在列表中设置什么(实体(用户)的角色) 实体上的列表始终设置为空,就像实体中的列表以某种方式受到保护一样。

4

0 回答 0