Announcement Announcement Module
Collapse
No announcement yet.
[CLEAN DESIGN] Quest for best Architecture for a Rich-Client / Server application Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • [CLEAN DESIGN] Quest for best Architecture for a Rich-Client / Server application

    I'm currently helping with the design of the architecture of a new client-server application the company I'm working in is about to develop, and I would like to have the Spring Community comment my ideas, and give me better ideas maybe, regarding how could I tweak or overhaul the whole design.

    To get it short: Client-server rich client web-oriented application, for managing items with an integrated community for information sharing.

    Swing Rich Client & Spring/Hibernate Server.

    Ideally the user should be able to collect stuff and organize his collections through the client (both online and offline), and have everything submitted automatically and trasparently to the server whenever going 'online', as to be able to find similar items, users with similar tastes regarding the items, and/or discuss the items with the community (votes, reviews, comments, etc...).

    I've already modeled the domain objects as simple POJOs with very little logic inside (I prefer to externalize the logic into services, and leave the domain objects as simple POJOs as possible).

    Since ideally the client should be able to work offline for potentially long periods, and scale to possibly a large item database (100.000+ items), I was planning to hold an in-memory database (hsqldb, and store it on disk on close) on the client, and transfer the domain objects from the server, to the client, saving them in a local database, and planning to do a 'synchronization' every time the client goes online (by submitting the modified data, and downloading the new data from the server).

    Possible architecture:

    SERVER - DAO Layer (Spring-Hibernate)
    For persistence and data access. Modelled after the domain object, with pinpointed methods to load/search/store/update instances of them. No validation is done here, except the validation esplicitly needed for data consistency (through hibernate/db constraint, or logic constraints).

    SERVER - Service Layer (exposed through httpInvoker remoting)
    Exposing to the clients all the needed services to interact with the server and the community. This layer should be responsible of checking the user authorization, validating the clients requests and the involved data, and handle the logic for realizing the needed services, by accessing the DAO layer for data access.

    CLIENT - Controller Layer (client backend handling the data synchronization and validation)
    Client logic for handling the communication with the server. Should implement the needed services, to give the presentation layer the data needed for user interaction, should do a first validation of data prior to forward data to the server, and should implement the possible offline operations, and the synchronizing with the server when needed.

    CLIENT - Presentation Layer (GUI)
    Client logic for retrieving the needed info through the controller layer, render them, and allow the user to modify and add the needed items, and do everything he should be able to do with the application, both offline and online.

    This is a draft of the four layers I was planning to divide the architecture in, but ANY advice regarding a better organization is welcome. Remember though, that while I'm not planning to make this a web application (it's stricly client-server, with a rich swing client), I would love anyway to maintain the flexibility to be able to add a web-client tomorrow, if the service focus will shift from the desktop offline work, to the full online web service.

    Now, onto my two biggest doubts/unresolved problems:

    Domain Object Relationships DB Mappings
    My DOM is made up of several objects which share the same relationships. For example there are several domain objects which can be commented, voted, reviewed, tagged, etc... Since the best way to do this in java is surely to have proper interfaces (Votable, Commentable, Reviewable) implemented in the needed POJOs, I'm now in the process of deciding how could I map this into the database.

    Ideally, I would love these associations to be bidirectionals (for example, I would love to do review.getItem() to get the reviewed item, and to do item.getReview() to get the reviews associated with that item), but since they are polimorphic (several domain objects can be reviewed: User, Item, Collection... and they are too different from each other to use a base class for them, and moreover they would need to extend SEVERAL classes, as they have to be commentable, reviewable, votable,... hence the interfaces.), I'm very doubtful on how to do this efficiently. ANy suggestion or proposed solution?


    Client-Server synchronization workflow
    Given the prerequisite (offline work), should I use a full-fledged database as I said, and persist all the offline modification to the local client database, and synchronize it the server when needed, or just simply cache the retrieved data and save the users operations for submitting later to the server, when going online?

    In the case of the database, I don't know exactly how can I handle the synchronization without impacting too much on the database or the network (I don't want to re-read and confront EACH involved ITEM). Maybe I should use some kind of 'tagging' to recognize which items have been modified, both on the server nad the client, since the last synchronization, like a timestamp.

    In the case of caching, It would be a nightmare to deal with the overriding cached data. If for example, I add an item to a collection, I would love to show this even if I've not yet synchronized with the server, but this would mean introducing some kind of logic to handle the 'data' not yet submitted to the server, and have these over-ride the DOM data.

    Which workflow is easier to deal with? Which is more performant, if implemented correctly? Which one would you suggest, given the prerequisite?n Is there a third better one I've missed?


    ***

    Any help is GREATLY appreciated, and will earn you a couple of beers offered by myself the first time you happen to pass from Milan, Italy ^_^
    Last edited by omero; Apr 27th, 2006, 03:53 AM.

  • #2
    Originally posted by omero
    Ideally, I would love these associations to be bidirectionals (for example, I would love to do review.getItem() to get the reviewed item, and to do item.getReview() to get the reviews associated with that item), but since they are polimorphic (several domain objects can be reviewed: User, Item, Collection... and they are too different from each other to use a base class for them, and moreover they would need to extend SEVERAL classes, as they have to be commentable, reviewable, votable,... hence the interfaces.), I'm very doubtful on how to do this efficiently. ANy suggestion or proposed solution?
    I would try to have as few bidirectional associations as possible in your object model. Experience tells me that bidirectional associations tend to cause headaches sooner or later. Besides that, unidirectionals allow for a better modularization of your object model.

    For example, it makes sense for a review object to refer to the reviewed items. However, I would find it unnecessary that the item itself knows about being reviewed. You would also be more flexible, so that you could later decide review items that weren't (conceptually) reviewable before, without introducing an interface to the item's type.

    With the proper foreign keys is place, you can easily define appropriate queries to return a review (if available) for an item.

    Originally posted by omero
    In the case of the database, I don't know exactly how can I handle the synchronization without impacting too much on the database or the network (I don't want to re-read and confront EACH involved ITEM). Maybe I should use some kind of 'tagging' to recognize which items have been modified, both on the server nad the client, since the last synchronization, like a timestamp.
    I would provide each item representation (in client and server database) with a modification timestamp. Besides that, the client should memorize (in its database) the timestamp of the last synchronization.
    With that information any modified objects since the last synchronization are easily determined and can be synchronized.

    Regards,
    Andreas

    Comment


    • #3
      Originally posted by Andreas Senft
      I would try to have as few bidirectional associations as possible in your object model. Experience tells me that bidirectional associations tend to cause headaches sooner or later. Besides that, unidirectionals allow for a better modularization of your object model.
      This is very true, and in fact my first draft of the DOM included classes with only uni-directional association (example: review-->item, comment-->item, vote-->comment, etc...).

      I tried to model things differently to improve the OO design of the DOM, since having the reviews/comments/items as java properties of the involved object, is more OO and make the DOM more self-contained and less dependent on the service objects (since without these, I'll have to explicitly ask the service object for the reviews of a particular item, instead of doing a simple getReviews() on the item).

      Also, reading the Hibernate Best Practices in the official documentation (http://www.hibernate.org/hib_docs/v3...ractices.html), I read this:

      Originally posted by Hibernate Best Practices

      Prefer bidirectional associations.

      Unidirectional associations are more difficult to query. In a large application, almost all associations must be navigable in both directions in queries.
      This is also what brought me to think that maybe bidirectional associations weren't that evil thing I was thinking, but could be used safely even in a large, complex application as mine hopefully will be.

      So, which choice is best, in this case? Leave bidirectional association to improve OO and isolate DOM better from the service objects, or prefer unidirectional associations to simplify mapping, and handle those connections through service objects?

      Using unidirectional associations will allow me to transfer the whole domain objects detached and fully initialized without having to worry about what it's initialized and what not (since using bidirectional associations instead, transferring the whole graph of the object and associated object would be unfeasible and overkill, since most of the time those associations won't be used), and without having to recur to the "Open Session in View" pattern, which couples the presentation logic with hibernate (loosely and indirectly, but still does somehow, and I would prefer to avoid this if possible).

      BUT, this isn't the REAL problem, but it's only a side one, the real problem is another one IMHO (I explain it a couple of lines below)

      Originally posted by Andreas Senft
      For example, it makes sense for a review object to refer to the reviewed items. However, I would find it unnecessary that the item itself knows about being reviewed. You would also be more flexible, so that you could later decide review items that weren't (conceptually) reviewable before, without introducing an interface to the item's type.

      With the proper foreign keys is place, you can easily define appropriate queries to return a review (if available) for an item.
      Ok, I understand and are now more willing to convert the bi-directional association into single-ended associations, but my main problem still remains, even with uni-directional associatons.

      THe problem that remains is that, the association is in fact polymorphic.

      Not only items can be reviewed, but also collections, and user themselves, in my DOM. So how could I handle the mapping between review and the reviewed thing, which can vary? The same problem applies to Comments, Tags, Vote and several other objects.

      They all regard an 'object' but this object may vary, and be a User, an Item, a Collection, a Comment, etc... in fact I have to map multiple, interwined hierarchies, and I don't know which is the best approach.

      This is why I decided to use an interface 'Reviewable' to represent the reviewable thing, because of this mapping problem (which gives me the added benefit of having the needed methods inside a proper interface, if I would like to incapsulate logic inside the DOM, or have bidirectional associations, like getReviews() on this Reviewable interface).

      Originally posted by Andreas Senft
      I would provide each item representation (in client and server database) with a modification timestamp. Besides that, the client should memorize (in its database) the timestamp of the last synchronization.
      With that information any modified objects since the last synchronization are easily determined and can be synchronized.
      This is as I inteded to do things, since it seems the most logic thing to do. Have a database at the client side, and synchronize it with the remote server, using a modification timestamp to pinpoint the objects that I need to synchronize, in order to minimize net transfers and database access (both at client and server side).

      Good to know it sounds good design, and that it should work, if implemented correctly

      Originally posted by Andreas Senft
      Regards,
      Andreas
      You have been very helpful, thanks Andreas =)
      Last edited by omero; Apr 27th, 2006, 05:47 AM.

      Comment


      • #4
        Originally posted by omero
        This is also what brought me to think that maybe bidirectional associations weren't that evil thing I was thinking, but could be used safely even in a large, complex application as mine hopefully will be.

        So, which choice is best, in this case? Leave bidirectional association to improve OO and isolate DOM better from the service objects, or prefer unidirectional associations to simplify mapping, and handle those connections through service objects?
        Well, bidirectional associations are not _evil_. I just made the experience that things get more complicated with them. One thing is, as you mention, that the object graph could become unwieldy. Ok, things might be amended by lazy-loading, but I normally like to split a larger object model into categorized layers with a dependency hierarchy, if possible. Using bidirectional associations everywhere yields one big bag of interdependent classes.
        Another thing is, that you have to keep bidirectional associations in sync somehow. Adding an address to a person should also add the person to the address (and vice versa).

        That said, the type of an association should be determined by the use cases you have. If your (important) use cases require to traverse a specific association in both directions, then it would not make sense to model it unidirectional. If, however, such a requirement doesn't exist, I would not make an association bidirectional "just in case".
        As usual, there is no single recipe on how to do things. :-/


        Originally posted by omero
        THe problem that remains is that, the association is in fact polymorphic.

        Not only items can be reviewed, but also collections, and user themselves, in my DOM. So how could I handle the mapping between review and the reviewed thing, which can vary? The same problem applies to Comments, Tags, Vote and several other objects.

        They all regard an 'object' but this object may vary, and be a User, an Item, a Collection, a Comment, etc... in fact I have to map multiple, interwined hierarchies, and I don't know which is the best approach.
        This one is indeed not easy. In any case I would try to get rid of "collections". It should be sufficient to be able to have multiple objects in a single review.
        Besides that, I guess that each object could participate in more than one review. So you end up having n-to-m relations. So you could have intermediate mapping tables between review and each type or one big intermediate table that stores also type information which allows resolving the correct associated instance.
        From a maintenance point of view I would choose the one-table approach, though it might be more complicated to set up the appropriate queries.

        Hope it helps,
        Andreas

        Comment


        • #5
          Originally posted by Andreas Senft
          Well, bidirectional associations are not _evil_. I just made the experience that things get more complicated with them. One thing is, as you mention, that the object graph could become unwieldy. Ok, things might be amended by lazy-loading, but I normally like to split a larger object model into categorized layers with a dependency hierarchy, if possible. Using bidirectional associations everywhere yields one big bag of interdependent classes.
          Another thing is, that you have to keep bidirectional associations in sync somehow. Adding an address to a person should also add the person to the address (and vice versa).
          True, the 'huge graph of interconnected objects' would be a mess to deal with, when detaching it from the hibernate session and transferring it to the clients.

          The only viable solution would be the 'Open Session in View' pattern, to allow lazy-loading of the associations even in the client side, but that would complicate things even more.

          So in the end, I prefer to leave all the associations single-ended, and handle the other way around with proper service methods (getXXXReviews() etc...).

          Especially since those associations won't be used everywhere the object is shown, but only in certain cases (full object details, etc...).

          Originally posted by Andreas Senft
          That said, the type of an association should be determined by the use cases you have. If your (important) use cases require to traverse a specific association in both directions, then it would not make sense to model it unidirectional. If, however, such a requirement doesn't exist, I would not make an association bidirectional "just in case".
          As usual, there is no single recipe on how to do things. :-/
          As I said, very true, and since this use case is not very common, and most of the time this associations won't be used, I prefer to use single-ended associations and deal with the other cases through proper service methods exposed on the corresponding server business class (ItemManager, UserManager, etc..).


          Originally posted by Andreas Senft
          This one is indeed not easy. In any case I would try to get rid of "collections". It should be sufficient to be able to have multiple objects in a single review.
          Besides that, I guess that each object could participate in more than one review. So you end up having n-to-m relations. So you could have intermediate mapping tables between review and each type or one big intermediate table that stores also type information which allows resolving the correct associated instance.
          From a maintenance point of view I would choose the one-table approach, though it might be more complicated to set up the appropriate queries.
          I cannot eliminate collection since this is not an utility class for representing a bunch of items, but has a specific meaning and lifecycle (the users will communicate also through the 'collections' of items they have set up, like "The item that made me cry" collection, etc...). They are a very important part of the use cases.

          Regarding the mapping, the one-table approach with a proper field to lookup the appropriate table involved in the particular instance of the polimorphic query, is indeed the approach that seems that most reasonable and performant to me (this way I wouldn't have to query N table, but only one, bigger, with proper where clauses).

          My doubt then regard how to declare this in Hibernate: I've never seen cases of a 'polimorphic' lookup dependent on the value of a field of the lookup table.

          Ideally, I would love to have an intermediate lookup table with 3 FIELDS:

          long reviewID (ID of the review)
          long objectID (ID of the object reviewed)
          enum objectType (enum, or some other type, to know where to look up the object ID)

          The problem is then: how could I represent this in Hibernate? I've never seen any example regarding the target table dependent on a lookup table field.

          Is this possible at all using hibernate config? If not, is there any other way I could implement this, like implementing some HibernateAssociationLoader class or the like, for that very specific case, without having to lose the standard hibernate ORM and do manually all the ORM for the involved objects?

          Originally posted by Andreas Senft
          Hope it helps,
          Andreas
          You are indeed helping me out, to a GREAT deal, believe me =).
          Last edited by omero; Apr 27th, 2006, 07:55 AM.

          Comment


          • #6
            Originally posted by omero
            I cannot eliminate collection since this is not an utility class for representing a bunch of items, but has a specific meaning and lifecycle (the users will communicate also through the 'collections' of items they have set up, like "The item that made me cry" collection, etc...). They are a very important part of the use cases.
            I see. Then maybe make that "collection" a first class domain object, referring to the contained objects. Then the association to the "collection" would be the same as the association to a "simple" object.

            Originally posted by omero
            Ideally, I would love to have an intermediate lookup table with 3 FIELDS:

            long reviewID (ID of the review)
            long objectID (ID of the object reviewed)
            enum objectType (enum, or some other type, to know where to look up the object ID)

            The problem is then: how could I represent this in Hibernate? I've never seen any example regarding the target table dependent on a lookup table field.
            That's how I envisioned it also. As of the mapping with Hibernate I am also unsure. Maybe you could use the hibernate type alias as object type identifier in the table. Then you could first get all entries belonging to a review id and from them build a dynamic query by id, using the type identifier for the "from" clause.
            Perhaps someone else can provide a more elegant solution, though.


            Originally posted by omero
            You are indeed helping me out, to a GREAT deal, believe me =).
            You're welcome
            Andreas

            Comment


            • #7
              Originally posted by Andreas Senft
              I see. Then maybe make that "collection" a first class domain object, referring to the contained objects. Then the association to the "collection" would be the same as the association to a "simple" object.
              In fact that's exactly what I did. My DOM is made up of several first-class objects, and Collection is one of those, as Item, User, Review, Comment, Tag, Vote, etc...

              Having the 'Collection' as an extension of 'Item' could simplify things for Item-Collection, but I would still have the problem for everything else.

              For example, I would love to have 'Vote's for all the entities: User, Item, Comments, Reviews, etc... without having to split Vote into N unneeded and unwanted specific classes (CommentVote, UserVote, ItemVote, etc...).

              This would complicate my DOM to a great axtent, and reduce by a lot the re-usability of the domain objects.

              Originally posted by Andreas Senft
              That's how I envisioned it also. As of the mapping with Hibernate I am also unsure. Maybe you could use the hibernate type alias as object type identifier in the table. Then you could first get all entries belonging to a review id and from them build a dynamic query by id, using the type identifier for the "from" clause.
              Perhaps someone else can provide a more elegant solution, though.
              Unfortunately, I cannot even understand your proposed solution.

              I'm sorry, but I'm not very competent of Hibernate Type Alias, and therefore I cannot understand how they could help me out in this case, and how could I use them to reach my proposed solution: a 'dynamic' lookuptablefield-dependent lookup.

              Andreas or any other can elaborate a bit more on this, or propose another solution for this? Thanks in advance guys =)

              Originally posted by Andreas Senft
              You're welcome
              Andreas

              Comment


              • #8
                Originally posted by omero
                For example, I would love to have 'Vote's for all the entities: User, Item, Comments, Reviews, etc... without having to split Vote into N unneeded and unwanted specific classes (CommentVote, UserVote, ItemVote, etc...).
                Maybe for that case the same approach could be used as for the assignment of reviews: a generic intermediate table.

                Originally posted by omero
                Unfortunately, I cannot even understand your proposed solution.
                I'm sorry. Actually it was a little bit "loud thinking".

                I meant the following: If you have a class "mypkg.Item" then you could use that string as identifier in the third column of the intermediate table.
                In the mapping you can optionally specify the package (here for example "mypkg"), so you could just use "Item" in your queries. In that case you could use "Item" as identifier. That is, what I meant by type alias.

                So you could then retrieve all entries with a given review id. For each element you will then have an id (e.g. 42) and a type (e.g. "Item").
                Then you could create a HQL query "from Item where id = 42".

                Problem is, that this does not scale well for large numbers of objects this way (n+1 select problem). For small number of objects it would be ok, though.

                Regards,
                Andreas

                Comment


                • #9
                  Just thought about a solution for the n+1 select problem.
                  After reading the intermediate entries you could group the ids by type and then create one statement per type using the "IN" keyword.
                  E.g.: "from Item where id in (42, 47, 51)"

                  Regards,
                  Andreas

                  Comment


                  • #10
                    Originally posted by Andreas Senft
                    Maybe for that case the same approach could be used as for the assignment of reviews: a generic intermediate table.
                    True, but I would prefer to avoid to have intermediate classes for that. My DOM is simply not done that way: I have one Vote, one Comment, etc... they are not polimorphic, it's the association that is.

                    And I prefer not to have to force my DOM into this way, unless explicitly and absolutely forced to, by impossibility to mapping the DOM the way I modelled it

                    Originally posted by Andreas Senft
                    I'm sorry. Actually it was a little bit "loud thinking".

                    I meant the following: If you have a class "mypkg.Item" then you could use that string as identifier in the third column of the intermediate table.
                    In the mapping you can optionally specify the package (here for example "mypkg"), so you could just use "Item" in your queries. In that case you could use "Item" as identifier. That is, what I meant by type alias.

                    So you could then retrieve all entries with a given review id. For each element you will then have an id (e.g. 42) and a type (e.g. "Item").
                    Then you could create a HQL query "from Item where id = 42".

                    Problem is, that this does not scale well for large numbers of objects this way (n+1 select problem). For small number of objects it would be ok, though.

                    Regards,
                    Andreas
                    Oh, now I understand what you mean. Using as a parameter in HQL queries, the content of that 'discriminating' field.

                    Yes, this would indeed work, but the problem is performance, since I wouldn't be able to query on a simple join of the involved tables, but instead selecting a single record through a specific HQL query with a parameter filled up from the lookup table field.

                    I have to investigate better this case, and the related performance problems.

                    In the meanwhile I'm still listening for (possible) better approaches, but to the whole design, and to this specific mapping problem using hibernate.

                    THanks again Andreas.

                    Comment


                    • #11
                      Originally posted by Andreas Senft
                      Just thought about a solution for the n+1 select problem.
                      After reading the intermediate entries you could group the ids by type and then create one statement per type using the "IN" keyword.
                      E.g.: "from Item where id in (42, 47, 51)"

                      Regards,
                      Andreas
                      True... but thinking about it, the use case would be as this:

                      A) View a list of the different collections or items, without using the associations of related votes/review/whatever at all

                      B) When clicking on a specific item, load through service methods the related reviews, votes, comments, etc... and display them in the 'item' detailed sheet.

                      C) When clicking on a specific review/comment/vote, display the info regarding it, along with a 'link' to the review/commented/voted object.

                      So, thinking about it, 99% of the times I would be loading one item at a time, and not mass loading hundreds of instances.

                      Anyway, if that was needed, I could use the IN (A, B, C) as you suggested, scanning first the intermediate table to build the needed query, in order to get all the Reviews for the specific N items, for example. But this would be a very rare usecase.

                      So I think it could work, even from a performance point of view. What do you think Andreas? THansk again =)

                      Comment


                      • #12
                        When navigating from an item to a review you can use a straightforward join, as the target type (Review) is known.

                        The dynamic query building would be required for the other way around. Which way to go (with or without IN clause) depends then on the number of expected objects. But I think it would be ok from a performance point of view (unless you have _many_ types, as you need a query for each type).

                        Regards,
                        Andreas

                        Comment


                        • #13
                          Originally posted by omero
                          True, but I would prefer to avoid to have intermediate classes for that. My DOM is simply not done that way: I have one Vote, one Comment, etc... they are not polimorphic, it's the association that is.
                          I think that you would need an intermediate table in any case, as one item could be in more than one collection (I guess) and one collection holds more than one item.

                          Maybe you could define a common type for all types that could participate in a collection. Then you could define the mapping based on that type, using one intermediate table. That should be supported by Hibernate directly.

                          Regards,
                          Andreas

                          Comment


                          • #14
                            Originally posted by Andreas Senft
                            I think that you would need an intermediate table in any case, as one item could be in more than one collection (I guess) and one collection holds more than one item.

                            Maybe you could define a common type for all types that could participate in a collection. Then you could define the mapping based on that type, using one intermediate table. That should be supported by Hibernate directly.

                            Regards,
                            Andreas
                            You got me wrong (= I explained badly), I surely know I need an intermediate table for collection-items (yes you are right, an item can be in many collections, and a collection is made up of many items).

                            I was just saying that i don't want intermediate CLASSES for mapping the hierarchy, like ReviewVote ItemVote UserVote, for representing a Vote on the different objects. I prefer a single 'Vote', with a polimorphic association with the needed object, which can be a different 'type' from time to time (a vote of a Review, a vote of an Item).

                            Comment


                            • #15
                              Originally posted by Andreas Senft
                              When navigating from an item to a review you can use a straightforward join, as the target type (Review) is known.
                              Very true, and since this will be the most common way of navigating the association, I'm fine with it.

                              Still, I prefer to leave the review.getReviewItem() on the review because I think it's the best thing to do, and avoid having the item.getReviews() instead, because that would force me to deal with lazy-initialization for associations to avoid to load and transfer a huge object graph even when it's not needed.

                              I would prefer to simply detach the fully initialized object to send it to clients, without having to keep the open session in the client, or similar workaround ("Open Session in View" pattern).

                              This can be obtained if I leave references from the review, to the review items, through the special lookup table you suggested, but do not put references from the item to the reviews, which would lead to an huge object graph very very quickly.

                              Originally posted by Andreas Senft
                              The dynamic query building would be required for the other way around. Which way to go (with or without IN clause) depends then on the number of expected objects. But I think it would be ok from a performance point of view (unless you have _many_ types, as you need a query for each type).
                              True, but it will be needed only for the single item in most of the cases (to show the 'review' along with the item the review refers to, when showing the 'review' sheet), and cases where I need to load all the reviews regarind a specific set of items, I can use the IN as you suggested.

                              In the end it seems to work, I seem to have found a viable solution thanks to you, but I would love to hear what you and others possibly think about it

                              Is it good design to have the association uni-directional in the less-used direction to avoid huge graph? Is there a better approach?

                              The more answers, the merrier ^_^

                              Comment

                              Working...
                              X