Aggregations in gmongo 0.9.1 - grails

I need to implement some simple aggregations in my app powered by Grails 1.3.7. The mongodb-plugin of 1.0.0.RC3 ships with gmongo 0.9.1, where the aggregate functions are not implemented.
How can I solve the problem? Are there any hooks to call java-mongo API directly, or maybe there's some other plugin releases which allow aggregations?
TIA

It seems that Mongo aggregation apis exist since 2.1 here, probably you might need to upgrade your libraries.
Here is the mongodb plugin documentation which is talking about accessing low-level api. For grails 1.3.7 take at this blog for details on how to add more recent mongo libs into your Grails application and this post seems to have the same issue.
Hope it helps.

Aggregations only work in GMongo 1.0+.

Well, it seems to be impossible to do it with the existing gmongo/mongo-GORM. There are too many version clashes: different mongo java drivers, different groovy versions etc. I saw many ClassNotFoundExceptions and alike.
Luckily I don't need the aggregation functionality right now, so I'll just wait and upgrade to grails 2.x and mongo-GORM 1.3++ later

So, I made it!
with a little amount of the blood shed, I found a way to use aggregations in gmongo 0.9.1 / mongodb 1.0.0.RC3 / Grails 1.3.7!
HOWTO:
you need to replace the mongo-java-driver with a newer version (I used the most recent for now 2.9.3). In Grails it looks like:
dependencies {
compile 'org.mongodb:mongo-java-driver:2.9.3'
}
In BootStrap or in my case Plugin-descriptor add the following line:
DBCollectionPatcher.PATCHED_METHODS << 'aggregate'
The aggregation invocation looks like:
def res = Task.collection.aggregate( [ $group:[ _id:'totalTime', time:[ $sum:'$time' ] ] ], [] as DBObject ).results()
and it works like a charm!

Related

Is it possible to have different gorm versions in plugins within a grails 3 application?

I have a grails 3 application that makes heavy use of plugins. Some of these plugins provide domain classes. My application will not start unless every plugin has the same gorm version. This is an annoyance for locally developed plugins, but can be a significant problem for using third-party plugins.
There are more details in the stacktrace, but the relevant parts appear to be:
Caused by: org.grails.core.exceptions.GrailsRuntimeException: Failed to introspect class: class (my class name)
at grails.core.ArtefactHandlerAdapter.isArtefact(ArtefactHandlerAdapter.java:129)
at grails.core.DefaultGrailsApplication.addOverridableArtefact(DefaultGrailsApplication.java:772)
at org.grails.plugins.AbstractGrailsPluginManager.registerProvidedArtefacts(AbstractGrailsPluginManager.java:310)
I am currently using Grails 3.2.8 with GORM 6.1.3.RELEASE, but this happens with other non-matching versions for gorm as well.
If there is a better way to accomplish the bigger-picture goal, my big-picture goal is to use the grails ehcache plugin (currently at 3.0.0.M1) which requires gorm 6.1.x as a minimum. Per conversations on that plugin github site, there is no problem using gorm 6.1 with grails 3.2.x, though this is not the default.
Is there any way to run a grails 3 application, using plugins which provide domain objects, in which these plugins have different minor versions of gorm?
In case anyone else comes across this, the answer was basically "no".
The longer answer is "not as long as the groovy version is changing in non-backwards-compatible ways", and apparently that happens a lot.
There are some comments from Graeme here: https://github.com/grails/grails-core/issues/10693 but to summarize: you have to use the same version of gorm across plugins, and also make sure any third-party plugins you rely on are on the same version. This is only required for plugins that provide domain objects, at least!

Is there a straight-forward way of doing an ORM roundtrip workflow in Grails 3+?

For the last few years I have been a Symfony developer and one of the things I enjoy the most is the fact that I don't have to write/maintain entities by hand.
Through Doctrine (the integrated ORM) I can extract the table metadata and relations through
php app/console doctrine:mapping:import SomeBundle yaml
And then I can generate the ORM entity classes
php app/console generate:doctrine:entities SomeBundle
And I'm friggin' done.
Need to migrate?, no problem. Use this command to create a migration:
doctrine:migrations:diff
And the following to migrate to it:
doctrine:migrations:migrate
For Grails, it seems that there is no straight forward way, unless I go and download the Hibernate tools and a tool like Liquibase.
There seem to be a couple of plugins that did this, but the one for reverse engineering from a database does not seem supported for Grails 3 (db-reverse-engineer) and the one for migrations I tried, but does not seem stable enough (database-migration).
Am I just looking in the wrong place?, if not, how do you as a professional Grails developer solve these needs?
No there is not a straight forward way to make a "round-trip" as you describe in Grails 3.x.
Most plugins aren't going to be 3.x ready yet. 3.x is still quite new.
That said, the reverse engineering plugin isn't designed to be a fully automated one-shot handles everything type of plugin. It's suppose to be a running start that you take the last bit by hand.
The migration plugin on the other hand is fully production ready and very stable in 2.x.

Grails 3 does not have wrapper?

Does Grails 3.0.x no longer have the ability to create wrappers anymore?
The documentation doesn't seem to have the Grails wrapper section anymore.
Is there an alternative way which we can use the gradle wrapper to execute grails commands such as create-controller?
Does Grails 3.0.x no longer have the ability to create wrappers
anymore?
No.
Is there an alternative way which we can use the gradle wrapper to
execute grails commands such as create-controller?
Not for commands like create-controller, no.
We may re-introduce grailsw. File a feature request at https://github.com/grails/grails-core/issues if you would like to track that.
The Grails wrapper is back as of Grails 3.2.3:
http://docs.grails.org/3.2.x/guide/introduction.html#whatsNewGrailsWrapper
I have an app created with Grails 3.1.x, then upgraded to Grails 3.2.6, but the files such as 'grailsw' did not appear in my project root, and I'm not sure how to get them added via some command in the project.
When I create a new app using Grails 3.2.6, the new files are in the project root (grailsw, grailsw.bat, grails-wrapper.jar). I assume they can be copied over to an app like mine: a quick test of this worked for me.

Clustered cache in Grails 2.4.x

I need suggestions on cache clustering for Grails at the most recent version I can get.
I've been trying to set up Terracotta with Grails 2.4.4 but I can't manage to find a compatible version of its plugin (by the way, the Terracotta plugin page says it was last updated 6 years ago). Also I can't find any recent posts on cache clustering for grails.
I'm planning on using it also for session replication. I'm using Apache Shiro for authentication/authorization. But that shouldn't matter.
Ehcache has an embedded distributed solution based on RMI. I'm gonna give it a try but I'm not sure it'll work for web sessions in grails since the documentation says to use Terracotta.

Grails + Gpars.memoize().. how to do memoization?

I can't seem to figure out how to do memoization in Grails. According to the GPars docs it should be as simple as
def c = { x -> x*2 }.memoize() or ... .gmemoize()
But all i seem to get is compilation errors and stacktraces thrown. Has anyone successfully used gpars with grails?
Grails up until 1.4.0m1 bundled an old version of gpars (0.9) that didn't include memoization. Since Grails preferes the bundled libs to the user-specified ones, you never get a chance to see the memoization methods.
To my best knowledge the Grails master branch has already fixed that and gives users the freedom to choose a GPars version they like.
We are currently successfully using GPars data flow concurrency in a Grails 1.3.7 application. GPars is defined as a basic jar dependency in BuildConfig.groovy, we are not using the GPars Grails plugin.

Resources