Grails searchable plugin errors mapping hasMany - grails

I"m using 0.6.3 of searchable and grails-1.3.7. If I do not map the Domain hasMany properties thing work fine. However, if I map a hasMany property like the example in the documentation:
http://www.grails.org/Searchable+Plugin+-+Mapping+-+Class+Property+Mapping
comments component: true
or
keywords index: 'not_analyzed'
in the searchable closure, I get this error
2011-10-10 15:20:53,788 [main] ERROR context.GrailsContextLoader - Error executing bootstraps: Error creating bean with name 'compassGps': Cannot resolve reference to bean 'compass' while setting bean property 'compass'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'compass': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: Unable to map [com.ace.mws.servicetemplates.ServiceTemplate.services]. It does not appear to a suitable 'searchable property' (normally simple types like Strings, Dates, Numbers, etc), 'searchable reference' (normally another domain class) or 'searchable component' (normally another domain class defined as a component, using the 'embedded' declaration). Is it a derived property (a getter method with no equivalent field) defined with 'def'? Try defining it with a more specific return type
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'compassGps': Cannot resolve reference to bean 'compass' while setting bean property 'compass'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'compass': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: Unable to map [com.ace.mws.servicetemplates.ServiceTemplate.services]. It does not appear to a suitable 'searchable property' (normally simple types like Strings, Dates, Numbers, etc), 'searchable reference' (normally another domain class) or 'searchable component' (normally another domain class defined as a component, using the 'embedded' declaration). Is it a derived property (a getter method with no equivalent field) defined with 'def'? Try defining it with a more specific return type
at org.grails.tomcat.TomcatServer.start(TomcatServer.groovy:212)
at grails.web.container.EmbeddableServer$start.call(Unknown Source)
at grails.web.container.EmbeddableServer$start.call(Unknown Source)
at _GrailsRun_groovy$_run_closure5_closure12.doCall(_GrailsRun_groovy:158)
at _GrailsRun_groovy$_run_closure5_closure12.doCall(_GrailsRun_groovy)
at _GrailsSettings_groovy$_run_closure10.doCall(_GrailsSettings_groovy:280)
at _GrailsSettings_groovy$_run_closure10.call(_GrailsSettings_groovy)
at _GrailsRun_groovy$_run_closure5.doCall(_GrailsRun_groovy:149)
at _GrailsRun_groovy$_run_closure5.call(_GrailsRun_groovy)
at _GrailsRun_groovy.runInline(_GrailsRun_groovy:116)
at _GrailsRun_groovy.this$4$runInline(_GrailsRun_groovy)
at _GrailsRun_groovy$_run_closure1.doCall(_GrailsRun_groovy:59)
at _GrailsRun_groovy$_run_closure8_closure14.doCall(_GrailsRun_groovy:263)
at _GrailsRun_groovy$_run_closure8_closure14.doCall(_GrailsRun_groovy)
at _GrailsPackage_groovy$_run_closure8.doCall(_GrailsPackage_groovy:299)
at _GrailsPackage_groovy$_run_closure8.call(_GrailsPackage_groovy)
at _GrailsRun_groovy$_run_closure8.doCall(_GrailsRun_groovy:245)
at RunApp$_run_closure1.doCall(RunApp:35)
at gant.Gant$_dispatch_closure5.doCall(Gant.groovy:381)
at gant.Gant$_dispatch_closure7.doCall(Gant.groovy:415)
at gant.Gant$_dispatch_closure7.doCall(Gant.groovy)
at gant.Gant.withBuildListeners(Gant.groovy:427)
at gant.Gant.this$2$withBuildListeners(Gant.groovy)
at gant.Gant$this$2$withBuildListeners.callCurrent(Unknown Source)
at gant.Gant.dispatch(Gant.groovy:415)
at gant.Gant.this$2$dispatch(Gant.groovy)
at gant.Gant.invokeMethod(Gant.groovy)
at gant.Gant.executeTargets(Gant.groovy:590)
at gant.Gant.executeTargets(Gant.groovy:589)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'compass': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: Unable to map [com.ace.mws.servicetemplates.ServiceTemplate.services]. It does not appear to a suitable 'searchable property' (normally simple types like Strings, Dates, Numbers, etc), 'searchable reference' (normally another domain class) or 'searchable component' (normally another domain class defined as a component, using the 'embedded' declaration). Is it a derived property (a getter method with no equivalent field) defined with 'def'? Try defining it with a more specific return type
... 29 more
Caused by: java.lang.IllegalArgumentException: Unable to map [com.ace.mws.servicetemplates.ServiceTemplate.services]. It does not appear to a suitable 'searchable property' (normally simple types like Strings, Dates, Numbers, etc), 'searchable reference' (normally another domain class) or 'searchable component' (normally another domain class defined as a component, using the 'embedded' declaration). Is it a derived property (a getter method with no equivalent field) defined with 'def'? Try defining it with a more specific return type
at grails.plugin.searchable.internal.compass.mapping.ClosureSearchableGrailsDomainClassCompassClassMapper.invokeMethod(ClosureSearchableGrailsDomainClassCompassClassMapper.groovy:217)
at com.ace.mws.servicetemplates.ServiceTemplate$__clinit__closure1.doCall(ServiceTemplate.groovy:6)
at com.ace.mws.servicetemplates.ServiceTemplate$__clinit__closure1.doCall(ServiceTemplate.groovy)
at grails.plugin.searchable.internal.compass.mapping.ClosureSearchableGrailsDomainClassCompassClassMapper.searchableGetCompassClassPropertyMappings(ClosureSearchableGrailsDomainClassCompassClassMapper.groovy:97)
at grails.plugin.searchable.internal.compass.mapping.ClosureSearchableGrailsDomainClassCompassClassMapper.this$3$searchableGetCompassClassPropertyMappings(ClosureSearchableGrailsDomainClassCompassClassMapper.groovy)
at grails.plugin.searchable.internal.compass.mapping.ClosureSearchableGrailsDomainClassCompassClassMapper.getCompassClassMapping(ClosureSearchableGrailsDomainClassCompassClassMapper.groovy:129)
at grails.plugin.searchable.internal.compass.mapping.CompositeSearchableGrailsDomainClassCompassClassMapper.getCompassClassMapping(CompositeSearchableGrailsDomainClassCompassClassMapper.java:93)
at grails.plugin.searchable.internal.compass.mapping.AbstractSearchableGrailsDomainClassCompassClassMapper.getCompassClassMapping(AbstractSearchableGrailsDomainClassCompassClassMapper.java:52)
at grails.plugin.searchable.internal.compass.config.mapping.SearchableClassPropertySearchableGrailsDomainClassMappingConfigurator.configureMappings(SearchableClassPropertySearchableGrailsDomainClassMappingConfigurator.java:80)
at grails.plugin.searchable.internal.compass.config.DefaultGrailsDomainClassMappingSearchableCompassConfigurator.configure(DefaultGrailsDomainClassMappingSearchableCompassConfigurator.java:131)
at grails.plugin.searchable.internal.compass.config.CompositeSearchableCompassConfigurator.configure(CompositeSearchableCompassConfigurator.java:39)
at grails.plugin.searchable.internal.compass.spring.SearchableCompassFactoryBean.buildCompass(SearchableCompassFactoryBean.java:93)
at grails.plugin.searchable.internal.compass.spring.SearchableCompassFactoryBean.getObject(SearchableCompassFactoryBean.java:58)
... 29 more

