Not Saving Domain Object with Grails Searchable Plugin - grails

Is it possible to use the Searchable Plugin to create an index of objects and never actually save the objects to the database?

I think so. If you never save the objects, then I think you can just call:
domainInstance.index()
But I've never tried it, so I'm not sure if it just indexes the one instance, or any instance of that class.
See here:
https://svn.codehaus.org/grails-plugins/grails-searchable/trunk/src/groovy/org/codehaus/groovy/grails/plugins/searchable/compass/domain/DynamicDomainMethodUtils.groovy
If you just want to save the object but just want to index manually, then set the following in your conf/Searchable.groovy config file:
mirrorChanges = false
bulkIndexOnStartup = false
See here: https://svn.codehaus.org/grails-plugins/grails-searchable/trunk/src/conf/Searchable.groovy

Related

Grails .save() not working

When i am writing the .save() in grails it is inserting a new row in the db table. However, not persisting data in the object.
I have tried with .save(flush: true) but had no luck.
Please help.
Thanks
Try save(failOnError:true) or check the return value of save() -- which is success/failure in Groovy-truth.
You can also add logSql: true to your application.yml datasource and
logger 'org.hibernate.type.descriptor.sql.BasicBinder', TRACE, ['STDOUT']
logger 'org.hibernate.SQL', TRACE, ['STDOUT']
to your logback.groovy
Probably the object you want to save is not validated. Means that not match with the minimum constraints described on the domain class.
Debug your code and run the validated method, after that take a look on the errors property.
object.validate()
object.errors
Take a look
https://docs.grails.org/latest/ref/Constraints/Usage.html
Remember that all not declared attributes on the constraints closure, are compulsory by default for saving the object

Why is this a ReadOnly record?

