Issue Details (XML | Word | Printable)

Key: GRAILS-3616
Type: Sub-task Sub-task
Status: Resolved Resolved
Resolution: Fixed
Priority: Critical Critical
Assignee: Graeme Rocher
Reporter: Jean-Noël Rivasseau
Votes: 7
Watchers: 6
Operations

If you were logged in you would be able to see more operations.
Grails
GRAILS-3396

One-to-one (bidirectional) does not currently produce correct data structure

Created: 20/Nov/08 06:25 AM   Updated: 26/Feb/09 01:57 PM   Resolved: 18/Dec/08 11:09 AM
Return to search
Component/s: Persistence
Affects Version/s: 1.0.4
Fix Version/s: 1.1-beta2

Time Tracking:
Not Specified

File Attachments: 1. Zip Archive sample-onetoone.zip (143 kB)



 Description  « Hide

As shown from the sample app attached, Grails does not create an optimal (and only correct) data structure for a bidirectional one-to-one.

Grails creates two foreign key columns. One on the owning side, one on the non owning side. This is strange - Hibernate for this case only creates one foreign key column on the owner side, and clearly you only need one column.

Grails should be fixed so that it does not add the useless column on the non owner side (it is the one which is set nullable and that caused me problems; the right FK column on the owner side is marked as non nullable and is OK).

In the attached sample app, two classes are present in two versions, one pure GORM and one Hibernate. Look at the differences in the tables generated.

Also, maybe in the case of a one-to-one bidirectional the "unique" constraint should be applied automatically. Currently it's not the case (so nothing prevents a many to one actually).



Graeme Rocher made changes - 20/Nov/08 07:07 AM
Field Original Value New Value
Issue Type Bug [ 1 ] Sub-task [ 7 ]
Parent GRAILS-3396 [ 73760 ]
Graeme Rocher made changes - 28/Nov/08 08:22 AM
Fix Version/s 1.1-beta1 [ 13674 ]
Fix Version/s 1.1-beta2 [ 14752 ]
Max Lapshin added a comment - 18/Dec/08 01:12 AM

This feature is required because has_one associations meets often in Rails app. If we want to have possibility to seamlesly port applications to Grails, this is musthave feature


Graeme Rocher made changes - 18/Dec/08 05:33 AM
Status Open [ 1 ] In Progress [ 3 ]
Graeme Rocher added a comment - 18/Dec/08 11:09 AM

Fixed. Not this fix applies only to bidirectional one-to-ones. A unidirectional one-to-one is still mapped as a many-to-one by default. You can make it unique if you don't like this, which results in a true one-to-one:

class Face {
    Nose nose

    static mapping = {
        nose unique:true
    }
}

Graeme Rocher made changes - 18/Dec/08 11:09 AM
Resolution Fixed [ 1 ]
Status In Progress [ 3 ] Resolved [ 5 ]
David Rosenstark added a comment - 26/Feb/09 09:03 AM

I downloaded 1.1 RC1 and groovy 1.6 and create two classes:

class Face {
String eyes;
String mouth;
Nose nose

static mapping = { nose unique:true }
}

class Nose { Face face String nostril1 String nostril2 }

When i bring up the app, i still see two foreign key columns:
alter table face add constraint FK2FD65D7F0070FA foreign key (nose_id) references nose
alter table nose add constraint FK33AFD3BF056CBA foreign key (face_id) references face


Graeme Rocher added a comment - 26/Feb/09 11:20 AM

In order to get the single column mapping you need to define an owner:

class Face {
String eyes;
String mouth;
Nose nose

static mapping = { nose unique:true }
}

class Nose { 
   static belongsTo [face:Face] // THIS IS THE CHANGE
   String nostril1 
   String nostril2 
}

Sorry should have been clear on that in the issue


David Rosenstark added a comment - 26/Feb/09 01:57 PM

Thanks, for the clarification. If i understand what you are saying (and i tested it and it works!), then this means that we in order to have the one FK, we are forced to have the cascade in this direction and not the reverse. In other words, if the FK were in Nose instead, then Face would need to belongTo Nose and cascading would be reversed. Or is there some way around this?