Is there a list of forbidden method names for Grails domain objects? - grails

Often as I add a helper method to a domain object I get an error when compiling which resolves to "x property is not found". This seems to happen for methods name getX, setX, and also recently isX. Is there a list of name forms that I should avoid? Is there a way to annotate or otherwise label these methods so Grails doesn't confuse them with auto properties?

Grails autodetects properties and assumes that they're persistent. Public fields in Groovy create a getter and setter under the hood so getters are assumed to be associated with persistent fields.
But if you want a helper method that starts with 'get' or 'is' but isn't a getter for a persistent field, you have two options. One is to use the transients list - see http://grails.org/doc/latest/ref/Domain%20Classes/transients.html
The other option is to declare the return value as def. Since it's not typed (def is an alias for Object) Hibernate can't persist it since it doesn't know what data type to use, so it's ignored.
My preference is the transients list because I would rather have self-documenting methods where it's obvious what they do, what parameter types they accept, and what they return.

I have no idea of common list - it's too diverse. Convention methods are added by different parts of Groovy and Grails:
Groovy convention about property getters/setters is very basic thing. It's impossible have a getX() method and not have read access to x property.
Grails domain class dynamic methods and Domain class convention properties are specific to Grails domain classes;
Same for controllers, and so on;
Groovy convention about property getters/setters, including methodMissing, propertyMissing, $staticMethodMissing, getProperty, properties and so on;
Groovy adds a number of as<Type>() methods, like asInteger();
different plugins could inject more convention methods.
To access declared field, not getter/setter, use java field access operator.

As far as I understand your problem, you can use transient !
static transients = ['feildName']

Related

Does Hibernate read domain object instance field directly or uses getter method while saving?

I am on grails 3.3.6, Gorm 6 and Hibernate 5.x and observing that a domain object instance field is read directly instead of from a getter method if present while saving. for e.g.
instance field
String accountStatus is read directly instead of invoking getAccountStatus().
Can someone confirm this
Thanks
Shiraz
According to Groovy documentation:
In Groovy, getters and setters form what we call a "property", and offers a shortcut notation for accessing and setting such properties. The getters and setters are generated dynamically by the compiler. Unless you want to override the defaults, then you can, of course, customise your own:
instance.accountStatus
//Groovy's syntax for:
instance.getAccountStatus()
Using getter and setters in grails or not?

Accessing field annotations on Grails domain classes

I'm trying to annotate fields over my domain classes but I'm not able to get them at runtime by reflection as usual Java fields.
My annotated domain class looks like:
class MyDomainClass {
#MyAnnotation
String myField
}
The Java way to access myField by reflection doesn't work:
MyDomainClass.class.getField("myField") //throws java.lang.NoSuchFieldException
The Grails way to inspect domain classes doesn't expose field annotations:
new DefaultGrailsDomainClass(MyDomainClass).getPersistentProperty("myField").??? //there is nothing similar to getAnnotations()
How can I retrieve the annotations associated with a domain field?
That's not a field, it's a property. When you declare a class-scope variable like that with no scope modifier (public, protected, etc.) in a Groovy class, the Groovy compiler converts it to a private field with the same type and name, and a getter and setter method, essentially
class MyDomainClass {
#MyAnnotation
private String myField
public String getMyField() {
return myField
}
public void setMyField(String s) {
myField = s
}
}
It won't overwrite an existing getter or setter though.
When you access the property you end up calling the getter or setter, which you can see if you add those methods and include println statements. This way Java classes can access the property via those methods, and Groovy pretends that you're directly reading or writing a field but under the hood you end up calling the same methods that you would from Java.
One benefit of this is that if you decide later that you want to add some logic when setting or getting the value, you can define the corresponding method(s) and add what you want without needing to change the code that accesses the property since in Groovy you can still treat it like a field and your custom methods will be called, and Java classes will have been calling the setter and getter all along.
getFields() returns only public fields, but getDeclaredFields() returns all of them, so since the actual field is private that's why getDeclaredFields() (or the property access form declaredFields) is necessary.
Grails doesn't use annotations because Graeme (and others) feel that they're ugly and bulky, not because they're not accessible.

