okelet
okelet

Reputation: 756

HasOne and HasMany of the same domain class and cascade save

I have 2 domain classes; the forst of them represents an email address, with the name of the user and the email address itself. The other class represents an email message, with the subject, the sender (one email address) and the recipients (a list of email addresses):

class EmailMessage {
    static hasMany = [ to: EmailAddress ]
    EmailAddress from
    String subject
}

class EmailAddress {
    String name
    String address
}

But this code doesn't work as I expect:

EmailMessage msg = new EmailMessage()
msg.from = new EmailAddress(name: "User 1", address: "[email protected]")
[new EmailAddress(name: "User 2", address: "[email protected]"), new EmailAddress(name: "User 3", address: "[email protected]")].each {
    msg.addToTo(it)
}
msg.subject = "Asunto"
msg.save(failOnError: true)

I get this error:

| Error 2013-08-14 21:08:40,362 [localhost-startStop-1] ERROR util.JDBCExceptionReporter  - La columna "FROM_ID" no permite valores nulos (NULL)
NULL not allowed for column "FROM_ID"; SQL statement: insert into email_message (id, version, from_id, subject) values (null, ?, ?, ?) [23502-164]
| Error 2013-08-14 21:08:40,375 [localhost-startStop-1] ERROR context.GrailsContextLoader  - Error initializing the application: could not insert: [prueba.EmailMessage];
SQL [insert into email_message (id, version, from_id, subject) values (null, ?, ?, ?)]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not insert: [prueba.EmailMessage]
Message: could not insert: [prueba.EmailMessage]; SQL [insert into email_message (id, version, from_id, subject) values (null, ?, ?, ?)]; constraint [null];
nested exception is org.hibernate.exception.ConstraintViolationException: could not insert: [prueba.EmailMessage]

I don't know if this even can be done, or the cascade save doesn't work as I suppose.

I thik I have tried all combinations of hasMany, belongsTo, etc. in each class, without success.

I have also read this topic but it doesn't work as expected Grails hasOne and hasMany same domain.

Could any one help me? Regards and thanks in advance.

Upvotes: 0

Views: 1197

Answers (2)

James Kleeh
James Kleeh

Reputation: 12228

This works for me in the standard memory database

class EmailMessage {
    static hasMany = [ to: EmailAddress ]
    EmailAddress from
    String subject

    static mapping = {
        from cascade: "save-update" //Pretty sure this is unnecessary
    }
}

class EmailAddress {
    String name
    String address

    static belongsTo = EmailMessage
}

Upvotes: 1

Chris
Chris

Reputation: 8109

Unfortunately you have to save your from before you save the parent.

EmailMessage msg = new EmailMessage()
msg.from = new EmailAddress(name: "User 1", address: "[email protected]")
if (!msg.from.save(flush: true)) {
    log.error("message could not be saved: " + msg.from.errors)
}
[new EmailAddress(name: "User 2", address: "[email protected]"), new EmailAddress(name: "User 3", address: "[email protected]")].each {
    msg.addToTo(it)
}
msg.subject = "Asunto"
msg.save(failOnError: true)

There is no cascading save in a 1:1 relation.

Upvotes: 1

Related Questions