java Annotation reflection - java

I have a java class, for some field (not all field), I will put an annotation for the filed. Now, I would like to find all the fields which have annotation?
I know, I can iterate all fields, and find whether the field has annotation.
Since there is only one or two field has annotation, so I would like a quick method to find such annotated field.

I don't know any way quicker than iterating over all the fields. Given that anything else would require some other piece of code to iterate over all the fields first and store the annotations in a form more optimized for your use case - which certainly won't be useful for all annotations - I wouldn't expect there to be anything provided for you.
Have you benchmarked the speed of just iterating over the fields, and found it too slow? If you only need to do this occasionally, it's probably fast enough as it is. If you need to do it multiple times on the same class, then you can create a cache for this yourself, so you only ever need to iterate over the fields of any particular class once.

Related

Does adding redundant #JsonProperty value annotations to fields increase deserialization performance?

I'm using Jackson (2.6.0) to deserialize JSON requests into simple POJOs. I have implemented all the setter methods in my POJOs to fine tune the assignment. Some of the field names in the JSON are rather cryptic, such as seq. I'd like to name my java class field something like layoutSequnce.
I'm aware to do this I simply need to annotate my field as:
#JsonProperty("seq")
private int layoutSequence;
My question is for JSON fields I do not needto rename, such as title, is there any minimal performance advantage to annotating it anyway as:
#JsonProperty("title")
private String title;
My question stems from my understanding of how I think Jackson works behind the scenes. I'm assuming Jackson uses reflection to introspectively examine my POJO and identify the current field it's attempting to assign from the JSON value. With this approach, I'm assuming it has to do some searching to find a match, which has some small amount of overhead.
If I specify the field name directly, will Jackson just blindly attempt to initialize my field using a setter that matches the pattern of the field name (setTitle() in this example) I've identified in the annotation? Or does it still perform an internal class search to validate the method's existence?
No, it should not improve performance. Introspection is only done once, to build the JsonDeserializer, and never after this initial time.
Annotation introspection (or even just general field, method introspection) is rather expensive operation, and so serializers/deserializers are aggressively cached to avoid having to do it more than once.
The only case where lookups would need to be repeated are when constructing a new ObjectMapper, that is, when not reusing/sharing small numbers (ideally one) of mappers.
ObjectReaders are different in that there is very little overhead, as they share cached deserializers with ObjectMapper that created them, so there is no need to reuse them. But mappers need to be reused.

How to make Hibernate ignore a method?

This question is essentially the opposite of this one.
I have a method like so:
public boolean isVacant() {
return getEmployeeNum() != null && getEmployeeNum().equals("00000000");
}
When I load it up, Hibernate is complaining that I have no attribute called vacant. But I don't want an attribute called vacant - I have no need to store that data - it's simply logic.
Hibernate says:
org.hibernate.PropertyNotFoundException: Could not find a setter for property vacant in class com.mycomp.myclass...
Is there an annotation I can add to my isVacant() method to make Hibernate ignore it?
Add #Transient to the method then Hibernate should ignore it.
To quote the Hibernate Documentation:
Every non static non transient property (field or method depending on the access type) of an entity is considered persistent, unless you annotate it as #Transient.
RNJ is correct, but I might add why this happens:
I'm guessing that you have annotated the getters of your persistent class. The prefixes used by java beans are "set" and "get", which are used do read and write to variables, but there is also the prefix "is", which is used for boolean values (instead of "get"). When Hibernate sees your getter-annotated persistent class, and finds a method "isVacant", it assumes that there is a property "vacant", and assumes that there is a "set"-method as well.
So, to fix it, you could either add the #Transient annotation, or you could change the name of your method to something that doesn't start with "is". I don't think this would be a problem if your class was annotated on the fields, instead of the get-methods.
Many frameworks (like Hibernate and Drools) are smart enough understand that Boolean variables need to be accessed by "is" instead of "get". But they don't always understand perfectly, and that is when "interesting" problems can develop. Or, worse yet, the different frameworks interpret the methods slightly differently, and they are supposed to work together.
BTW, the #Transient solution is not guaranteed to solve all your problems. Most notably, say that you are adding it to a toString() that returns a huge and complex object. You might be getting a stack overflow not because the method is huge and complex, or even because all the sub-obejcts have their own toString() methods, but because your structure has circular structures. That is what causes the stack overflows.

How to use reflection to retrieve private variable property from JPA objects

