Grails 无法从表单中级联保存多对一

标签 grails grails-orm

我有一个多对一的关系,我想通过一个表单公开,但我无法让级联保存工作,我在日志中看不到任何错误/异常。这是域类:

class Person {
  String name
  List reminders = new ArrayList()
  static hasMany = [ reminders : PEvent ]
  static mapping = { reminders cascade:"all-delete-orphan" }
  def getRemindersList() {
    return LazyList.decorate(eventos, FactoryUtils.instantiateFactory(PEvent .class))
  }
}
class PEvent implements Comparable {
  static belongsTo = [person:Person ]
  static transients = [ '_deleted' ]
  String eventType
  Date eventDate
  String comments
  boolean _deleted
  int compareTo(Object other) {
    eventType <=> other.eventType ?: eventDate <=> other.eventDate ?: comments <=> other.comments
  }
}

以下是我在表单中引用提醒的方式:
<div class="fieldcontain ${hasErrors(bean: personInstance, field: 'reminders', 'error')} required">
  <label for="reminders">
    <g:message code="person.reminders.label" default="Reminders" />
    <span class="required-indicator">*</span>
  </label>
  <div id="childList">
    <g:Each var="reminder" in="${personInstance.reminders}" status="i">
    <div id="reminder${i}"> 
      <g:select name="remindersList[${i}].eventType" from="${reminder?.constraints?.eventType?.inList}" required="" value="${reminder?.eventType}" />
      <g:datePicker name="remindersList[${i}].eventDate" precision="day"  value="${reminder?.eventDate}"  />
      <g:textField name="remindersList[${i}].comments" required="" value="${reminder?.comments}"/>
      <input type="hidden" name='remindersList[${i}]._deleted' id='remindersList[${i}]._deleted' value='false'/>
    </div>
    </g:each>
  </div>
</div>

