title: Grails one to many with composite key
body: <p>(Grails 2.2.4) </p>
  
  <p>When I execute this:</p>
  
  <pre><code>def AuditLog auditLog=new AuditLog(appUserId: 1488902, auditDate: new Date(), action: "Update Questionnaire", username: "USER1" )
  auditLog.addToAuditTargets(new AuditTarget(targetId: 100, type: "what's the type"))
  auditLog.save(failOnError:true)
  </code></pre>
  
  <p>I get this error:</p>
  
  <blockquote>
    <p>| Error 2014-01-04 00:39:38,904 [localhost-startStop-1] ERROR context.GrailsContextLoader  - Error initializing the application: Validation Error(s) occurred during save():
    - <strong>Field error in object 'com.company.kyn.model.AuditLog' on field 'auditTargets[0].auditId': rejected value [null]</strong>; codes [com.company.kyn.model.AuditTarget.auditId.nullable.error.com.company.kyn.model.AuditLog.auditTargets[0].auditId...]; arguments [auditId,class com.company.kyn.model.AuditTarget]; default message [Property [{0}] of class [{1}] cannot be null]</p>
  </blockquote>
  
  <p>The generated auditId is not set on AuditTarget. How do I fix this?</p>
  
  <p>Thank you.</p>
  
  <pre><code>package com.company.kyn.model
  
  class AuditLog {
  
  Date auditDate
  String action
  String username
  Long appUserId
  
  static hasMany = [auditTargets: AuditTarget]
  
  static mapping = {
      id column: "AUDIT_ID", generator: "hilo"
      auditTargets joinTable:false
      version false
  }
  
  static constraints = {
      action maxSize: 100
      username maxSize: 100
  }
  }
  </code></pre>
  
  <hr>
  
  <pre><code>package com.company.kyn.model
  
  import org.apache.commons.lang.builder.EqualsBuilder
  import org.apache.commons.lang.builder.HashCodeBuilder
  
  class AuditTarget implements Serializable {
  
  Long auditId
  String type
  Long targetId
  
  static belongsTo = [auditLog:AuditLog]
  
  static mapping = {
      id composite: ["auditId", "type", "targetId"]
      auditLog column: "AUDIT_ID"
      version false
  }
  
  static constraints = {
      type maxSize: 100
  }
  
  int hashCode() {
      def builder = new HashCodeBuilder()
      builder.append auditId
      builder.append type
      builder.append targetId
      builder.toHashCode()
  }
  
  boolean equals(other) {
      if (other == null) return false
      def builder = new EqualsBuilder()
      builder.append auditId, other.auditId
      builder.append type, other.type
      builder.append targetId, other.targetId
      builder.isEquals()
  }
  }
  </code></pre>