What can I use instead of an entity bean?

248 views Asked by At

I would like to write a Java EE app for online learning. I'm thinking of this data representation:

@Entity
public class Course {
    private String name;
    private String[] instructors;
    private String[] teachingAssistants;
    private GradeBook gradeBook;

    // plenty of methods
}

@Entity
public class GradeBook {
    private GradeBookColumn[];

    // some methods
}

@Entity
public abstract class GradeBookColumn {
    private String name;
    private GradeBookColumnType type;

    // more methods
}

I would have quite a lot more than just that, but you get the point.

Now, in the EJB 3.2 spec, entity beans were removed and replaced with JPA entities. My question is how to cope with this tragic loss. There are three reasons why serialized JPA entities won't work for me:

  1. Performance. I will need to push the whole entity and all of its data through the net. There is quite a lot of that data, and it could take an unacceptably long time to get it all through.
  2. Security. If all the data in the entity is transferred over the net, then all of the data is accessible to the program that downloaded it. However, I want certain data to only be accessible if the user has sufficient permissions.
  3. Write Access. Once the copy of the data has been downloaded, the client should be able to make changes to it. However, if the changes are made, they won't be persisted to the server. Of course, I could always send the entity back to the server for persisting, but I would have to send all the data through an even slower upstream connection.

So, how do I design this system to meet these requirements without entity beans?

1

There are 1 answers

2
ewernli On

I'm not sure that the loss of entity beans is really tragic, but that's a matter of opinion :)

You seem that have a rich client on the desktop that connects to a remote server. You have two options:

A. You exchange "detached" object graphs between the client and server. The client receives some data, modifies it, then sends it back. The server then "merges" the data it receives. There is one transaction on the server when you load the data, and one when you merge back. To ensure you don't have conflict, you can version the data.

B. You use an "extended persistence context". In that case, the client receives entites that are still "attached" to a session. Modification to the entities on the client side are cached, and will be synchronized when you call a method on the server.

So, regarding the three design issue you face, here is my take on it:

  1. Performance. JPA and other modern ORM rely on laziness to avoid unnecessary data transfer: data is loaded on demand. You can choose which part of the graph can be loaded eagerly or lazily. With option A, you need to make sure that you load all the necessary data before you send them to the client; if the client attempts to access data that aren't loaded, it gets an exception since it's outside of a transaction. With option B, I guess the client can lazy load data anytime (it would be worth double checking that).

  2. Security. The JPA entities should be business objects, not data object. They can encapsulate business methods that do the necessary checks and preserve the desired invariants. In other words: security is not handled at the data level but at the business logic level. This applies for both options A and B.

  3. Write Access. With option A, you need to send back the whole graph and merge it. With option B, the framework should merge the changes that have been cached in a more optimized way.

Conclusions:

Extended persistence contexts have been designed for GUI applications with long units of work. They should in theory solve your problems. In practice, extended persistence contexts have their share of complexitiy though (e.g. needs to use stateful session beans).

The approach to detach and merge the graph is simpler, but raises the issues that you mention in terms of performance.

The third options is to go back to traditional data transfer object (DTO) to optimize performance. In that case the JPA entites stay exclusively on the server side. Instead of transferring JPA entites, you transfer only the subset of the data really needed into DTOs. The drawback is that DTOs will proliferate, and you will have boilerplate code to create DTOs from JPA entites, and update the JPA enties from DTOs.