Domain class variables

How do domain classes in Grails have variables like static constraints ={ }?
I can't see any direct inheritance.
I guess it's meta-programming but can you explain this?
In Grails domain classes don't extend a framework-provided base class, this is consistent with how persistent entities work in Hibernate.
Also be aware that static methods don't get inherited anyway, and no fields get inherited. The mapping and constraints variables are static fields declared on the domain class. Inheritance doesn't apply here.
Grails knows which classes are domain classes, services, controllers, etc. based on where their files are in the project structure. Grails knows to look for static variables in the domain objects named constraints and mapping.
This much is leveraging of conventions, not meta-programming. Meta-programming would be involved in implementing the DSL for the entries in those closures, and in adding GORM methods to the domain classes.

Distinguishing between Grails domain-class fields and getBlah() methods via GrailsDomainClassProperty

I'm writing a Groovy script (as part of a Grails plugin) and I want to get a list of properties for a GrailsDomainClass that a user of my plugin might define. I can do this using domainClass.properties (where domainClass is a GrailsDomainClass).
However, suppose a user has the grails domain class:
class Example {
String name
static constraints = {
}
def getSomeNonExistingProperty(){
return "Not-a-real-property"
}
}
In this case, domainClass.properties returns a list with both name and someNoneExistingProperty
I understand that this is because of Grails is generating a read-only property on-the-fly for use where someone has a getBlah() method. That's great, but in my script I want to perform some actions with the "real" properties only (or at least non read-only properties).
That is, I would like some way of distinguishing or identifying someNonExistingProperty as a read-only property, or, alternatively, as a property generated by Grails and not entered explicitly as a field in the domainClass by the user of my plugin.
I've looked at the GrailsDomainClassProperty Class and it has a range of methods providing information about the property. However, none of them appear to tell me whether a property is read-only or not, or to allow me to distinguish between a field defined in the domainClass and a field created on-the-fly by Grails as a result of a "getSomeNonExistingProperty()" method.
Am I missing something obvious here? Is there a way of getting a list of just the explicitly user-defined fields (eg name, in the above example)?
I believe transient properties are what you are trying to exclude
I've run into this problem a few times, and instead of trying to work around it I typically just end up renaming my getX() method. It's probably the easiest option.
Edit:
Alternatively, I wonder if you could use reflection to see which methods are defined on the class, and while iterating over your properties see if the property has an explicit getter defined, and omit it. I'm not very familiar with reflection when it comes to Groovy and Grails, especially with the dynamic methods, but it's a possible route of investigation.

Techniques for dependency injection into a domain model

I have a domain model type. One of its numerous properties requires an ITranslationService to provide the ability to translate its return value into the appropriate language.
Should I inject the ITranslationService into the constructor of the domain model type (thereby having to alter everywhere the type is instantiated and having to be concerned about initialisation when retrieved via NhIbernate), even though it is used by a tiny part of the type (one of many properties); or is there another functional pattern I can use?
Does anyone have any relevant experience they can share?
I would not expect the domain object to do the translation - instead, use the translation service with the domain object (or the relevant property value) as a parameter, and return the translated value. For example, you could simply do
var translatedString = yourServiceInstance.Translate(theDomainObject.Property);
Should I inject the
ITranslationService into the
constructor of the domain model type
Yes, that may make sense, depending on your situation. If you would always avoid the injection of services into entities, then that might lead to an anemic domain model which is an anti-pattern.
Code which needs to instantiate entities can be shielded from the extra constructor argument by using a factory, which takes care of the dependency injection.
NHibernate can also inject services into an entity via the constructor: http://fabiomaulo.blogspot.com/2008/11/entities-behavior-injection.html

Resources