What is the preferred design pattern for combining JPA, EJB, and JSF beans?

This is a template template. Here is the scenario: I am using EJB3.0 with JPA. For example, let's say I have a user who can belong to groups. So, in my user entity, I have a getGroups () method that lazily selects groups. And I have UserDao, which is a non-bean session that has a method
User getUser (int uid)

Now, in my JSF bean support, I insert the UserDao remote interface and call getUser on it to get the User bean. But I can not access user.getGroups because it is a separate object. So I can think of three approaches here:

  • In my dao method, I willingly take groups so that they are also available in the remote user entity. But the problem with this is that the Group itself could be lazy to get an attitude, and I also have to look forward to it, and they may have a more lazy attitude, etc. Therefore, I will eventually send a heavy object, most of the properties of which I will not need.
  • I send the User as it is, and rely on my client not to call getGroups on it. I can provide a separate method in userdao, which is a List of <Integer> getGroupsIds (int userId)
    And I have a GroupDao that has similar getGroup (int groupId) methods and other methods for getting the id of lazy relationships.

  • The third option is to not send these JPA entities at all and create other POJOs such as UserInfo, GroupInfo, etc. that simply contain the basic attributes of each object and send them through. And I can have methods in the DAO to get these entities for different relationships, for example:
    List <GROUPINFO> getGroupsForUser (int uid)
    List <UserInfo> getUsersInGroup (int gid)

So which one is preferred. Or is there some other template that people use here?

+4
source share
3 answers

There are also 4th and 5th options :-)

4) Turn on the "inflation rate" parameter for the corresponding API calls, for example. getUser (id, inflation). Thus, you delegate responsibility for the selection of which parts of the object sent by wire will be available to the client who will use this object. You can say that the level of intrusion is as coarse or fine as you want. A typical example would be something like BASIC (only the immediate properties are filled), ASSOCIATIONS (basic + direct collections / associations), FULL (the whole hierarchy - all related objects).

5) You can write your own proxy server that supports lazy initialization without interruption. This approach is only possible if related objects (or properties) that are lazy can potentially be huge, but are rarely used (by clients).

Then, of course, there is also Sim as a scaffman mentioned :-)

+1
source

I have a third version of my already completed project. This is not good. Each time you have to change 2-3 classes instead of one. Fields are duplicated and so on. Not an option.

If you really do not need all the information that the user object can look forward to, than go with the second option.

If it turns out that in fact all the time you need all the user information. And no one else uses your User object through a remote service, and then use your User object - go with the first one.

Another solution is out there somewhere. I need a better one.

0
source

Why is the user instance disabled? If you really use JPA, you can use a live instance. That way, when getGroups() is called, user groups load lazily.

0
source

All Articles