Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I have an optional one-to-one relationship in GORM?

I have 2 objects, ObjectA and ObjectB.

When ObjectA gets created, ObjectB doesn't (and can't, due to not having the data yet) exist yet.

Once ObjectB is created, it needs to have a corresponding ObjectA attached to it if an appropriate one exists. If there isn't an appropriate ObjectA, then the new ObjectB simply isn't connected to one.

So, all ObjectA instances will eventually be attached to an ObjectB, but not all ObjectB instances will have an ObjectA.

Essentially, I'm looking for GORM to build database tables like this:

ObjectA
- Id (NotNull, unique)
- ObjectB_Id[FK: ObjectB.Id] (unique)

ObjectB
- Id (NotNull, unique)

How can I put together the GORM domain classes to do this?

I've tried just about every combination of hasOne, belongsTo, raw properties, nullable: true and unique: true constraints I can think of, but I must be missing one. This doesn't seem like it's a particularly odd scenario, so there must be some way to accomplish this.

like image 415
cdeszaq Avatar asked Feb 21 '12 18:02

cdeszaq


1 Answers

As is often the case, putting my thoughts together into a question lead me to the solution:

Class ObjectA {
    ObjectB objectB

    static constraints = {
        objectB nullable: true, unique: true
    }
}

Class ObjectB {
    static belongsTo = [objectA: ObjectA]

    static constraints = {
        objectA nullable: true
    }
}

The only catch with this that I can't seem to get around is that it's possible to set ObjectB.objectA to an ObjectA that is already associated with an ObjectB. When saving the new association, GORM just doesn't save the association. No errors are thrown, and pulling the new ObjectB out of the database leaves it's objectA property unset.

Adding unique: true to the objectA constraints in the ObjectB class doesn't help either. Instead of silently failing, an error is thrown indicating that the uniqueness check is failing due to an un-set parameter.

like image 77
cdeszaq Avatar answered Oct 09 '22 03:10

cdeszaq