Torque
  1. Torque
  2. TORQUE-182

Additional methods for handling associated objects

    Details

    • Type: New Feature New Feature
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 4.0
    • Component/s: None
    • Labels:
      None

      Description

      Assuming complexObjectModel=true and objectIsCaching=true (the default settings for generation)
      Consider a table (book) having a foreign key on another table (author).
      Couurently, in the Author object, the method addBook() is implemented, by which a book can be associated with the author and which adds it to the collection obtained by getBooks(). These books are also saved when the author object is saved.

      However, there are no methods by which associations can be removed, an associated book can be deleted or all associated books can be deleted.
      It would be nice if one could do these operations on an object level and these operations would be written to the database on save().
      The first possibility to implement this would be to generate methods removeBook(), deleteBook() and deleteAllBooks().
      The other possibility would be to use a custom list object which intercepts the calls to the add(), remove() etc methods and translates these operations to database operations (with the problem that remove() can be interpreted as removing the association as well as deleting the associated object, my preference being the latter)

        Activity

        Hide
        Thomas Fox added a comment -

        So there should be a new method e.g. author.setAndSaveBooks(Collection<Book> newAssociatedBooks)
        Saving amkes sense because deletion of other objects also happens during the method.

        There might be the following special cases to consider for the delete part

        • singular primary key: The delete can be done like "delete from book where author_id=? and book_id not in (?,...?);
        • composite primary key (e.g. in m:n association table). The deletes must be done like "delete from book where author_id=? and not ((book_pk1=?and book_pk2=?) or (book_pk1=? and book_pk2=) or ...)
        • no primary key or primary key disregarded (e.g. by boolean flag): delete like composite primary key but with value attrs instead of pk attrs

        Updating/saving is done by loading all remaining associated objects and comparing them to the newAssociatedBooks.
        Either by pk values or by value attrs, depending whether pk exists and is not disregarded. If a equivalent object is found in both lists, the modified flag and the new flag must be set in the newAssociatedBooks entry accordingly.
        Perhaps there should be also a forceSave mode which saves all associated objects, regardless whether they are modified or not (note that loading is still necessary for that, to decide between update and insert)

        Show
        Thomas Fox added a comment - So there should be a new method e.g. author.setAndSaveBooks(Collection<Book> newAssociatedBooks) Saving amkes sense because deletion of other objects also happens during the method. There might be the following special cases to consider for the delete part singular primary key: The delete can be done like "delete from book where author_id=? and book_id not in (?,...?); composite primary key (e.g. in m:n association table). The deletes must be done like "delete from book where author_id=? and not ((book_pk1=?and book_pk2=?) or (book_pk1=? and book_pk2=) or ...) no primary key or primary key disregarded (e.g. by boolean flag): delete like composite primary key but with value attrs instead of pk attrs Updating/saving is done by loading all remaining associated objects and comparing them to the newAssociatedBooks. Either by pk values or by value attrs, depending whether pk exists and is not disregarded. If a equivalent object is found in both lists, the modified flag and the new flag must be set in the newAssociatedBooks entry accordingly. Perhaps there should be also a forceSave mode which saves all associated objects, regardless whether they are modified or not (note that loading is still necessary for that, to decide between update and insert)
        Hide
        CG Monroe added a comment -

        I think this should be done either as a set of new methods rather than automatically doing this on save.

        Just because something is related does not mean there is automatically a one to one relationship. So, deleting the related information automatically and by default is not a good thing IMHO.

        For instance, take the case of an object that maps a user to application permissions. If you delete or modify the user mapping, you don't want to automatically delete the permission records, since there are used by multiple other users and application tables.

        If you are going to do a "cascade" delete, it should be clear in the code that this is happening. Just like in a DB schema, you can decide exactly where this happens.

        Show
        CG Monroe added a comment - I think this should be done either as a set of new methods rather than automatically doing this on save. Just because something is related does not mean there is automatically a one to one relationship. So, deleting the related information automatically and by default is not a good thing IMHO. For instance, take the case of an object that maps a user to application permissions. If you delete or modify the user mapping, you don't want to automatically delete the permission records, since there are used by multiple other users and application tables. If you are going to do a "cascade" delete, it should be clear in the code that this is happening. Just like in a DB schema, you can decide exactly where this happens.
        Hide
        Thomas Fox added a comment -

        Thinking further on it, the use case I encounter most in practice is to ascertain that the associated books consist of a given set.
        So, given a random collection of books (newAssociatedBooks), I would like to call author.setBooks(newAssociatedBooks) and expect the following is done

        • delete all books which are currently associated to the author in the database and are not in newAssociatedBooks
        • update all books which are currently associated to the author in the database and are in newAssociatedBooks to the book values in newAssociatedBooks
        • insert all books which are currently not associated to the author in the database and are in newAssociatedBooks to the book values in newAssociatedBooks
        • fill the collection which is returned by author.getBooks() by the books in newAssociatedBooks
        Show
        Thomas Fox added a comment - Thinking further on it, the use case I encounter most in practice is to ascertain that the associated books consist of a given set. So, given a random collection of books (newAssociatedBooks), I would like to call author.setBooks(newAssociatedBooks) and expect the following is done delete all books which are currently associated to the author in the database and are not in newAssociatedBooks update all books which are currently associated to the author in the database and are in newAssociatedBooks to the book values in newAssociatedBooks insert all books which are currently not associated to the author in the database and are in newAssociatedBooks to the book values in newAssociatedBooks fill the collection which is returned by author.getBooks() by the books in newAssociatedBooks

          People

          • Assignee:
            Thomas Fox
            Reporter:
            Thomas Fox
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development