Search code examples
jakarta-eeentity3-tier

Java-EE6: How to design @Entity passing between tiers?


I am currently working on a 3-tier application with Java-EE6 (GlassFish 3.1.2, MySQL Server 5.1 and Netbeans 7.1.1).

The project currently consists of 3 projects:

  • Enterprise Application / EJB's: facades to control entities on the database
  • Java Class-Library: @Entity annotated classes that represent the database model (this project is shared by the EE-app and the fat-clients in order to exchange the entity instances between tiers)
  • J2SE Fat-Client: JNDI lookup of server resources (remote access to EJB's)

For updating the client's GUIs when entities are created/modified/deleted I decided to make use of JMS by implementing a Topic where each client subscribes on start-up and a message-driven bean on the EJB-container serves as publisher.

Now I face the following big issue:

  • I attached life-cycle listeners (@PostUpdate, etc.) to the entity objects which then should publish the update messages to the subscribed clients. The entity classes reside in the class-lib project, whereas the publisher resides in the EE-app. The problem is, that the EE-app references the class-lib project, but not vice-versa (since cyclic project references are not allowed). Thus the life-cycle callback methods in the entity classes do not have a reference on the message-driven publisher bean in the EE-app.

This is a more design-related question & thus asking you if this is basically the right approach to design a 3-tier application with Java-EE6 ?

I want to avoid DTO/DAO if possible in order to keep complexity as low as possible and the application does not produce heavy network traffic.

Thanks for your advise in advance !


Solution

  • I solved the problem by passing the @Entity objects directly between all the layers. By activating static weaving (using eclipse-link as jpa provider) I was able to use lazy fetching for the heavy relations. In order to only fetch particular important relations from the client side, I use load groups to define the lazy relations that should be pre-fetched before serialized over the network which detaches the entity from the entity manager. vis-versa to send an entity to the server again, I just use EntityManager.merge(T) on the server side facade to put the entity back to managed state. This design works fine, even for very complex data hierarchies.