Grails
  1. Grails
  2. GRAILS-5303

Inconsistent, erroneous behavior when persisting classes with certain many-to-many relationships

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Duplicate
    • Affects Version/s: 1.2-M2, 1.2-M3
    • Fix Version/s: None
    • Component/s: Persistence
    • Labels:
      None
    • Environment:
      OS X, Java 1.5 and 1.6

      Description

      I've tried this with both Java 1.5 and 1.6, and with both hsqldb and postgresql.

      Basically, setting up the following many-to-many relationship AND an additional field that references the same type (see below) causes inconsistent behavior when saving and getting the objects back out of the persistence store. Note that the below is not precisely the code I'm using in my system; it's redacted somewhat.

      class Member {
      static hasMany = [accounts:Account]

      Account primaryAccount
      }

      class Account {
      static belongsTo = Member
      static hasMany = [members:Member]

      static createAccountAndMember()

      { def member = new Member() def account = new Account() account.addToMembers(member) member.addToAccounts(account) account.save() member.setPrimaryAccount(account) member.save() return member }

      }

      So we have some code that calls Account.createAccountAndMember() (the actual code passes in parameters like first name, last name, etc., which I redacted from the above for clarity), and then redirects to a page which calls the controller via a jsonp callback to return the list of members in the account. Strangely, this second call sometimes returns an empty list, and sometimes returns the correct value (a single member). Adding debugging output confirms that this is what the persistence layer returns — inconsistent results.

      Now, this is the really strange part. If we change the code to the following, it works consistently and never fails:

      class Member {
      static hasMany = [accounts:Account]

      Long primaryAccountId
      }

      class Account {
      static belongsTo = Member
      static hasMany = [members:Member]

      static createAccountAndMember()

      { def member = new Member() def account = new Account() account.addToMembers(member) member.addToAccounts(account) account.save() member.setPrimaryAccountId(account.getId()) member.save() return member }

      }

      My suspicion is that there is something in GORM that is doing lookups based on type via some sort of hashmap when trying to generate the mappings, and if there is an explicit member (such as "primaryAccount") with the type Account and also a collection of accounts inside the Member, sometimes GORM gets confused and fails to persist things correctly. Eliminating the Account variable and changing it to an id resolves the problem.

      It took me several hours to figure out what was going wrong here, so I think this is a bug that ought to be fixed.

        Activity

        Hide
        Thom Pischke added a comment -

        Looks like a potential duplicate of GRAILS-2736

        Show
        Thom Pischke added a comment - Looks like a potential duplicate of GRAILS-2736

          People

          • Assignee:
            Unassigned
            Reporter:
            Mitsu Hadeishi
          • Votes:
            2 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development