This is a known issue. The popular workarounds are either not mapping the hasMany fields (as you mentioned) or using merge(flush:true) on your object instance before save(flush:true) is called. I found not mapping the hasMany fields to be more effective and less of a headache since using merge(flush:true) can cause duplicate objects in some situations and also requires you manually maintain the search index. Read more about the issue here.

Related

Deploying Grails application on Glassfish 4 error

i'm trying to deploy Grails application on Glassfish 4 but it was failed and got the below error :
Exception Occurred :Error occurred during deployment: Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManagerPostProcessor': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager': Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Invocation of init method failed; nested exception is org.hibernate.cache.NoCacheRegionFactoryAvailableException: Second-level cache is used in the application, but property hibernate.cache.region.factory_class is not given; please either disable second level cache or set correct region factory using the hibernate.cache.region.factory_class setting and make sure the second level cache provider (hibernate-infinispan, e.g.) is available on the classpath.. Please see server.log for more details.]]
I can't figure out what is causing this error , i tried on google but nothing useful
in the DataSource.groovy commented driverClassName and dialect in the whole file , in the production section i commented URL and used instead the URL the jndiName and was deployed on GlassFish successfully without the previous error . Hope this workaround helps others
The root cause of error is related to hibernate cache configuration:
Invocation of init method failed; nested exception is org.hibernate.cache.NoCacheRegionFactoryAvailableException:
Second-level cache is used in the application, but property hibernate.cache.region.factory_class is not given;
please either disable second level cache or set correct region factory using the hibernate.cache.region.factory_class setting and make sure the second level cache provider (hibernate-infinispan, e.g.) is available on the classpath..
I would suggest to review/compare cache setting and check cache provider.