So I am building an associated object through a main object like so:
item.associated_items.build({name: "Machine", color: "Grey"})
and then in another method calling item.save. However I am getting an ActiveRecord::ReadOnlyRecord error. I read in the docs that
Records loaded through joins with piggy-back attributes will be marked as read only since they cannot be saved.
so I think that is what is happening here. But
I dont't know why that is happening. I have called save on an object with a new associated record before and had no problems.
What do the docs mean when they say "piggy-back attributes"?
Is there a way to make the save happen by doing something like item.associated_items.readonly(false).build(attributes). I tried that and it didnt work, but I'm hoping there is another way.
edit: I just tried
new_associated_item = AssociatedItem.new({attributes})
item.associated_items << new_associated_item
and the later method calls
item.save
and the read only exception still happens.
edit2: MurifoX asked me about how Item is being loaded. The above code is happening in a couple of service objects. The process is
Controller
owner = Owner.includes(:medallions).references(:medallions).find_by_id(params[:id])
later
creator = NoticeCreator.new(owner)
creator.run
NoticeCreator
def initialize #effectively
medallion_notice_creators = []
owner.medallions.some_medallion_scope.each do |medallion|
medallion_notice_creator = MedallionNoticeCreator.new(medallion)
medallion_notice_creator.prepare
medallion_notice_creators << medallion_notice_creator
end
end
later after looping through the medallion notice creators
def prepare
medallion.notices.build(attributes)
end
later
medallion_notice_creators.each do |medallion_notice_creator|
medallion_notice_creator.medallion.save
end
Apologies if the code seems convoluted. There is a bunch of stuff going on and I'm trying to condense the code and anonymize it.
Objects created with joins or includes, which is your case, are marked read-only because you are making a giant query with joins and stuff and preloading nested objects within your main one. (ActiveRecord can become confused with so many attributes and don't know how to build the main object, so it marks readonly on it.)
As you have noticed, this won't happen if you create you object with a simple find, as the only attributes received from the query are from the object itself.
I don't know why you are eager loading all of this associations, maybe it is from some rule in your code, but you should try to create a simple owner object using Owner.find(params[:id]), and lazy loading the associations when needed, so this way you can build nested associations on the simple object and save them.

Grails: Is it possible to prevent a domain class instance from being persisted?

I want to create an (one) instance of a Domain class (which, as expected, has a GORM interface to my database) and only use it as a container to pass data around, like a Map object. I want to make absolutely sure that my instance is never going to get persisted in the database. I'm afraid that GORM, with all its cleverness, will somehow manage to save it in the database behind the scene even without an explicit call to save(). Is there a way to specify a "do not persist this" clause when instantiating my object? I know how to prevent persistence on a domain class, what I want is to prevent persistence on a particular instance of the class only.
The solution I have now is to create a class in groovy/src/ that carries the same properties and methods, and use it as my data container, and do type casts as required. It feels wrong, fails DRY, and hacky.
Of course you may also tell me that I should stop being so paranoid and that Grails is never going to persist an domain class instance without an explicit save.
Assume that, you already know how to prevent persistence(table creation) on a domain class. Furthermore, you also know that w/o explicit .save() object won't be persisted.
So, what do you want actually? Is it like.. even if someone accidentally call obj.save(), it will never persist.
Although that doesn't make any sense, but according to your query ,
Is there a way to specify a "do not persist this" clause when
instantiating my object?
Yes, there is a way :
class MyFishyDomain {
String pwd
// properties
// constraints
def beforeInsert() {
if (!this.pwd.equals("drago")) return false
}
def beforeUpdate () {
if (!this.pwd.equals("drago")) return false
}
}
Now..
new MyFishyDomain(pwd:"drago").save() // success
new MyFishyDomain(pwd:"rambo").save() // fail
By the way, if you want to permanently disable Create+Update+Delete But at the same time want to issue query against domain then solution is:
static mapping = {
cache usage: "read-only"
}
def beforeInsert() {
return false
}
Grails will not save an instance of your domain class without an explicit call to save() on the instance. You can create an instance and pass it around, and it will not be persisted.

Copy from one datasource to another in grails 2

I'm trying to use a domain that's configured for two datasources to copy data from one datasource to another. The documentation implies that this is straight-forward but I can only get it to save to the default datasource.
class LocalTransaction {
static mapping = {
datasources(['DEFAULT','migration'])
}
}
First I tried finding the transaction from the default datasource via LocalTransaction.findAllBy..(), then attempt to save changes via tr.migration.save(flush:true,failOnError:true) but the changes are saved to DEFAULT.
I think tried to create a new instance via LocalTransaction.migration.get(lt.id), copy the data over and then save, but that isn't saving to the migration datasource either.
Thanks,
Bill
Grails 2.0 has added support for multiple datasources to its core (this was formerly provided by a plugin). Please read the following section in the Grails documentation http://grails.org/doc/2.0.0.RC1/guide/conf.html#multipleDatasources
To save data in a specific datasource, you have to use its name before calling the save() closure, for example:
localTransactionObj.migration.save()
Hope that helps!

Creating new Objects With SPRING.Net

I'm new on spring.net, and I'm tring to create an List<> of objects.
The list is initialized by a loop that calls:
IObj obj= (IObj)ContextRegistry.GetContext().GetObject("obj")
change object properties....
add it to the list...
the problem is : I keep getting the same object every step of the loop
so I get a list of the same object
If your object definitions are not singletons, then you will get a new object each time. Note, by default, singleton is set to true, so you have to explicitly set it to false.
For example, if you are using xml files to configure your objects, set the singleton attribute to false:
<object name="name" type="..." singleton="false"/>
It is not clear what you are trying to achieve by looping over the "GetObject("obj")" method. Maybe you can post the loop-code?
What "GetObject("obj")" does is to ask the Container for the Object with the name "obj". You stated that want to change the object's properties and add it to a list. This is something the container can do for you:
Set the properties of an Object:
http://www.springframework.net/doc-latest/reference/html/objects.html#objects-simple-values
Create a list:
http://www.springframework.net/doc-latest/reference/html/objects.html#objects-collections-values
This list can be injected into an Object you choose.
If you just want non-singleton objects of your IObj, naders answer is correct. Spring calls these non-singleton objects "prototypes". An overview of available Scopes can be found here: http://www.springframework.net/doc-latest/reference/html/objects.html#objects-factory-scopes

Resources