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.
Related
I am writing this class, and noticed the anon function design you can use for small things.
String get fullName => "$fname $lname"; //A
and I got thinking on whether i should do my setters and getters in this fashion or the standard:
void setFullName( String fn, String ln ) { //B
fname = fn;
lname = ln;
}
String getFullName(){ //C
return "$fname $lname";
}
I know that the difference between A and C is that one is a method while the other is not.
print(fullName);
// vs
print(getFullName());
So, which approach is best. I was reading a demo that said anon functions should really only be used when the function has reason to change. I personally think that getters should be functions in teh traditional sense, but some things are pretty simple to just do shorthand.
If there is a shorthand for a getter like how i wrote A, is there a shorthand for a setter?
First in Dart fields are automatically wrapped by getters and setters. If you use reflection (mirrors) to query the members of a class, you'll get getters and setters instead of fields.
This is also reflected in the Dart style guide:
Don't wrap fields with getters/setters just to be sure.
You can change fields to getters/setters any time without breaking code that uses your class.
Other things to consider for getters/setters are: they shouldn't do expensive computation and they shouldn't have side-effects (except of setting the backing field when calling the setter).
If these criteria are met (and you don't need additional parameters), then it's usually a good idea to use getters/setters.
Note: short-hand function notation is not limited to getters/setters and they also don't require it. You can use it for functions as well and you can have block bodies for getters/setters as well.
bool _isSet;
bool get isSet {
return _isSet;
}
set isSet(bool value) {
if(value is null) {
throw new ArgumentError();
}
_isSet = value;
}
and you use them like
var myClass = new MyClass();
myClass.isSet = true; // setter
print(myClass.isSet); // getter
unnecessary_getters_setters
From the style guide:
AVOID wrapping fields in getters and setters just to be "safe".
In Java and C#, it's common to hide all fields behind getters and setters (or properties in C#), even if the implementation just forwards to the field. That way, if you ever need to do more work in those members, you can without needing to touch the callsites. This is because calling a getter method is different than accessing a field in Java, and accessing a property isn't binary-compatible with accessing a raw field in C#.
Dart doesn't have this limitation. Fields and getters/setters are completely indistinguishable. You can expose a field in a class and later wrap it in a getter and setter without having to touch any code that uses that field.
I have a very simple function which I define as follows:
def mySimpleFunction(Map myMap) {
// Function logic here...
}
However, when I try to compile this, I get a warning message and build exception which says that: The [mySimpleFunction] action accepts a parameter of type [java.util.Map] which has not been marked with Validateable.
How can I mark this function as Validateable? I imported the org.codehaus.groovy.grails.validation.Validateable
and have marked my class as #Validateable .
What should I be doing differently in order to get my application to build?
Thank you in advance!
If it is a helper method, make it private. In Grails 2.0+ public controller methods are assumed to be actions, and arguments are assumed to be bindable. That means they need to be number types, boolean, String, etc., or a command object class.
Command object classes are automatically made validateable if they're defined in the controller class file, and if they're defined elsewhere they need to be annotated as #Validateable.
Since this is a helper method and not an action, just make it private (especially since it can't be called from another class anyway):
private mySimpleFunction(Map myMap) {
// Function logic here...
}
When I'm displaying the properties with name user_id its perfectly showing. But If I want to display the values like "User_id " its prompting to cant find the property (NOMETHODFOUND EXCEPTION)
and also Inappropriate OGNL expression: (d - 49216) - s
This is not related to Struts2, and definitely not related to DisplayTag.
This is about OGNL and JavaBeans Naming Conventions.
As described in the JavaBeans PDF by SUN,
8.3 Design Patterns for Properties
8.3.1 Simple properties
By default, we use design patterns to locate properties by looking for methods of the form:
public <PropertyType> get<PropertyName>();
public void set<PropertyName>(<PropertyType> a);
If we discover a matching pair of “get<PropertyName>” and
“set<PropertyName>” methods that take and return the same type, then
we regard these methods as defining a read-write property whose name
will be “<propertyName>”. We will use the “get<PropertyName>”
method to get the property value and the “set<PropertyName>” method
to set the property value. The pair of methods may be located either
in the same class or one may be in a base class and the other may be
in a derived class.
If we find only one of these methods, then we regard it as defining
either a read-only or a writeonly property called “<propertyName>”
By default we assume that properties are neither bound nor constrained
(see Section 7).
So a simple read-write property “foo” might be
represented by a pair of methods:
public Wombat getFoo();
public void setFoo(Wombat w);
8.3.2 Boolean properties
In addition, for boolean properties, we allow a getter method to match
the pattern:
public boolean is<PropertyName>();
This “is<PropertyName>” method may be provided instead of a
“get<PropertyName>” method, or it may be provided in addition to a
“get<PropertyName>” method.
In either case, if the
“is<PropertyName>” method is present for a boolean property then we
will use the “is<PropertyName>” method to read the property value.
An example boolean property might be:
public boolean isMarsupial();
public void setMarsupial(boolean m);
Please read about Java Naming Conventions and CamelCase practice too.
That said, your property user_id (that should be named by convention userId), has a getter like public String getUser_id() (if it is a String, but an ID should not be a String);
this means that you get it from OGNL with "user_id", and not with "User_id".
If the result you are trying to achieve is to capitalize the CONTENT of user_id variable,
then you should go for another way (another getter with capitalized result, like getUser_idCapitalized, or a static call from OGNL to a funcion like WordUtils.capitalize(str) by Apache, like described here, etc...
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']
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.