BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Article: Fetching strategy implementation in a J2EE application using AOP

Article: Fetching strategy implementation in a J2EE application using AOP

Bookmarks

A typical J2EE application using an O/R Mapping tool is faced with the task of fetching the required data using a minimal set of SQL queries, which is not always an easy task. By default the O/R Mapping tool loads data on demand unless otherwise instructed to. This behavior known as Lazy Loading ensures that dependents are only loaded as they are specifically requested and hence makes it possible to avoid unnecessary creation of objects. Because of the lazy loading, DB performance reduces when a large number of Select queries are executed, as all the required data for a business case are not fetched at once. This might prove a bottleneck for an application which needs to support a large number of requests.

In this article Manjunath R. Naganna introduces a strategy for overriding the default fetching pattern in the Repository/DAO class with a different fetching pattern based on the specific use case as defined with Aspect Oriented Programming. Aspect helps in deciding which fetching strategy needs to be used in a particular business use case. In this case, fetching strategy decision management is kept outside the lower level service or repository layer.

 Read: Fetching strategy implementation in a J2EE application using AOP

The logic of deciding which query needs to be executed is a crosscutting concern that is retained in an Aspect. Aspect decides which fetching strategy needs to be injected in the repository before the service layer executes the API on the repository based on business use case. By this we can use the same service and repository layer APIs to satisfy different business use case requirements.

Rate this Article

