1
votes

With Grails 2.2.4. and build-test-data:2.0.5. I'm failing at adding a many-to-many instance in the DB using conf - Bootstrap.groovy. Using MySQL as the database.

Here's the simplified domain classes:

class Reseller {
String resellerName
static hasMany = [addresses: Address]

}

and

class Address {
String address1 
static hasMany = [resellers: Reseller]
static belongsTo = [Reseller]   

}

which results in this being created in MySQL when ran...

(a simple ER diagram below since I can't post images from MySQL Workbench Diagram)

reseller ==> 1 to many==> reseller_address <== many to 1 <== address

CREATE TABLE IF NOT EXISTS address ( id bigint(20) NOT NULL AUTO_INCREMENT, version bigint(20) NOT NULL, address1 varchar(255) NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS reseller ( id bigint(20) NOT NULL AUTO_INCREMENT, version bigint(20) NOT NULL, reseller_name varchar(255) NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;

CREATE TABLE IF NOT EXISTS reseller_addresses ( address_id bigint(20) NOT NULL, reseller_id bigint(20) NOT NULL, PRIMARY KEY (reseller_id,address_id), KEY FK3F39FB15CB44906F (reseller_id), KEY FK3F39FB1541937EA5 (address_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE reseller_addresses ADD CONSTRAINT FK3F39FB1541937EA5 FOREIGN KEY (address_id) REFERENCES address (id), ADD CONSTRAINT FK3F39FB15CB44906F FOREIGN KEY (reseller_id) REFERENCES reseller (id);

Here's the Bootstrap.groovy:

    import grails.buildtestdata.mixin.Build
import manytomany.*

class BootStrap {

    def init = { servletContext ->
        Address ad1 = Address.build()
        Reseller rs1 = Reseller.build()

        //comment out next line to run and see tables being built.
        rs1.addToAddresses(address: ad1) //does not work.  see error below                      
    }
    def destroy = {
    }
}

And the above results in the error below. It also results in zero tables in the DB over in MySQL. I can see them get created and then they disappear at the error below.

    | Running Grails application
Hibernate: insert into address (version, address1) values (?, ?)
Hibernate: insert into reseller (version, reseller_name) values (?, ?)
| Error 2013-11-13 17:37:01,543 [localhost-startStop-1] ERROR hibernate.AssertionFailure  - an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)
Message: null id in manytomany.Address entry (don't flush the Session after an exception occurs)
    Line | Method
->>  334 | innerRun  in java.util.concurrent.FutureTask$Sync
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|    166 | run       in java.util.concurrent.FutureTask
|   1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
|    615 | run       in java.util.concurrent.ThreadPoolExecutor$Worker
^    724 | run . . . in java.lang.Thread
| Error 2013-11-13 17:37:01,628 [localhost-startStop-1] ERROR context.GrailsContextLoader  - Error initializing the application: null id in manytomany.Address entry (don't flush the Session after an exception occurs)
Message: null id in manytomany.Address entry (don't flush the Session after an exception occurs)
    Line | Method
->>  334 | innerRun  in java.util.concurrent.FutureTask$Sync
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|    166 | run       in java.util.concurrent.FutureTask
|   1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
|    615 | run       in java.util.concurrent.ThreadPoolExecutor$Worker
^    724 | run . . . in java.lang.Thread
1

1 Answers

0
votes

Try it this way, you can pass your associations to the parent class through .build(...):

def init = { servletContext ->
    Address ad1 = Address.build()
    Reseller rs1 = Reseller.build(addresses:[ad1])
} 

documentation : https://github.com/tednaleid/build-test-data/wiki/SampleCode