tomee-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mark Struberg <strub...@yahoo.de>
Subject Re: Entity cant be refreshed with new list values
Date Sat, 19 Oct 2013 07:16:55 GMT
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 <rmannibucau@gmail.com>
>To: users@tomee.apache.org 
>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" <maxtorzito@gmail.com> 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 <maxtorzito@gmail.com>
>>
>> > 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 <rmannibucau@gmail.com>
>> >
>> >> Cause you arent managed...do the whole method in an ejb (with a
>> >> transaction)
>> >> Le 18 oct. 2013 19:30, "José Luis Cetina" <maxtorzito@gmail.com>
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 <rmannibucau@gmail.com>
>> >> >
>> >> > > Hi
>> >> > >
>> >> > > Your entity is not managed so you cant do it. It is normal.
>> >> > > Le 18 oct. 2013 19:09, "José Luis Cetina" <maxtorzito@gmail.com>
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*
>> -------------------------------------------------------------------
>>
>
>
Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message