Using #TestFor in unit test for bean that uses constructor arguments throws an error (Grails 2.0.0RC1)

I'm trying to create a unit test for a service class that uses a constructor argument. I have already configured an entry in the grails-app/conf/spring/resources.groovy to allow Spring to create the bean using the constructor argument.
Running an integration test for the service class works without problem, however, running a unit test that uses #TestFor, the following exception shows up:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sampleService': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [ph.jojopad.SampleService]: No default constructor found; nested exception is java.lang.NoSuchMethodException: ph.jojopad.SampleService.<init>()
at grails.test.mixin.services.ServiceUnitTestMixin.mockService(ServiceUnitTestMixin.groovy:54)
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [ph.jojopad.SampleService]: No default constructor found; nested exception is java.lang.NoSuchMethodException: ph.jojopad.SampleService.<init>()
Caused by: java.lang.NoSuchMethodException: ph.jojopad.SampleService.<init>()
It seems that #TestFor only expects a bean that uses the default constructor. Looking at the documentation of Grails I can't find any references on how to use #TestFor for beans with constructor arguments. I was expecting that with the correct bean configuration at grails-app/conf/spring/resources.groovy would do the trick.

grails - error executing bootstrap (Error creating bean with name 'messageSource')

I made some seemingly harmless changes (added a few domain classes, added the plugin shopping-cart), and now apparently the BootStrap.groovy class doesn't execute at all.
While I made a few changes to BootStrap.groovy, I restored a previously good file that works fine, dumbfounded by the error. Also, in the good (old) BootStrap.groovy, I put some println statements at the top of the init action, but those aren't printing out and don't seem to even be reached. Finally, I did an uninstall of the plugin, and after that, deleted the shopping-cart plugin folder manually.
Do you know what this error is, or have any debug guidance? (am running Grails 1.3.7)
Running Grails application..
Configuring Spring Security ...
Configuring Spring Security UI ...
2011-12-09 13:51:33,036 [main] ERROR context.GrailsContextLoader -
Error executing bootstraps: Error creating bean with name
'messageSource': Initialization of bean failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'transactionManager': Cannot resolve reference
to bean 'sessionFactory' while setting bean property 'sessionFactory';
nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'sessionFactory': Invocation of init method
failed; nested exception is org.hibernate.MappingException: Type
[null] is not a basic type or a domain class and cannot be mapped.
Either specify a type within the [mapping] block or use a basic type
(String, Integer etc.)
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'messageSource': Initialization of bean
failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'transactionManager': Cannot resolve reference
to bean 'sessionFactory' while setting bean property 'sessionFactory';
nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'sessionFactory': Invocation of init method
failed; nested exception is org.hibernate.MappingException: Type
[null] is not a basic type or a domain class and cannot be mapped.
Either specify a type within the [mapping] block or use a basic type
(String, Integer etc.) at
org.grails.tomcat.TomcatServer.startSecure(TomcatServer.groovy:289)
at grails.web.container.EmbeddableServer$startSecure.call(Unknown
Source) at
_GrailsRun_groovy$_run_closure5_closure12.doCall(_GrailsRun_groovy:152)
at
_GrailsRun_groovy$_run_closure5_closure12.doCall(_GrailsRun_groovy) at
_GrailsSettings_groovy$_run_closure10.doCall(_GrailsSettings_groovy:280)
at _GrailsSettings_groovy$_run_closure10.call(_GrailsSettings_groovy)
at _GrailsRun_groovy$_run_closure5.doCall(_GrailsRun_groovy:149) at
_GrailsRun_groovy$_run_closure5.call(_GrailsRun_groovy) at _GrailsRun_groovy.runInline(_GrailsRun_groovy:116) at _GrailsRun_groovy.this$4$runInline(_GrailsRun_groovy) at _GrailsRun_groovy$_run_closure2.doCall(_GrailsRun_groovy:66) at RunApp$_run_closure1.doCall(RunApp.groovy:30) at
gant.Gant$_dispatch_closure5.doCall(Gant.groovy:381) at
gant.Gant$_dispatch_closure7.doCall(Gant.groovy:415) at
gant.Gant$_dispatch_closure7.doCall(Gant.groovy) at
gant.Gant.withBuildListeners(Gant.groovy:427) at
gant.Gant.this$2$withBuildListeners(Gant.groovy) at
gant.Gant$this$2$withBuildListeners.callCurrent(Unknown Source) at
gant.Gant.dispatch(Gant.groovy:415) at
gant.Gant.this$2$dispatch(Gant.groovy) at
gant.Gant.invokeMethod(Gant.groovy) at
gant.Gant.executeTargets(Gant.groovy:590) at
gant.Gant.executeTargets(Gant.groovy:589) at
com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'transactionManager': Cannot resolve
reference to bean 'sessionFactory' while setting bean property
'sessionFactory'; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'sessionFactory': Invocation of init method
failed; nested exception is org.hibernate.MappingException: Type
[null] is not a basic type or a domain class and cannot be mapped.
Either specify a type within the [mapping] block or use a basic type
(String, Integer etc.) ... 24 more Caused by:
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'sessionFactory': Invocation of init method
failed; nested exception is org.hibernate.MappingException: Type
[null] is not a basic type or a domain class and cannot be mapped.
Either specify a type within the [mapping] block or use a basic type
(String, Integer etc.) ... 24 more Caused by:
org.hibernate.MappingException: Type [null] is not a basic type or a
domain class and cannot be mapped. Either specify a type within the
[mapping] block or use a basic type (String, Integer etc.) ... 24
more
Process finished with exit code 1
I removed all the new domain classes and references to them, and the error went away. I'll update this as soon as I figure out what the problem is, hopefully not related to a domain change to one of the Spring Security classes (User).
Ok, the problem is/was, I had an enum declaration at the top of one of the domain classes I added. If I move the enum declaration below the class declaration, then all is good. I imagine this is a hibernate error / problem?
I would guess that you have a problem in one of your domain classes where you use a "def" or some other invalid type in the domain class for one of the fields.

