users@glassfish.java.net

Re: Application clients - Local EntityManager vs remote facades with detached entities.

From: Witold Szczerba <pljosh.mail_at_gmail.com>
Date: Sat, 7 Jul 2007 21:59:36 +0200

In my application, the first plan was to use something like 'strategy
2' but for each entity there was separate session bean. It was
implementing some generic CRUD interface, similar to the one of yours,
but with generics. The reason of splitting CRUD implementation was the
ability to add some specific logic like security constraints.
Moreover, each session bean had to implement other functionality
regarding given entity.
The plan was working fine until we found few problems. First one was
terrible performance. Some @Entity objects were too big, I mean they
were connected to other entities, other entities were connected to
another... and so on. When client was asking for one entity to show it
on a form, too much data was about to travel across the Internet.
There was something worse - the way we were thinking about changing
entities was coupled with our needs regarding GUI. That was
unacceptable to me, so I decided to introduce DAO. Now, each session
bean has a pair of methods, for example:

public PersonDTO entity2dao(Person entity) {...}
public void dao2entity(Person entity, PersonDTO dto) {...}

Now, we can modify DTO, so it can fit client requirements much better,
for example, when we show some person on a form, we want DTO to
contain all its properties. But we do not need to download all the
properties of all his/her companies, loans, documents and so on. We
can, for example we can show on the form only the number of his
companies or loans, and when user clicks on the button, we can
download LoanDTO. Client knows nothing about Person, Loan, Proposal,
he asks for PersonDTO, LoanDTO, proposalDTO instead. That gives you
much more power and flexibility. The price you have to pay is extra
entity2dto and dto2entity methods, but as far as I know, there is
nothing you can do. Using detached entities downloaded using Internet
can work only for a tutorial presentation, it will not work for
anything bigger.



2007/7/7, Ryan J <ryan.j_at_vacode.com>:
> Hi,
>
> Please don't hesitate to point out if any of my logic is flawed :-)
>
> I'd like to hear some thoughts about the best way to deal with entities and
> persistence from an application client. As far as I can tell, there are two
> possible strategies:
>
> Strategy 1 - Local EntityManager
>
> I can define a PersistenceUnit and have the ACC inject an EntityManagerFactory
> by adding the following to my main application class:
>
> > @PersistenceUnit(name = "jptech_punit")
> > private static EntityManagerFactory emf;
>
> I can then create an EntityManager using:
>
> > em = emf.createEntityManager();
>
> I can then use that EntityManager for all persistence related operations
> relating to my Entity classes.
>
>
> Strategy 2 - Remote facades with detached entities
>
> I can create a remote interface that acts as a facade for persistence operations:
>
> > @Remote
> > public interface DataAccessRemote {
> > public void create(Object entity);
> > public Object retrieve(Class classType, int uniqueId);
> > public boolean update(Object entity);
> > public boolean delete(Object entity);
> > }
>
> and a matching implementation in my EJB module:
>
> > @Stateless(name = "ejb/DataAccessBean")
> > public class DataAccessBean implements DataAccessRemote {
> > @PersistenceContext
> > private EntityManager em;
> >
> > // implementation here
> > }
>
> Then in my application client, I obtain a reference to the the DataAccessBean
> (facade):
>
> > INITIAL_CONTEXT = new InitialContext();
> > Object ref = INITIAL_CONTEXT.lookup("java:comp/env/ejb/DataAccessBean");
> > dataAccessBean = (DataAccessBean) PortableRemoteObject.narrow(ref, DataAccessRemote.class);
>
> and use the facade to execute my persistence operations. This method involves
> moving detached entities back and forth across the network.
>
> I can make a few observations about each strategy:
>
> Strategy 1
> It works quite well. The ACC deals with a lot of the (configuration)
> complexity. All of the @Id fields in my @Entity beans get updated
> automatically, regardless of cascading. Determining if an Entity is new is a
> simple call to EntityManager.contains(Object entity).
>
> However, since the EntityManager connects to and interacts with the database
> directly, there's the potential to end up with several EntityManager[s]; one for
> each application client and one (or more?) on the server.
>
> Assume there is a web service querying data in a manner similar to what I
> described in 'Strategy 2'. Entities managed by the server side EntityManager
> could become outdated as application clients update the database.
>
> Strategy 2
> This also works ok, with one exception. When the application client is dealing
> with a (newly created) detached entity and persists that entity via the
> 'create(Object entity)' method of the DataAccessRemote interface, the detached
> copy of the entity needs to have its @Id field updated manually. It's also
> necessary to update the @Id field of any child entities that have a CascadeType
> of PERSIST or ALL.
>
> Once you start dealing with trying to keep all of the entity @Id fields updated,
> this strategy becomes a lot more hassle than the first, but has the advantage of
> ensuring that entities managed by the server side EntityManager are no outdated.
>
> I also don't know how well this strategy would handle entities with a
> CascadeType of ALL.
>
> Assume I had an Author (myAuthor) entity that contained a Collection of Book
> entites using CascadeType.ALL. What would happen if the Author contained 1000
> Book entities, I updated a 'name' field for the Author and called the
> update(myAuthor) method of my DataAccessRemote interface? Would the Author plus
> all 1000 Book entites be serialized and moved across the network so the server
> side EntityManager can determine what needs to be updated?
>
>
> I hope I've described things well enough to make it understandable. I don't
> really have a question, rather I'm interested in hearing how others have been
> dealing with entities and persistence in application clients. I've done a ton
> of reading, but can't really find a 'definitive' way of writing an EE
> application (rich) client.
>
> Any feedback that specifically related to (optimistic) locking or security would
> really interest me.
>
> Thanks in advance for your time,
> Ryan
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_glassfish.dev.java.net
> For additional commands, e-mail: users-help_at_glassfish.dev.java.net
>
>