I have created dynamic setter getter using Reflection API but it is creating performance issue so I want to replace my reflection code with some dynamic cutom method specially for getter.
I am planning to store all my field name in map but not sure how will I link my accurate values agains those fields.
I have tried with PropertyUtils as well but it also use reflection internally.
In the case of reflection it was working fine.
Is there any way to write dynamic getter value with fieldname verified because if i will store fields name in map on first attempt as key and value as null then how will i link specific value for that field after that and again it will be lengthy process.
Use Lombok for that https://projectlombok.org/. It will generate boilerplate getter/setters for you on precompile.
it will be like
#Getter
#Setter
public class LombokExample(){
private String myField;
}
done - end of class definition - no getters/setters required
and still you will be able to
lombok=new LombokExample();
lombok.getMyField();
lombok.setMyField();
Related
In Java we can use custom annotation to validate the fields but apart from this is there any way we can set the value of variable based upon logic using custom annotation in java or spring boot.
See example below
#CustomAnnotation
private String name;
if setter method set the value to name is "$123See" our custom annotation automatically modify the value to name "see" by remove some characters or based upon our own logic.
This is not possible directly and without a background process. Basically, attribute annotations are performed and populated by class analysis.
#1 way: You create a setter method for private attributes and define annotate on it. So, you have to define (example) #Around AOP to your annotation.
https://www.baeldung.com/spring-aop-annotation
#2 way: You add your annotation to your attribute and you have to analyse it with Java reflection, direct after setting the attribute or before setting it with another logic. https://www.baeldung.com/java-custom-annotation
(You can write private attr. in reflection temporary: Set private field value with reflection)
I'm dealing here with JWT and setting up custom fields.
All those custom fields are described in an Enum:
public enum JwtFields {
userId,
manyOtherCustomFieldsBellow,
blaBlaBla
}
So whenever I create token instead of passing strings for the keys, I'm using an enum as it is faster and safer.
Claims claims = Jwts.claims().setSubject(userId);
claims.put(JwtFields.someCustomFieldFromEnum.name(), "someValue")
Now, once I check that the received token is valid and all necessary custom fields are present, I want to deserialise it to some TokenDecoded class and attach it to the request payload, so whenever I'm processing a request I will have all values and fields from the JWT token.
However, that deserialise class pretty much contains all fields from the enum, and if tomorrow I will add new fields to the enum, I'll have to also manually update my TokenDecoded class to include that new custom field too.
The question:
How can I make this TokenDecoded class to be based on the enum fields, so if I add a new field to the enum, it will be automatically present in TokenDecoded? Is there reflection involved? Or it could be achieved simpler?
Lombok provides a feature that works the other way 'round: If you define your fields in a class, you can annotate it with #FieldNameConstants(asEnum = true) to generate an enum based on the field names. Or, without the asEnum parameter, you'll get public static final Strings for your fields if you only need it as Strings.
You have several options:
Use a Map instead of a class. Simplest solution but doesn't enforce typing or fields.
Code generation: you can generate the class at compile time (e.g. JavaPoet).
Byte code generation: you can generate byte code for the class at runtime (e.g. Javassist).
Use Groovy metaprogramming features (or any other JVM-based language that support runtime data structure definition).
In my opinion code generation at compile time is best suited to your scenario.
Note that if you're using JWT you might want to look into a JWT library instead of reinventing the wheel.
I'm working on a Maven Plugin and I need to modify one class of an external jar (used during maven execution), to add:
a new field on this class
a getter for the field
some behavior to an existing setter to populate the field
The library code should use my 'new' class, and I want to be able to use the getter to retrieve some additional information.
Instances of this class are created within the library code (I'm not creating them in my code, I just need to access them).
Class is a non-final public class.
Do you know if this feasible and which is the best way to do it? Is it possible to do it with ByteBuddy?
EDIT: I cannot wrap the class, because it's not instantiated in my own code, let me elaborate a bit.
There's a library class named "Parser" that instantiate and populate some "Element" instances. My code looks like:
List<library.Element> elements = new library.Parser(file).parse();
the Parser.parse() method calls "Element.setProperties(List properties)" on each element.
I want to be able to enrich the setProperties method to store the original list of properties (that are lost otherwise)
Thanks
Giulio
At the end I managed to obtain the wanted result with byte-buddy (I don't know if it's the best solution but it works):
instrument library class (library.Element) using 'rebase' strategy to delegate the method 'setProperties' call to an interceptor.
Note: this must be done as the first instruction of the maven plugin execution when library.Element.class is not yet loaded (I didn't want to use a JVM agent)
define the above interceptor as a class that stores the original 'properties' value in a global map (key = identity hash code of the object, value = properties) and then call the original 'setProperties' method of library.Element
change my code to get properties from the map, instead of library.Element getter (I had already a wrapper of this class).
If someone is interested, I can show some code.
Your suggestion sounds a bit hackish, and in general what you want to do would not even be possible without generating sources from the JAR, modifying them, and then repackaging. If I faced this problem, I would consider using a decorator pattern instead. You can create a wrapper which exposes all the methods of your JAR, except it would add one extra field along with a getter and setter.
import com.giulio.old.jar.everything.*;
public class WrapperOfJar {
private String newField;
public String getNewField() { // ... }
public void setNewField() { // ... }
// all getters and setters from current JAR
}
Now your users will see the same interface, plus one new method for your field. This answer assumes that the class in question is not final.
Assuming a JPA entity with (for example) an long id generated automatically:
#Entity
#AutoProperty
public class SomeItem {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private long Id;
...
}
Is there any reason to not generate setter and getters for this Id? One might be tempted to not generate a setter for example, since it is the responsibility of JPA to generate the ID.
I see that other comments has misguided you so I feel myself obliged to elaborate on this issue a bit, even though I can't give you a scientific and complete answer. #vcetinick wrote the current accepted answer:
You may find that you may be able to get away [..] from the persistence side of things.
This quote in particular is wrong. All depends on where you put your #Id annotation. The specification says:
If the entity has field-based access, the persistence provider runtime
accesses instance variables directly.
Thus you are not required in any way to provide a setter or getter. Because you annotated your field and not a getter method (annotating the setter method will be ignored and have no bearing).
However, if you write a getter method, and annotated this method with your #Id annotation instead of your field, then we would tell our persistence provider to access our field through the accessor (getter) and mutator (setter) methods and not use reflection. In that case, both a getter and a setter should be present. The book Pro JPA 2: Mastering the Java™ Persistence API writes on page 71 (bold markup by me!):
When property access mode is used, the same contract as for JavaBeans applies, and there must be getter and setter methods for the persistent properties. The type of property is determined by the return type of the getter method and must be the same as the type of the single parameter passed into the setter method. Both methods must be either public or protected visibility.
Therefore, I usually annotate my id field, and write both a setter and getter method, but the setter method I give protected access. I just don't want any other pieces of code to have easy write access to such an important field. I don't know if this would cause problems in other domains. I'm no expert. But I don't find any rationale either as to why not setup an id attribute in this way. See also the Netbeans forums.
You may find that you may be able to get away without putting a getter/setter on the JPA Entity from the persistence side of things. But if you start dealing with entities that are serialized from other sources, even from your view in some cases, you will need a way to set the ID of the entity to let JPA know that it is dealing with an existing entity, if you cant set the id, then the persistence layer will just treat it as a new Object.
Id is your primary key without it you will never able to insert records in the database.
In your case #GeneratedValue(strategy=GenerationType.AUTO) it ensures that id will be generated for each persist but then also you will need a method to access it since it is primary identification of entity you should provide access to it .
Its like you asking some person his name and he doesn't provide it to you and you would thing he is just being rude .
I am using hibernate annotations. How to add methods to POJO object? For example i have "getChildNodes" method, associated with database, but i want also add recursive method "getAllChildNodes". I get "org.hibernate.PropertyNotFoundException: Could not find a setter for property progress in class" exception when i do it.
If I interpret this as "how do I add a method that is NOT related to persistence" then you need to use the #Transient annotation on the getAllChildNodes() method
There are two ways of defining the structure of your entity.
using annotations on the instance variables of your entity or
using annotations on the getter methods of your entity
When using the annotations on getter methods, Hibernate assumes that every getXxx (and isXxx for boolean types) represents definition of a persistent property. And this holds even if that particular getter does not contain any annotations, as happens in your case.
Hibernate also expects to find a matching setter method for each persistent property. And in your case that is what's missing and causes the exception.
You can solve this problem by declaring your custom getter as #Transient that says this getter does not represent a persistent property. Another way would be to convert the entity to use annotations on the instance variables. The latter would be my personal choice.
Open up the .java file and write a method named getAllChildNodes().
Hibernate doesn't write code for you, it maps fields in your database to your code. That's all. If you want to have extra logic in your domain/model classes besides the normal getters and setters for your properties, you'll have to add them yourself.