Possible to create a domain class that is NOT mapped to a database table?

I'm using Grails 1.2.1. I'm converting a Java app to a Grails app and I had a Java object that I thought I'd create a grails domain for. However, the object does not rely on an underlying database table. When I startup my app, I'm getting the error,
ERROR context.ContextLoader - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'messageSource': Initialization of bean
failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'transactionManager': Cannot resolve reference
to bean 'sessionFactory' while setting bean property 'sessionFactory';
nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'sessionFactory': Invocation of init method
failed; nested exception is org.hibernate.MappingException: Could not
determine type for: java.io.InputStream, at table:
http_cache_response, for columns: [org.hibernate.mapping.Column(body)]
Am I misusing the domain? Should this object just be a regular class in src/groovy? Thanks, - Dave
Yes, domain objects are specifically database-mapped objects. Not domain in the DDD sense.
Depending on if the class is a singleton or not it should either be a service or a class in src/groovy.
It's possible to create a class that does not have an underlying domain object. There are 2 cases:
You want an object to use in Controller, you may create a Command Object.
If you want to create a pure java or groovy class, you can create it in src/java or src/groovy.
You might want to check out mapWith property of domain classes:
static mapWith = "none" should do the trick
I would say if your not going to use the class as a grails style domain object, it's better to put it in src/java and use them like any other class.

