Much easier solution: mark the fields you don't like to persist as @javax.persistence.Transient
I still wonder why you cannot set a new array into the entity. Imo this should work even for unmanaged entities. All which happens (at least if you use OpenJPA with enhancement and not with subclassing - which is mostly broken) is that the PCStateManagerImpl inside the entity gets replace by a DetachedStateManagerImpl which tracks the _dirty field updates. But I agree that it's much better to use DTOs whenever you use EJBs. I would suggest to only use not DTOs when you use either a producer for a @RequestScoped EntityManager (not container managed, so you need to use @Inject) or if you use a manually managed UserTransaction. In standard EJBs you will get the entitymanager-per-transaction pattern. Which means that any lazy loading field or relation you did not touch in your EJB will remain null forever. If you are aware of this restriction, then all is fine and you can use EJBs. Nowadays a DTO is nothing more than making sure that you touch all the fields an info you need in the other layer of your app, Btw, you should add a @Version private Integer optlock; to all your entities. Otherwise you will not have any locking in the database. And of course if you use DTOs then you will also need to set this info into your DTO and do a manual comparison in your EJBs to make sure the entitiy did not get changed in the meantime. LieGrue, strub >________________________________ > From: Romain Manni-Bucau <[email protected]> >To: [email protected] >Sent: Friday, 18 October 2013, 20:15 >Subject: Re: Entity cant be refreshed with new list values > > >Create a copy or use a dto > >Le 18 oct. 2013 20:06, "José Luis Cetina" <[email protected]> a écrit : > >> I only want to add some info to a retrieved object but i dont want to >> persist that new info >> >> >> 2013/10/18 José Luis Cetina <[email protected]> >> >> > But if use a transaction the new values will be committed and i want that >> > values as a read only >> > >> > >> > 2013/10/18 Romain Manni-Bucau <[email protected]> >> > >> >> Cause you arent managed...do the whole method in an ejb (with a >> >> transaction) >> >> Le 18 oct. 2013 19:30, "José Luis Cetina" <[email protected]> a >> écrit >> >> : >> >> >> >> > Ok, in the example i tried to set the list in the ejb, but if removed >> >> and >> >> > then put the list in the managed bean i get the same behavior >> >> > >> >> > >> >> > @Named >> >> > public class MyBean implements Serializable{ >> >> > >> >> > @EJB >> >> > private MyEJB ejb; >> >> > >> >> > public void anyMethod(){ >> >> > User user = ejb.getUserWithRoles(); >> >> > //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 >> >> > user.setRoles(roleList); >> >> > >> >> > user.getRoles(); //<---- HERE THE LIST IS ALWAYS NULL >> >> > } >> >> > >> >> > } >> >> > >> >> > >> >> > >> >> > >> >> > I dont want these roles get persisted i just want to modify my object, >> >> is >> >> > still the same even setting the value in the maged bean? >> >> > >> >> > >> >> > >> >> > 2013/10/18 Romain Manni-Bucau <[email protected]> >> >> > >> >> > > Hi >> >> > > >> >> > > Your entity is not managed so you cant do it. It is normal. >> >> > > Le 18 oct. 2013 19:09, "José Luis Cetina" <[email protected]> a >> >> > écrit : >> >> > > >> >> > > > I sent this mail to openJPA mailing list but i dont know if this >> >> could >> >> > be >> >> > > > something related to TomEE or just im doing something wrong. >> >> > > > >> >> > > > >> >> > > > I have a "strange" behavior, with list properties of any kind of >> >> > entity. >> >> > > > >> >> > > > When i try to set a non empty list to a retrieved entity that has >> a >> >> > list >> >> > > > value with null (because is not fetched) the entity doesnt >> "reflect" >> >> > the >> >> > > > new non-empty values that i set. >> >> > > > >> >> > > > Steps >> >> > > > 1. Retrieve any entity (ex. user) from database in an ejb with >> >> > criterias. >> >> > > > 2. The retrieved entity has a OneToMany attribute (roles) by >> >> default is >> >> > > > lazy thats why if i dont do a fetch (i dont) the list is null >> >> > > > 3. Then try to fill the role list with a NON-EMPTY list >> >> > > > 4. Here the list that i set has values but the user list has a >> null >> >> in >> >> > > the >> >> > > > roles list attribute even though i set it in the step 3 >> >> > > > >> >> > > > >> >> > > > I dont know why this is happening, the only way i could fix this >> is >> >> > > cloning >> >> > > > (using SerializationUtils from Apache commons.lang3) the user >> entity >> >> > (see >> >> > > > the steps) and with this work, but i dont know why. >> >> > > > >> >> > > > 1. Retrieve any entity (ex. user) from database in an ejb with >> >> > criterias. >> >> > > > 2. Clone retrieved entity and asig to new one User clonedUser = >> >> > > > SerializationUtils.clone(originalRetrivedUser); >> >> > > > 3. Then try to fill the role list with a NON-EMPTY list to the >> >> > clonedUser >> >> > > > 4. The list of clonedUser has the correct values >> >> > > > >> >> > > > >> >> > > > Why i need to clone? why i cannot set a list to the entity if is >> not >> >> > > > cloned? >> >> > > > >> >> > > > >> >> > > > Im using Apache TomEE 1.6.0-SNAPSHOT (with the openjpa version >> >> > embedded) >> >> > > > >> >> > > > >> >> > > > Scenario: >> >> > > > >> >> > > > ***** 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 CLASS **** >> >> > > > @Stateless >> >> > > > public class MyEJB{ >> >> > > > >> >> > > > @PersistenceContext(unitName ="ANY_NAME") >> >> > > > private EntityManager em; >> >> > > > >> >> > > > 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 MyEJB 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. >> >> > > > >> >> > > > } >> >> > > > >> >> > > > >> >> > > > } >> >> > > > >> >> > > > I know i can get the values fetching but im trying to not do it >> >> > > > >> >> > > >> >> > >> >> > >> >> > >> >> > -- >> >> > ------------------------------------------------------------------- >> >> > *SCJA. José Luis Cetina* >> >> > ------------------------------------------------------------------- >> >> > >> >> >> > >> > >> > >> > -- >> > ------------------------------------------------------------------- >> > *SCJA. José Luis Cetina* >> > ------------------------------------------------------------------- >> > >> >> >> >> -- >> ------------------------------------------------------------------- >> *SCJA. José Luis Cetina* >> ------------------------------------------------------------------- >> > >
