|
With the example classes below, I tried to model an optional one-to-one (zero or one) with State and Country both being optional owners of Capitol but this fails with the following error. How should a zero or one relationship be specified where the child has more than one owner? class Capitol { State state Country country static constraints = { state(nullable:true) country(nullable:true) } } package optionalonetoone class Country { static hasOne = [capitol:Capitol] static constraints = { } } package optionalonetoone class State { static hasOne = [capitol:Capitol] static constraints = { } } @Test void testSomething() { assert new Country(capitol:new Capitol()).save(failOnError:true) } | Failure: testSomething(optionalonetoone.CountryTests) | org.springframework.jdbc.UncategorizedSQLException: Hibernate operation: could not insert: [optionalonetoone.Capitol]; uncategorized SQLException for SQL [insert into capitol (id, version, country_id, state_id) values (null, ?, ?, ?)]; SQL state [90006]; error code [90006]; NULL not allowed for column "STATE_ID"; SQL statement: insert into capitol (id, version, country_id, state_id) values (null, ?, ?, ?) [90006-147]; nested exception is org.h2.jdbc.JdbcSQLException: NULL not allowed for column "STATE_ID"; SQL statement: insert into capitol (id, version, country_id, state_id) values (null, ?, ?, ?) [90006-147] at optionalonetoone.CountryTests.testSomething(CountryTests.groovy:20) Caused by: org.h2.jdbc.JdbcSQLException: NULL not allowed for column "STATE_ID"; SQL statement: insert into capitol (id, version, country_id, state_id) values (null, ?, ?, ?) [90006-147] at org.h2.message.DbException.getJdbcSQLException(DbException.java:327) |
|
If I understand correctly, you want to be able to create a capitol with [a state/a country/both/none], and a country or a state where you need to fill in the capitol? How about this construction; you'll make the capitol a leading entity to which either the country or state belong to, creating an optional one to one relation. (Please ignore this if I misunderstood you ;-)) class Capitol { static hasOne = [state: State, country: Country] static constraints = { state nullable: true country nullable: true } } class Country { static belongsTo = [capitol: Capitol] static constraints = { capitol nullable: false } } class State { static belongsTo = [capitol: Capitol] static constraints = { capitol nullable: false } } On Wednesday, May 2, 2012 at 5:33 PM, Brandon Fish wrote:
|
|
In reply to this post by bjfish
On Wed, May 2, 2012 at 8:33 AM, Brandon Fish <[hidden email]> wrote:
You are looking for the 'mappedBy' directive. Example and details here: http://grails.org/doc/latest/ref/Domain%20Classes/mappedBy.html
|
|
In reply to this post by bjfish
Hey,
regarding your subject, one-to-one does not go along with multiple owners. Also i would not use hasOne with nullable: true on the corresponding domain. Here is how you can setup your domains. If you like, you can delete in State domain hasOne Capitol and add Capitol capitol. In Capitol domain you can then add belongsTo State and make in both domains nullable true. Sure there is different setup with Capitol / Country mapping, but i would do it over the State, because this is the natural way. class Country { static hasMany = [states: State] static constraints = { } } class State { static belongsTo = [country: Country] static hasOne = [capital: Capitol] static constraints = { } } class Capitol { State state static constraints = { } } Date: Wed, 2 May 2012 10:33:37 -0500 From: [hidden email] To: [hidden email] Subject: [grails-user] How do you specify an optional one-to-one with multiple owners With the example classes below, I tried to model an optional one-to-one (zero or one) with State and Country both being optional owners of Capitol but this fails with the following error. How should a zero or one relationship be specified where the child has more than one owner? class Capitol { State state Country country static constraints = { state(nullable:true) country(nullable:true) } } package optionalonetoone class Country { static hasOne = [capitol:Capitol] static constraints = { } } package optionalonetoone class State { static hasOne = [capitol:Capitol] static constraints = { } } @Test void testSomething() { assert new Country(capitol:new Capitol()).save(failOnError:true) } | Failure: testSomething(optionalonetoone.CountryTests) | org.springframework.jdbc.UncategorizedSQLException: Hibernate operation: could not insert: [optionalonetoone.Capitol]; uncategorized SQLException for SQL [insert into capitol (id, version, country_id, state_id) values (null, ?, ?, ?)]; SQL state [90006]; error code [90006]; NULL not allowed for column "STATE_ID"; SQL statement: insert into capitol (id, version, country_id, state_id) values (null, ?, ?, ?) [90006-147]; nested exception is org.h2.jdbc.JdbcSQLException: NULL not allowed for column "STATE_ID"; SQL statement: insert into capitol (id, version, country_id, state_id) values (null, ?, ?, ?) [90006-147] at optionalonetoone.CountryTests.testSomething(CountryTests.groovy:20) Caused by: org.h2.jdbc.JdbcSQLException: NULL not allowed for column "STATE_ID"; SQL statement: insert into capitol (id, version, country_id, state_id) values (null, ?, ?, ?) [90006-147] at org.h2.message.DbException.getJdbcSQLException(DbException.java:327) |
|
To clarify, I plan for the Capitol to have one of either the State or Capitol at a time.
I believe the entity diagram would look like the following with either the state or country being the owner: State 0..1 ----- 1 Capitol 1 ---- 0..1 Country There would be only one owner at a time. Given the responses I'm still not sure how to model this. On Wed, May 2, 2012 at 11:17 AM, Christian Rommel <[hidden email]> wrote:
|
|
How about this construction; both Country and State are a Governed Entity, and Capitol has one of those. You can use capitol.governedEntity.instanceOf(Country) to determine wether that governedEntity is a Country or not, and Capitol will always have one of either (or none):
class Country extends GovernedEntity { static belongsTo = [capitol: Capitol] static constraints = { capitol nullable: false } } class State extends GovernedEntity { static belongsTo = [capitol: Capitol] static constraints = { capitol nullable: false } } class Capitol { static hasOne = [governedEntity: GovernedEntity] static constraints = { governedEntity nullable: true } } On Wednesday, May 2, 2012 at 6:28 PM, Brandon Fish wrote:
|
|
On Wed, May 2, 2012 at 9:43 AM, Eric Ettes <[hidden email]> wrote:
Wouldn't you put the capitol property in GovernedEntity if you were going to do it via a common base class - which is probably the appropriate way to do it if you want it to have EITHER a state OR a country rather than the potential for both, since your domain model would then be correctly enforcing your logical construction. You could have two properties in capitol and only assign to one of them at a time, but then you've got to enforce that constraint or risk having an entity in an inconsistent state. And for the record, a 'capitol' is a building that houses a legislative assembly, and a 'capital' is a city that is the seat of govt.
|
| Powered by Nabble | Edit this page |
