2

I'm implementing several DAO classes for a web project and for some reasons I have to use JDBC.

Now I'd like to return an entity like this:

public class Customer{

    // instead of int userId
    private User user;

    // instead of int activityId
    private Activity act;


    // ...
}

Using JPA user and activity would be loaded easily (and automatically specifying relations between entities).

But how, using JDBC? Is there a common way to achieve this? Should I load everiting in my CustomerDAO? IS it possible to implement lazy initialization for referenced entities?

My first idea was to implement in my UserDAO:

public void initUser(Customer customer);

and in my ActivityDAO:

public void initActivity(Customer customer);

to initialize variables in customer.

davioooh
  • 23,742
  • 39
  • 159
  • 250

2 Answers2

1

Active Record route

You could do this with AspectJ ITDs and essentially make your entities into Active Record like objects.

Basically you make an Aspect that advises class that implement an interface called "HasUser" and "HasActivity". Your interfaces HasUser and HasActivity will just define getters. You will then make Aspects that will weave in the actual implementation of getUser() and getActivity().

Your aspects will do the actual JDBC work. Although the learning curve on AspectJ is initially steep it will make your code far more elegant.

You can take a look at one of my answers on AspectJ ITD stackoverflow post.

You should also check out springs @Configurable which will autowire in your dependencies (such as your datasource or jdbc template) into non managed spring bean.

Of course the best example of to see this in action is Spring Roo. Just look at the AspectJ files it generates to get an idea (granted that roo uses JPA) of how you would use @Configurable (make sure to use the activerecord annotation).

DAO Route

If you really want to go the DAO route than you need to this:

public class Customer{

    // instead of int userId
    private Integer userId;

    // instead of int activityId
    private Integer activityId;

}

Because in the DAO pattern your entity objects are not supposed to have behavior. Your Services and/or DAO's will have to make transfer objects or which you could attach the lazy loading.

Community
  • 1
  • 1
Adam Gent
  • 47,843
  • 23
  • 153
  • 203
  • Is it a bad practice to return an entity with both `userId` and `user` reference? The DAO could initialize only id, (`user = null`), and then I could load the `user` instance (for example using some `UserDAO` method) when I actually need it... – davioooh Jun 15 '12 at 07:31
  • If you do that (which I have done that before also to save on transfer objects) you should mark the field as transient and another annotation to keep the User instance from being serialized. – Adam Gent Jun 15 '12 at 14:18
0

I'm not sure if there is any automated approach about this. Without ORM I usually define getters as singletons where my reference types are initialized to null by default, i.e. my fetching function would load primitives + Strings and will leave them as null. Once I need getUser(), my getter would see if this is null and if so, it would issue another select statement based on the ID of the customer.

Mario Peshev
  • 1,063
  • 8
  • 16
  • so you simply use another dao (`UserDAO`) to get the `user` by id if it is not yet initialized... correct? – davioooh Jun 14 '12 at 13:45
  • That's my problem with the DAO pattern. When you do something like that its not a DAO anymore. If you really want to follow the DAO pattern which separates behavior from state you need to have the entity only return the Ids of activity and user. – Adam Gent Jun 14 '12 at 14:42