Announcement Announcement Module
Collapse
No announcement yet.
Database query vs Set iteration Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Database query vs Set iteration

    Hi All,

    Assume a model with a user who has lots of subscriptions. The user class hence has a Set called subscriptions which holds all the users subscriptions and a hibernate mapping file exists for both user and subscription describing the association.

    Great, I can load a user and access all his subscriptions!

    The question I have is what if I only wanted to have all the active subscriptions?
    A business rule exists which defines what an active subscription is, in this case its simply a property of type boolean in the subscription object.

    Back to the question. Would I create a method in the User object which simply iterates over the Set of subscriptions and returns a subset containing only active subscriptions OR would I do create a hibernate query to return the active subscriptions for the user?

    I am thinking that if initally I eagerly fetch the subscriptions for the user as an outer join, then iterating through the subscriptions would avoid me an additional trip to the database.

    Does anyone have any recommendations here or pros and cons for each approach?

    Kind thanks,
    Serge

  • #2
    I would avoid eager fetching, I don't think you need to solve this by just getting everything at once. I would look at HQL, filters and formula based mapping. I have found filters to be very useful in the past, they also allow quite a nice abstraction if your business requirements change in the future.

    http://www.hibernate.org/hib_docs/v3...tate-filtering
    http://www.hibernate.org/hib_docs/v3...tion-manytoone
    http://www.hibernate.org/hib_docs/v3...mance-fetching

    Comment


    • #3
      Hey thanks,

      I totally forgot about filters.... I will look into this some more.

      Thanks again for those pointer.

      Serge

      Comment


      • #4
        I have wondered this same thing. Disregarding performance, I prefer the iterate-over-the-set-and-return-subset method. I think one of the benefits of Hibernate is how it promotes an object-oriented style, and the iterate method seems like a good example of that.

        However, it may not make sense from a performance point of view. What if there are very few active subscriptions; eager fetching might save trips to the database, but Hibernate still has to instantiate more classes and pass back more data that you then need to iterate over on the Java-side; it would certainly be faster to issue a query on the database-side.

        However, most likely you have a DAO method to retrieve a User. To get all of the subscriptions, a getSubscriptions() call will work. But to get the active subscriptions, what are the alternatives? Embed a DAO in the User object (which some people seem passionately against) to achieve this? If I issue a query to get all Users who signed up one year ago, I then want to simply call getActiveSubscriptions() on each User; I don't want to have to use some other DAO to get the active ones.

        I guess my question is this: can I define methods on my persistent class that do not correspond to persistent properties? For instance, can you have an "activeSubscriptions" property/method that defines the filtering criteria? In that case, you could arbitrarily add methods on persistent domain objects corresponding to various filtering on persistent sets. I think this would be ideal; the actual query would be filtered on the database-side, but it would be handled transparently by Hibernate so you can simply query for a User and then invoke any methods you want (without embedding a DAO in the User or using a different DAO and passing the User as an argument).

        Does Hibernate support this?

        Comment


        • #5
          I would love to find a nice way of doing this. You could embed your Dao, but as you said there are two camps on this one. If you want to leave the Dao out of this you can provide a formula on a mapping in Hibernate. So you define how the relationship contents are retrieved. This might work for you. One tiny problem with this, is the reference manual isn't very helpful on this matter.

          http://www.hibernate.org/hib_docs/v3...tion-manytoone

          Comment


          • #6
            Hi,

            One tiny problem with this, is the reference manual isn't very helpful on this matter
            No its not, having just spent some time looking for information...

            The other issue I still have with this is that we are now tying ourselves to hibernate which may or may not be a problem for some.

            But if I were to use a filter or formula, am I really encapsulating the business logic of what an active subscription is in the domain model??

            Serge
            Last edited by ssozonoff; Dec 4th, 2006, 04:19 AM.

            Comment


            • #7
              Originally posted by ssozonoff View Post
              The other issue I still have with this is that we are now tying ourselves to hibernate which may or may not be a problem for some.

              But if I were to use a filter or formula, am I really encapsulating the buisness logic of what an active subscription is in the domain model??
              I understand what you getting at but at some level you there is always going to be a dependency. If you don't like filters or formulas, the other option is just to ensure that fetching of the subscriptions is efficient generally. I would still stay clear of eager fetching by default unless necessary. The simple fact is though, this in itself is a dependency of Hibernate.
              http://www.hibernate.org/hib_docs/v3...mance-fetching

              If you embed the Dao in the model it really doesn't matter which option you choose as its hidden.
              Last edited by karldmoore; Dec 3rd, 2006, 11:51 AM.

              Comment


              • #8
                Originally posted by Arthur Loder View Post
                However, most likely you have a DAO method to retrieve a User. To get all of the subscriptions, a getSubscriptions() call will work. But to get the active subscriptions, what are the alternatives? Embed a DAO in the User object (which some people seem passionately against) to achieve this? If I issue a query to get all Users who signed up one year ago, I then want to simply call getActiveSubscriptions() on each User; I don't want to have to use some other DAO to get the active ones.

                I guess my question is this: can I define methods on my persistent class that do not correspond to persistent properties? For instance, can you have an "activeSubscriptions" property/method that defines the filtering criteria? In that case, you could arbitrarily add methods on persistent domain objects corresponding to various filtering on persistent sets. I think this would be ideal; the actual query would be filtered on the database-side, but it would be handled transparently by Hibernate so you can simply query for a User and then invoke any methods you want (without embedding a DAO in the User or using a different DAO and passing the User as an argument).

                Does Hibernate support this?
                My 2 cents - I have always thought cases like this are perfect usage scenarios for injecting DAOs into DOs. As we all know, an "activeSubscriptions" can be easily created quite naturally, based on merely the Java Bean Spec instead of a particularly powerful ORM tool, by exposing a getActiveSubscriptions() on the User class. On the other hand, it seems (to me) rather inconsistent to have User.getSubscriptions() and UserService.getActiveSubscriptions(User).

                Comment


                • #9
                  Bringing other subscription related methods into this discussion, the logic for subscribe and unsubscribe are fairly complex and include for example the maintenance of jobs in Quartz. So it might be nice to actually put this into its own class. SubscriptionManager or SubscriptionHelper or something.
                  Would one want to inject this into the User entity and make the unsubscribe and subscribe methods public and available from the User class and hence all subscription functionaliy would be made available through the User class.

                  Alernatively, all subscription methods including activeSubscriptions etc.. could go into a SubscriptionManager class the the User class would not house this logic at all...in which case.... things would be taking the direction of an anemic domain model?

                  So either way works.... Is it now just a matter of personal preference or Anemic vs Rich domain model?

                  Comment


                  • #10
                    I've read quite a few debates on this whole thing and I'm really not decided. Lots of the time, I think you just need to do what *you* think makes sense. Your the closest to the code so you can see what is working and what isn't. If you start to go down a path that doesn't feel right, you can just refactor it. Anemic vs Rich, Good vs Evil, I'll take common sense.

                    Comment

                    Working...
                    X