Adoption
Style

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Community comments

  • So what for is repository?

    by Sławomir Sobótka,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    In this approach the repository is just for executing strategy. For me it's not enough justification for existence of repository class:/
    There is also additional code that checks list details (size) but of course this clumsy design (returning from strategy list instead of object) is just to mask odd idea i guess.

  • Sounded good...

    by Branden Root,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    The first part of the article sounded good - I can attest to having a repository's code size explode as more and more specific use case queries are added. But it seemed like the article ran out of steam when it came to the execution of the AOP strategy. Maybe flush it out with more concrete examples?

  • Is AOP used inappropriately here?

    by Wei Wei,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    It is a brilliant idea to inject different fetching strategies during the run time by taking advantages of AOP. But to me, aspects are not use cases specific. My understanding is that they are meant to address more general concerns in the application, e.g. logging.

  • Refactored Bloat

    by bruce b,

    Your message is awaiting moderation. Thank you for participating in the discussion.


    • Code bloat - the only bloat is compared to the naive eager or lazy approaches. The use case specific code still exists in the AOP solution.

    • Maintenance nightmare -Splitting the implementation of ORM fetching between inline code and aspect driven code is the real maintenance nightmare. The concerns implemented with AOP should be orthogonal to the use case driven service/repository code. This isn't the case here.

    • Code duplication - The same duplication occurs in the sibling FetchingStrategy impl classes

    • Missing the role interface

      by Udi Dahan,

      Your message is awaiting moderation. Thank you for participating in the discussion.

      I did something like this two years ago in .NET and wrote it up here:

      www.udidahan.com/2007/04/23/fetching-strategy-d...

      A year later is was rolled into the open source Rhino suite Ayende Rahien is leading as written about here:

      ayende.com/Blog/archive/2008/03/27/Adaptive-Dom...

      The main thing necessary for this to work is for there to be use-case-specific role interfaces for the domain which the service layer uses, rather than using the specific domain classes themselves.

      This allows us to hook the fetching strategy on the use case, rather than on any implementation detail.

      Hope that helps.

    • Re: Is AOP used inappropriately here?

      by Bill Poitras,

      Your message is awaiting moderation. Thank you for participating in the discussion.

      Although AOP has traditionally used to address infrastructure cross cutting concerns like logging and transactions, its meant to address all cross-cutting concerns. I saw an AOP talk that gave a good example of using AOP for application functionality. I think in this case it was exception mapping between a service and its caller.

    • Re: Missing the role interface

      by Manjunath Naganna,

      Your message is awaiting moderation. Thank you for participating in the discussion.

      Hi Udi,

      I have a question here regarding how do you hook-up the use-case specific role interface to the service layer at run-time?

      As you see currently from my example code i am hooking it up using aspect. Can you give me a code snippet that explains it?

      -Manjunath

    • Re: Refactored Bloat

      by Manjunath Naganna,

      Your message is awaiting moderation. Thank you for participating in the discussion.

      Code Bloat-
      If we start writing use case specific fetching api's we will have lot more code bloating then here since here aspect is handling of injecting the actual query that needs to be executed based on use case.

      And if there is any common processing needs to be done after fetching domain object at repository level then this code needs to be present at all the use case specific fetching api's.

      Maintenance Nightmare - Regarding this how come this becomes more maintenance nightmare than having multiple fetching use case specific api's at repository and lowel level service api's. You can check my sample code and evaluate it by adding new use case specific api needs changes at Business level service interface and aspect than changes to the lower level layers.

      Code duplication - Here i don't see any code duplication since each FetchingStratergyImpl will have fine tuned queries specific to use case.

      -Manjunath

    • Re: Missing the role interface

      by Udi Dahan,

      Your message is awaiting moderation. Thank you for participating in the discussion.

      The service layer specifically asks for the role interface. Rather than:

      Employee e = ORM.Get<Employeee>(id);
      e.Fire();

      It calls:

      IAmGoingToFireEmployee e = ORM.Get<IAmGoingToFireEmployee>(id);
      e.Fire();

      Then the ORM internally uses a service locator to find an implementation of IFetchingStrategy<IAmGoingToFireEmployee>. If found, the ORM uses it to find out which other objects to eagerly load.

      Does that make sense?

    • Re: Missing the role interface

      by Manjunath Naganna,

      Your message is awaiting moderation. Thank you for participating in the discussion.

      Hi Udi,

      I still have a bit of confusion regarding missing role interface. I have gone through your talk Making Roles Explicit on InfoQ where you mention about role interface.

      But as part of my example code i have Business Layer above Service layer to retrieve different set information of information to be displayed based on use case how do i notify my repository that i need to use particular fetching strategy. How do i pass this information from lower level service api's to repository.

      For ex:-

      Business Layer has a service which needs to run some Specification(Business Rule validation) on the retrieved entity

      <Pseudo-Code>

      BusinessLayer

      void makeHimAValuableEmployee(int employeeId) {
      Employee emp = lowerLevelServiceLayer.findEmplyee(employeeId);
      ISpecification.isValuableEmployee(emp);
      //Some more operations on domain object.
      }

      <Pseudo-Code>

      Can you just go through my source code. Can your provide me a pseudo-code how would you have achieved it by making role explicit?

      -Manjunath

      </pseudo-code></pseudo-code>

    • Re: Missing the role interface

      by Udi Dahan,

      Your message is awaiting moderation. Thank you for participating in the discussion.

      Manjunath,

      Apparently there are more architectural differences in our approaches than was originally visible. In your case, your business layer would call:

      lowerLevelServiceLayer.MakeHimAValuableEmployee(employeeId);

      And the lower level service would call:

      IWantToMakeEmployeeValuable e = repository.Get<IWantToMakeEmployeeValuable>(employeeId);
      e.MakeValuable();

      Is that any clearer?

    • Re: Refactored Bloat

      by bruce b,

      Your message is awaiting moderation. Thank you for participating in the discussion.

      Sorry for the delayed response, just got back from vacation. Downloaded the code and see that that each fetching strategy is a one liner returning the HQL for a use case. So for each entity that may have multiple fetching options, you need to define an interface, implement the interface for each fetching option, then you have to define pointcuts to intercept calls to determine the correct fetching option. That's a lot of boilerplate to support a simple lookup algorithm for a database query.

      As I'm writing this, I realize it's not a fetching strategy, so much as a fetching option. Options can usually be managed using low-tech means such as method parameters. The repository method could accept a parameter passed by the service method indicating which fetch mode to use when fetching an entity and its children. At this point mapping the option parameter to the HQL statement is a straightforward lookup that can be implemented in numerous ways. If a new use case arises requiring a new fetch mode, all you have to do is add a new name => HQL mapping to whatever lookup mechanism is in use.

      If a need arises to execute common code after a fetch, then introducing AOP might be warranted, but only if it leads to less inline code boilerplate and duplication.

    Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

    Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

    BT