Groovy Mixins?

I'm trying to mix-in a class in my Groovy/Grails app, and I'm using the syntax defined in the docs, but I keep getting an error.
I have a domain class that looks like this:
class Person {
mixin(ImagesMixin)
// ...
}
It compiles fine, but for some reason it won't work. The file containing ImagesMixin is located in my /src/groovy/ directory.
I've tried it using Groovy versions 1.5.7 and 1.6-RC1 without any luck. Does anyone know what I'm doing wrong?
stacktrace:
2008-12-30 17:58:25.258::WARN: Failed startup of context org.mortbay.jetty.webapp.WebAppContext#562791{/FinalTransmission,/home/kuccello/Development/workspaces/lifeforce/FinalTransmission/web-app}
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'pluginManager' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is java.lang.ExceptionInInitializerError
at java.security.AccessController.doPrivileged(Native Method)
at RunApp_groovy$_run_closure2_closure7.doCall(RunApp_groovy:67)
at RunApp_groovy$_run_closure2_closure7.doCall(RunApp_groovy)
at Init_groovy$_run_closure6.doCall(Init_groovy:131)
at RunApp_groovy$_run_closure2.doCall(RunApp_groovy:66)
at RunApp_groovy$_run_closure2.doCall(RunApp_groovy)
at RunApp_groovy$_run_closure1.doCall(RunApp_groovy:57)
at RunApp_groovy$_run_closure1.doCall(RunApp_groovy)
at gant.Gant.dispatch(Gant.groovy:271)
at gant.Gant.this$2$dispatch(Gant.groovy)
at gant.Gant.invokeMethod(Gant.groovy)
at gant.Gant.processTargets(Gant.groovy:436)
at gant.Gant.processArgs(Gant.groovy:372)
Caused by: java.lang.ExceptionInInitializerError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
at Episode.class$(Episode.groovy)
at Episode.<clinit>(Episode.groovy)
... 13 more
Caused by: groovy.lang.MissingMethodException: No signature of method: static Person.mixin() is applicable for argument types: (java.lang.Class) values: {class ImagesMixin}
at Broadcast.<clinit>(MyClass.groovy:17)
... 17 more
2008-12-30 17:58:25.259::WARN: Nested in org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'pluginManager' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is java.lang.ExceptionInInitializerError:
groovy.lang.MissingMethodException: No signature of method: Person.mixin() is applicable for argument types: (java.lang.Class) values: {class ImagesMixin}
at Broadcast.<clinit>(Person.groovy:17)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
at Episode.class$(BelongsToMyClass.groovy)
at Episode.<clinit>(BelongsToMyClass.groovy)
at java.security.AccessController.doPrivileged(Native Method)
at RunApp_groovy$_run_closure2_closure7.doCall(RunApp_groovy:67)
at RunApp_groovy$_run_closure2_closure7.doCall(RunApp_groovy)
at Init_groovy$_run_closure6.doCall(Init_groovy:131)
at RunApp_groovy$_run_closure2.doCall(RunApp_groovy:66)
at RunApp_groovy$_run_closure2.doCall(RunApp_groovy)
at RunApp_groovy$_run_closure1.doCall(RunApp_groovy:57)
at RunApp_groovy$_run_closure1.doCall(RunApp_groovy)
at gant.Gant.dispatch(Gant.groovy:271)
at gant.Gant.this$2$dispatch(Gant.groovy)
at gant.Gant.invokeMethod(Gant.groovy)
at gant.Gant.processTargets(Gant.groovy:436)
at gant.Gant.processArgs(Gant.groovy:372)
2008-12-30 17:58:25.271::INFO: Started SelectChannelConnector#0.0.0.0:8080
Since Groovy 1.6 you can either apply a mixin at compile-time to a class using an annotation
#Mixin(ImagesMixin)
class Person {
}
Or you can apply the mixin at runtime like this:
def myMixin = ImagesMixin
Person.mixin myMixin
The latter approach is more dynamic as the class to mixin can be determined at runtime. Further information about Groovy mixins is available here.
In my experience, a lot of meta-programming of domain classes simply doesn't work. I don't exactly know why, but suspect it's due to the fact these classes are already very heavily meta-programmed by the Grails runtime. In general my approach is
Try the meta-programming on a POGO in the Groovy console
If that works, try it on a non-domain class in the Grails console
If that works, try it on a domain class in the Grails console. If it doesn't work, then it must be because it's a domain class (rather than a problem with the syntax). At this point it's advisable to try and find another way of accomplishing your goal. If that's not possible, then use a combination of the Grails mailing list and/or Stackoverflow and/or the Grails source code to try and get the meta-programming working.
I don't think you are using the proper mixin syntax. Try this:
class MyMixin {
static doStuff(Person) {
'stuff was done'
}
}
class Person {}
Person.mixin MyMixin
new Person().doStuff()
I guess what you've seen there is rather a proposal than a feature ;) Groovy does not support mixins out of the box in this way yet (if ever). But there is a 3rd party lib that can be used to emulate such a behavour: Injecto. And mixins can be defined using AST-Macros in the 1.6 version of Groovy (which is not final yet).
You should always check if your're reading the docs from the real groovy project or from the GroovyJSR project (which is rather a place where proposals are collected).
Another way is to use plain-old MOP to inject behaviour into groovy classes by modifying metaClasses.
Cheers
In case this helps anyone, Following on from #virtualeyes comment above, I've found that
Person.doStuff()
fails unless you call the following first:
new Person().doStuff()
Person.doStuff()
after which, the static method on the class does seem to work (for me, using Grails 2.2.4) I guess it's to do with initialising the class, or something, but I tried:
Person.metaClass.initialize()
Person.doStuff()
and that didn't work!
FYI: There is such a thing as "embedded" domains in Grails now, but it has problems. This is where you can logically include one domain as part of another and have its fields all occur physically in the one DB table. For example, if you find that you have the same subset of fields appearing in multiple tables, like street address/city/state/zip, you could define a StreetAddress domain and embed it. One of the current problems is that Grails will still create a street_address table in addition to embedding its fields in the other tables (unless you play tricks). There are submitted patches pending for this, it seems.
Grails domain objects are already heavily meta-programmed.
Instead of the groovy mixin try:
#grails.util.Mixin(ImagesMixin)
class Person {
}
Use Traits!
Traits are the reason they removed support for mixins, because that are just better. They're basically abstract classes that are implemented. Allowing you to use multiple and operate them as partial classes.
trait A {
void printSomething() {
println "foobar"
}
}
class B implements A {
void printAnything() {
printSomething()
}
}
new B().printAnything()
Try it out!

Resources