部分跟踪显示持续存在的内容。在开始时,我正在记录从表单中捕获的内容,到目前为止一切正常,但是当 Person 被保存时,提醒集合似乎是空的。
2015-07-13 12:22:13,469 [http-bio-8080-exec-10] DEBUG rescate.personService  - par: remindersList[0].comments=jon5com
2015-07-13 12:22:13,470 [http-bio-8080-exec-10] DEBUG rescate.PersonService  - par: remindersList[0]=[eventType:nacimiento, eventDate:date.struct, eventDate_day:13, eventDate_month:7, eventDate_year:2015, comments:jon5com, _deleted:false]
2015-07-13 12:22:13,470 [http-bio-8080-exec-10] DEBUG rescate.PersonService  - par: daten_month=7
2015-07-13 12:22:13,470 [http-bio-8080-exec-10] DEBUG rescate.PersonService  - par: datein_year=2015
2015-07-13 12:22:13,470 [http-bio-8080-exec-10] DEBUG rescate.PersonService  - par: remindersList[0].eventType=nacimiento
2015-07-13 12:22:13,470 [http-bio-8080-exec-10] DEBUG rescate.PersonService  - par: remindersList[0]._deleted=false
2015-07-13 12:22:13,470 [http-bio-8080-exec-10] DEBUG rescate.PersonService  - par: daten_year=2015
2015-07-13 12:22:13,470 [http-bio-8080-exec-10] DEBUG rescate.PersonService  - par: dist=crt
2015-07-13 12:22:13,470 [http-bio-8080-exec-10] DEBUG rescate.PersonService  - par: remindersList[0].eventDate_day=13
2015-07-13 12:22:13,472 [http-bio-8080-exec-10] DEBUG rescate.PersonService  - par: create=Create
2015-07-13 12:22:13,472 [http-bio-8080-exec-10] DEBUG rescate.PersonService  - par: remindersList[0].eventDate_year=2015
2015-07-13 12:22:13,472 [http-bio-8080-exec-10] DEBUG rescate.PersonService  - par: datein_day=13
2015-07-13 12:22:13,472 [http-bio-8080-exec-10] DEBUG rescate.PersonService  - par: name=jon5
2015-07-13 12:22:13,472 [http-bio-8080-exec-10] DEBUG rescate.PersonService  - par: loop=cm
2015-07-13 12:22:13,472 [http-bio-8080-exec-10] DEBUG rescate.PersonService  - par: datein=date.struct
2015-07-13 12:22:13,473 [http-bio-8080-exec-10] DEBUG rescate.PersonService  - par: gnd=m
2015-07-13 12:22:13,473 [http-bio-8080-exec-10] DEBUG rescate.PersonService  - par: tim=1m
2015-07-13 12:22:13,473 [http-bio-8080-exec-10] DEBUG rescate.PersonService  - par: dateOfIntake_month=7
2015-07-13 12:22:13,473 [http-bio-8080-exec-10] DEBUG rescate.PersonService  - par: remindersList[0].eventDate_month=7
2015-07-13 12:22:13,474 [http-bio-8080-exec-10] DEBUG rescate.PersonService  - par: dateNeutered_day=13
2015-07-13 12:22:13,475 [http-bio-8080-exec-10] DEBUG rescate.PersonService  - par: remindersList[0].eventDate=date.struct
2015-07-13 12:22:13,475 [http-bio-8080-exec-10] DEBUG rescate.PersonService  - par: dateNeutered=date.struct
2015-07-13 12:22:13,475 [http-bio-8080-exec-10] DEBUG rescate.PersonService  - par: spc=notes2
2015-07-13 12:22:13,475 [http-bio-8080-exec-10] DEBUG rescate.PersonService  - par: action=save
2015-07-13 12:22:13,475 [http-bio-8080-exec-10] DEBUG rescate.PersonService  - par: format=null
2015-07-13 12:22:13,475 [http-bio-8080-exec-10] DEBUG rescate.PersonService  - par: controller=person
2015-07-13 12:22:13,615 [http-bio-8080-exec-10] TRACE internal.SessionImpl  - Setting flush mode to: MANUAL
2015-07-13 12:22:13,616 [http-bio-8080-exec-10] TRACE internal.SessionImpl  - Setting flush mode to: AUTO
2015-07-13 12:22:13,616 [http-bio-8080-exec-10] DEBUG hibernate.GrailsHibernateTemplate  - Found thread-bound Session for HibernateTemplate
2015-07-13 12:22:13,617 [http-bio-8080-exec-10] TRACE internal.SessionImpl  - Setting flush mode to: MANUAL
2015-07-13 12:22:13,617 [http-bio-8080-exec-10] TRACE internal.AbstractSaveEventListener  - Transient instance of: org.ppl.Person
2015-07-13 12:22:13,617 [http-bio-8080-exec-10] TRACE internal.DefaultSaveOrUpdateEventListener  - Saving transient instance
2015-07-13 12:22:13,618 [http-bio-8080-exec-10] TRACE internal.AbstractSaveEventListener  - Saving [org.ppl.Person#<null>]
2015-07-13 12:22:13,618 [http-bio-8080-exec-10] TRACE internal.Cascade  - Processing cascade ACTION_SAVE_UPDATE for: org.ppl.Person
2015-07-13 12:22:13,618 [http-bio-8080-exec-10] TRACE internal.Cascade  - Done processing cascade ACTION_SAVE_UPDATE for: org.ppl.Person
2015-07-13 12:22:13,618 [http-bio-8080-exec-10] TRACE internal.Versioning  - Seeding: 0
2015-07-13 12:22:13,618 [http-bio-8080-exec-10] TRACE spi.ActionQueue  - Adding an EntityIdentityInsertAction for [org.ppl.Person] object
2015-07-13 12:22:13,618 [http-bio-8080-exec-10] TRACE spi.ActionQueue  - Executing inserts before finding non-nullable transient entities for early insert: [EntityIdentityInsertAction[org.ppl.Person#<null>]]
2015-07-13 12:22:13,619 [http-bio-8080-exec-10] TRACE spi.ActionQueue  - Adding insert with no non-nullable, transient entities: [EntityIdentityInsertAction[org.ppl.Person#<null>]]
2015-07-13 12:22:13,619 [http-bio-8080-exec-10] TRACE spi.ActionQueue  - Executing insertions before resolved early-insert
2015-07-13 12:22:13,619 [http-bio-8080-exec-10] DEBUG spi.ActionQueue  - Executing identity-insert immediately
2015-07-13 12:22:13,619 [http-bio-8080-exec-10] TRACE internal.SessionImpl  - Setting flush mode to: MANUAL
2015-07-13 12:22:13,621 [http-bio-8080-exec-10] TRACE entity.AbstractEntityPersister  - Inserting entity: org.ppl.Person (native id)
2015-07-13 12:22:13,621 [http-bio-8080-exec-10] TRACE entity.AbstractEntityPersister  - Version: 0
2015-07-13 12:22:13,622 [http-bio-8080-exec-10] DEBUG hibernate.SQL  - insert into animal (id, version, Gnd, daten, datein, tim, spc, name, dist, loop) values (null, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2015-07-13 12:22:13,623 [http-bio-8080-exec-10] TRACE internal.JdbcCoordinatorImpl  - Registering statement [prep38: insert into animal (id, version, Gnd, daten, datein, edad, spc, name, dist, loop) values (null, ?, ?, ?, ?, ?, ?, ?, ?, ?)]
2015-07-13 12:22:13,623 [http-bio-8080-exec-10] TRACE entity.AbstractEntityPersister  - Dehydrating entity: [org.ppl.Person#<null>]
2015-07-13 12:22:13,624 [http-bio-8080-exec-10] TRACE sql.BasicBinder  - binding parameter [1] as [BIGINT] - [0]
2015-07-13 12:22:13,624 [http-bio-8080-exec-10] TRACE sql.BasicBinder  - binding parameter [2] as [VARCHAR] - [Male]
2015-07-13 12:22:13,624 [http-bio-8080-exec-10] TRACE sql.BasicBinder  - binding parameter [3] as [TIMESTAMP] - [Mon Jul 13 00:00:00 ART 2015]
2015-07-13 12:22:13,624 [http-bio-8080-exec-10] TRACE sql.BasicBinder  - binding parameter [4] as [TIMESTAMP] - [Mon Jul 13 00:00:00 ART 2015]
2015-07-13 12:22:13,626 [http-bio-8080-exec-10] TRACE sql.BasicBinder  - binding parameter [5] as [VARCHAR] - [1m]
2015-07-13 12:22:13,626 [http-bio-8080-exec-10] TRACE sql.BasicBinder  - binding parameter [6] as [VARCHAR] - [notes2]
2015-07-13 12:22:13,626 [http-bio-8080-exec-10] TRACE sql.BasicBinder  - binding parameter [7] as [VARCHAR] - [jon5]
2015-07-13 12:22:13,627 [http-bio-8080-exec-10] TRACE sql.BasicBinder  - binding parameter [8] as [VARCHAR] - [crt]
2015-07-13 12:22:13,627 [http-bio-8080-exec-10] TRACE sql.BasicBinder  - binding parameter [9] as [VARCHAR] - [cm]
2015-07-13 12:22:13,628 [http-bio-8080-exec-10] DEBUG id.IdentifierGeneratorHelper  - Natively generated identity: 2
2015-07-13 12:22:13,628 [http-bio-8080-exec-10] TRACE internal.JdbcCoordinatorImpl  - Releasing result set [rs42: org.h2.result.LocalResult@2a3ba9ee columns: 1 rows: 1 pos: 0]
2015-07-13 12:22:13,628 [http-bio-8080-exec-10] TRACE internal.JdbcCoordinatorImpl  - Closing result set [rs42: org.h2.result.LocalResult@2a3ba9ee columns: 1 rows: 1 pos: 0]
2015-07-13 12:22:13,631 [http-bio-8080-exec-10] TRACE internal.JdbcCoordinatorImpl  - Releasing statement [prep38: insert into animal (id, version, Gnd, daten, datein, tim, spc, name, dist, loop) values (null, ?, ?, ?, ?, ?, ?, ?, ?, ?) {1: 0, 2: 'Male', 3: TIMESTAMP '2015-07-13 00:00:00.0', 4: TIMESTAMP '2015-07-13 00:00:00.0', 5: '1m', 6: 'notes2', 7: 'jon5', 8: 'crt', 9: 'cm'}]
2015-07-13 12:22:13,631 [http-bio-8080-exec-10] TRACE internal.JdbcCoordinatorImpl  - Closing prepared statement [prep38: insert into animal (id, version, Gnd, daten, datein, tim, spc, name, dist, loop) values (null, ?, ?, ?, ?, ?, ?, ?, ?, ?) {1: 0, 2: 'Male', 3: TIMESTAMP '2015-07-13 00:00:00.0', 4: TIMESTAMP '2015-07-13 00:00:00.0', 5: '1m', 6: 'notes2', 7: 'jon5', 8: 'crt', 9: 'cm'}]
2015-07-13 12:22:13,631 [http-bio-8080-exec-10] TRACE internal.JdbcCoordinatorImpl  - Starting after statement execution processing [ON_CLOSE]
2015-07-13 12:22:13,632 [http-bio-8080-exec-10] TRACE internal.UnresolvedEntityInsertActions  - No unresolved entity inserts that depended on [[org.ppl.Person#2]]
2015-07-13 12:22:13,633 [http-bio-8080-exec-10] TRACE internal.Cascade  - Processing cascade ACTION_SAVE_UPDATE for: org.ppl.Person
2015-07-13 12:22:13,633 [http-bio-8080-exec-10] TRACE internal.Cascade  - Cascade ACTION_SAVE_UPDATE for collection: org.ppl.Person.reminders
2015-07-13 12:22:13,633 [http-bio-8080-exec-10] TRACE internal.Cascade  - Done cascade ACTION_SAVE_UPDATE for collection: org.ppl.Person.reminders
2015-07-13 12:22:13,633 [http-bio-8080-exec-10] TRACE internal.Cascade  - Done processing cascade ACTION_SAVE_UPDATE for: org.ppl.Person
2015-07-13 12:22:13,633 [http-bio-8080-exec-10] TRACE internal.AbstractSaveEventListener  - Persistent instance of: org.ppl.Person
2015-07-13 12:22:13,633 [http-bio-8080-exec-10] TRACE internal.DefaultSaveOrUpdateEventListener  - Ignoring persistent instance
2015-07-13 12:22:13,634 [http-bio-8080-exec-10] TRACE internal.DefaultSaveOrUpdateEventListener  - Object already associated with session: [org.ppl.Person#2]
2015-07-13 12:22:13,634 [http-bio-8080-exec-10] TRACE internal.UnresolvedEntityInsertActions  - No entity insert actions have non-nullable, transient entity dependencies.
2015-07-13 12:22:13,635 [http-bio-8080-exec-10] TRACE internal.AbstractFlushingEventListener  - Flushing session
2015-07-13 12:22:13,635 [http-bio-8080-exec-10] DEBUG internal.AbstractFlushingEventListener  - Processing flush-time cascades
2015-07-13 12:22:13,635 [http-bio-8080-exec-10] TRACE internal.Cascade  - Processing cascade ACTION_SAVE_UPDATE for: org.ppl.Person
2015-07-13 12:22:13,635 [http-bio-8080-exec-10] TRACE internal.Cascade  - Cascade ACTION_SAVE_UPDATE for collection: org.ppl.Person.reminders
2015-07-13 12:22:13,635 [http-bio-8080-exec-10] TRACE internal.Cascade  - Done cascade ACTION_SAVE_UPDATE for collection: org.ppl.Person.reminders
2015-07-13 12:22:13,635 [http-bio-8080-exec-10] TRACE internal.Cascade  - Done processing cascade ACTION_SAVE_UPDATE for: org.ppl.Person
2015-07-13 12:22:13,635 [http-bio-8080-exec-10] DEBUG internal.AbstractFlushingEventListener  - Dirty checking collections
2015-07-13 12:22:13,635 [http-bio-8080-exec-10] TRACE internal.AbstractFlushingEventListener  - Flushing entities and processing referenced collections
2015-07-13 12:22:13,636 [http-bio-8080-exec-10] TRACE internal.WrapVisitor  - Wrapped collection in role: org.ppl.Person.reminders
2015-07-13 12:22:13,636 [http-bio-8080-exec-10] DEBUG internal.Collections  - Collection found: [org.ppl.Person.reminders#2], was: [<unreferenced>] (initialized)
2015-07-13 12:22:13,636 [http-bio-8080-exec-10] TRACE internal.AbstractFlushingEventListener  - Processing unreferenced collections
2015-07-13 12:22:13,636 [http-bio-8080-exec-10] TRACE internal.AbstractFlushingEventListener  - Scheduling collection removes/(re)creates/updates
2015-07-13 12:22:13,637 [http-bio-8080-exec-10] DEBUG internal.AbstractFlushingEventListener  - Flushed: 0 insertions, 0 updates, 0 deletions to 1 objects
2015-07-13 12:22:13,637 [http-bio-8080-exec-10] DEBUG internal.AbstractFlushingEventListener  - Flushed: 1 (re)creations, 0 updates, 0 removals to 1 collections
2015-07-13 12:22:13,637 [http-bio-8080-exec-10] DEBUG util.EntityPrinter  - Listing entities:
2015-07-13 12:22:13,637 [http-bio-8080-exec-10] DEBUG util.EntityPrinter  - org.ppl.Person{loop=cm, name=jon5, id=2, imagenes=null, datein=Mon Jul 13 00:00:00 ART 2015, Gnd=Male, tim=1m, dist=crt, reminders=[], daten=Mon Jul 13 00:00:00 ART 2015, spc=notes2, version=0}
2015-07-13 12:22:13,638 [http-bio-8080-exec-10] TRACE internal.AbstractFlushingEventListener  - Executing flush
2015-07-13 12:22:13,638 [http-bio-8080-exec-10] DEBUG collection.AbstractCollectionPersister  - Inserting collection: [org.ppl.Person.reminders#2]
2015-07-13 12:22:13,639 [http-bio-8080-exec-10] DEBUG collection.AbstractCollectionPersister  - Collection was empty

任何线索都将受到欢迎。

最佳答案

我发现了这个问题。我正在关注一个示例( http://www.2paths.com/2009/10/01/one-to-many-relationships-in-grails-forms/ ),其中通过 getter 访问 LazyList,并且表单字段将引用此“可扩展”列表。嗯,这就是问题所在,表单字段显然需要具有域的集合列表,因此 grails 可以执行数据绑定(bind)。我的方法:为了向表单添加新字段,我使用 ajax 在 Controller 中调用操作,获取一个新子项并使用它呈现模板,然后在表单中将模板附加到子项列表中。
至于创作,我只是依靠grails数据绑定(bind)。
我仍然不确定上面 2paths 的示例中的 WHY 或 HOW 是通过可扩展列表完成的。

class Author {
  static constraints = {    }
  String name
  List books = new ArrayList()
  static hasMany = [ books:Book ]
  static mapping = {
      books cascade:"all-delete-orphan"
  }
  def getExpandableBookList() {
      return lazyList.decorate(books,FactoryUtils.instantiateFactory(Book.class))
  }
}

关于Grails 无法从表单中级联保存多对一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31389324/

相关文章:

Grails 逆向工程师数据库

Grails GORM 自引用 belongsTo 删除与预期相反的方向

带参数的 grails 域类 .list() 方法

grails - Grails/GORM 中定义的注入(inject)域类方法(如 isDirty、save 等)在哪里?

Grails 动态脚手架与 hasMany : is it a bug or am I misconfiguring?

grails - 计算子项的属性总计,并在Grails中显示在 View 上

json - Grails对请求和响应的通用JSON处理

Grails 填充 g :select from database

spring - 无法安装spring-security-core.2.0-RC2

Grails 1.3.4 缺少依赖问题