Reputation: 1163
I use the grails formRemote tag to add an item to a dropdown list "on the fly". The item does get added, but when I submit the main form I get:
Could not find matching constructor for: VarnType(java.lang.String)
where Varn is the domain object being created in the main form and VarnType is the domain object listed in the dropdown,the list I am adding to with formRemote. Here is the formRemote usage:
<g:form url="[resource:varnInstance, action:'save']" id="mainV">
<fieldset class="form">
<g:render template="form"/>
</fieldset>
<fieldset class="buttons">
<g:submitButton name="create" class="save" value="${message(code: 'default.button.create.label', default: 'Create')}" />
</fieldset>
</g:form>
<g:formRemote name="vTypeForm"
url="[controller:'varnType', action:'createVarnTypeOnTheFly']"
update="varnType">
<input type="text" name="typeName" >
<input type="submit" value="Create Varn Type!">
</g:formRemote>
Thinking that the VarnType object needed another constructor with an argument of String, I added it, but got, in the controller of the Varn domain object itself:
Class
org.hibernate.TransientObjectException
Message
object references an unsaved transient instance - save the
transient instance before flushing
I don't understand why the Varn domain object (the parent object) is trying to persist a VarnType (child object) that was already created via the formRemote. Is there an additional step I should take to make this object available to Grails?
EDIT: Here is controller code:
def createVarnTypeOnTheFly(){
VarnType vt = new VarnType(params)
vt.save flush: true
render(template: '/config/varnTypeOptions',model:[optionList: VarnType.list()])
}
Here is the entity relationship:
class VarnType {
String typeName
static constraints = {
}
static mapping = {
id column:"varn_type_id"
id generator: "sequence",params: [sequence:"scan_sequence"]
}
String toString(){
return typeName
}
}
VarnType:
class Varn {
Application app
Assessment assessment
String varnName
String recommendation
String httpMethod
VarnType varnType
String varnNote
String param
Risk risk
String urlParam
Date dateFound
Date dateReported
Date dateFixed
static hasMany = [varnNotes:AppNote]
static constraints = {
varnName nullable: true
urlParam nullable: true
risk nullable: true
recommendation nullable: true
assessment nullable: true
}
static mapping = {
id column:'varn_id'
id generator: 'sequence',params:[sequence:'scan_sequence']
}
}
Thanks.
Upvotes: 1
Views: 635
Reputation: 27245
I expect that you have a request parameter named varnType
and you are doing something like new Varn(params)
. When the data binder tries to initialize the varnType
property in the Varn
instance, since you haven't told it otherwise it us trying to call new VarnType(params.varnType)
, which fails.
If you want the binder to be able to create an instance of VarnType
from a String you will need to do something like provide a custom Converter
or use the BindUsing
annotation. All of that is covered in the user guide. See http://grails.org/doc/latest/guide/theWebLayer.html#dataBinding.
Upvotes: 3