One of my goals is to create an engine that will set values in pojo object from JPA objects dynamically using reflection. One of the matching criteria is, that the field names should match.
I was successfully able to implement this for two pojo objects. But when I tried using JPA objects as one of the object parameter, it didn't work. Based on my research I found out that the method Class.getDeclaredFields() , does not give me the name of the field but the getter/setter method name of member variable for JPA objects.
Can anyone please give me a lead or direction as in where/what should I look to accomplish this task?
JPA providers will often use dynamic proxy classes of your concrete JPA classes, so you have no guarantee of the field names in the proxy. The only guarantee about a proxy is that the methods are the same. Use a debugger to inspect the runtime class of the JPA class instances that you're trying to use and you'll see the problem.
The best you'll be able to do is use reflection to call methods on JPA-returned objects.
All that aside, I don't really see why you'd need to POJO-ify an entity class anyway, since an entity is primarily an annotated... POJO.
One of the matching criteria is, that the field names should match.
I think that this is the root of your problem. There is simply no guarantee that a Java object's field names will match the names of getters and setters ... or anything else. If you make this assumption, you will run into cases where is doesn't work.
The best solution is to simply not use this approach. Make it a requirement that the Pojo classes conform to the JavaBeans spec and rely on the setters to set the properties. This is likely to work more often than making assumptions about (private) field names.
In fact, the state of a generic JPA object implemented using a dynamic proxies could well be held in a hash map. Those fields you can see could simply be constants used for something else.

Structural design pattern

I'm working with three separate classes: Group, Segment and Field. Each group is a collection of one or more segments, and each segment is a collection of one or more fields. There are different types of fields that subclass the Field base class. There are also different types of segments that are all subclasses of the Segment base class. The subclasses define the types of fields expected in the segment. In any segment, some of the fields defined must have values inputted, while some can be left out. I'm not sure where to store this metadata (whether a given field in a segment is optional or mandatory.)
What is the most clean way to store this metadata?
I'm not sure you are giving enough information about the complete application to get the best answer. However here are some possible approaches:
Define an isValid() method in your base class, which by default returns true. In your subclasses, you can code specific logic for each Segment or FieldType to return false if any requirements are missing. If you want to report an error message to say which fields are missing, you could add a List argument to the isValid method to allow each type to report the list of missing values.
Use Annotations (as AlexR said above).
The benefit of the above 2 approaches is that meta data is within the code, tied directly to the objects that require it. The disadvantage is that if you want to change the required fields, you will need to update the code and deploy a new build.
If you need something which can be changed on the fly, then Gangus suggestion of Xml is a good start, because your application could reload the Xml definition at run-time and produce different validation results.
I think, the best placement for such data will be normal XML file. And for work with such data the best structure will be also XMLDOM with XPATH. Work with classes will be too complicated.
Since java 5 is released this kind of metadata can be stored using annotations. Define your own annotation #MandatoryField and mark all mandatory fields with it. Then you can discover object field-by-field using reflection and check whether not initiated fields are mandatory and throw exception in this case.

Using annotation for an object sorter?

I am working a container to hold a list of objects (of the same class) the have certain fields that use a custom RetentionSortable annotation. The purpose of the annotation is two fold:
To mark the field as able to be compared to another objects same field.
And to give the sort name of the field (eg. Modification Date or First Name).
The container will then walk through the list of objects (remember they are like) and gather the list of RententionSortable's that the object contains and pass the list to the GUI. The GUI will display the list and request a sortable selection and return it to the sortable which will then sort the list based on the RetentionSortable selected.
The purpose of this method or sorting object is to allow me to create a small container that can generically accept any object and sort it as long as it has at least one RetentionSortable field.
My gut screams that this is bad practice and that relying this much on reflection is a bad idea but my tests work flawlessly and better than I expected.
Is using annotation reflection to find all the fields that are annotated by a particular annotation good practice for abstract object sorting?
Annotations are there for convenience, and your use is making the situation more convenient, so it seems reasonable. The alternative is to maintain a separate dictionary of which fields are sortable for which objects, and is slightly more cumbersome but slightly better from a seperation of concerns point of view.
The question is really whether your object should know about the annotations or not (is the object going to be reused in another situation where the annotations do not make sense or conflict). With a separate list of sortable fields, you can pick which to apply in any given case.
If the convenience trade-off works for you, then you should stick with the annotations, just so long as you are aware of the potential design ramifications (which may be nothing for your particular case).
How do you think basically every annotation-driven configuration framework works? "Give me all the of such-and-such type fields annotated with '#Inject'" or "give me everything in package baz.plugh annotated with '#Controller'".
Whether or not it's good for "abstract sorting" or not, I don't see why not. If it works, and eliminates the need for things like bean mappers and bean info classes, what's the issue?

Categories