I am currently checking some code and I've come across a class which uses java.beans.Transient annotation with some of its methods. The code looks like this:
import lombok.Data;
import java.beans.Transient;
#Data
public class SomeClass {
private OtherClass obj1;
private OtherClass obj2;
#Transient
public boolean isSthPossible(){
...
return retVal;
}
}
This is the first time I have contact with java.beans so I tried to read something more about it however there aren't that much materials on this topic. I was able to find some useful information but I wasn't able to fully understand it yet.
I understand that beans are classes that have private fields and getter/setter methods to access them. I also understand that the #Transient annotation is used to mark getters of a bean so that they are not used during serialization process. However I couldn't find any information on whether the annotation can have any effect on non-bean methods like this. I also couldn't deduce it from the code I am analyzing and I am not able to contact the author of the code.
My question is whether #Transient annotation makes any sense when applied to non-bean methods, like that described. Can it change anything and can it be used any other way than with bean getter methods for serialization purposes?
Related
I'm using lombok's annotation #Data when writing pojos because it automatically generates constructor, hashCode as well as other methods for me. It worked like a charm until I was trying to use #Data in such a pojo class.
#Data
public class MyPojo {
private final String name;
private final int from;
private final int to;
// other fields
}
What I need to do is to restrict values of from and to when creating this pojo so that to will always be greater than from, but it seems that in order to achieve this logic, I have to rewrite the constructor all by myself with lots of code similar to this.name = name.
PS: I think using super from inheritance could be a workaround, but it may make the program harder to be understood.
Is there any better way to satisfy this need?
#Data annotation is not providing any way to validate construction arguments. I feel you need to annotate your pojo with #Getter #Setter #ToString #EqualsAndHashCode annotations and write constructor on your own.
Looking at Lombok's website, I don't see any way to restrict constructor parameters to specific values, especially relative to another variable that may have not been initialized yet. You'll probably have to create a concrete constructor for this class.
but it may make the program harder to be understood
I really wouldn't worry about that as you're already using Lombok, which would make any big program very confusing when trying to track down a specific field/method.
Having a simple class A that contains class B is there any lombok annotation that will create new instance of class b in a in case of null?
public class A {
#Getter
#Setter
private B b;
}
I am afraid the feature doesn't exist. The documenation lists a number of configuration keys for the annotations, but the functionality you are after is not listed.
Somebody recently asked for something like this on the Lombok GitHub page:
I'd love this feature for this scenario:
#Getter(lazy = true) private List<String> foo = new ArrayList<>();
to generate something like this:
private List<String> foo;
public List<String> getFoo() {
if (this.foo == null) {
this.foo == new ArrayList<>();
}
return this.foo;
}
Of course, it could use the double-checked locking or an AtomicReference, but the point here is I'd rather get an empty list than a null reference. It's a common idiom in JAXB classes for instance which are nice to reduce in size with Lombok.
So, the feature is not (yet?) implemented. If I were you, I would avoid using the annotation in these cases, and instead create the methods wanted by hand.
The GitHub issue was parked on 20 February 2020. Part of the motivation is as follows:
Also, it'd mean that calling a getter has a clear observable side effect and that sounds like a very bad idea. The current impl of lazy getter is fine because the field cannot pragmatically be accessed in the first place, and the getter appears to be idempotent. This in contrast to your proposal, where the field remains accessible.
I guess this makes it even more unlikely that the feature will be implemented.
I'm trying to learn how to store objects as XML files in java, but I'm having a bit of a problem.
Most tutorials that I have found have said that I should use the #XmlElement annotation with set methods, however is there another way to use them, as my objects would be easier to make using just the constructors I have for them instead of a set for each field.
The #XmlElement can also be used on the property. You will find more information in the javadoc.
The javadoc gives this example:
public class USPrice {
#XmlElement(name="itemprice")
public java.math.BigDecimal price;
}
All public fields and properties (get/set method pairs) will be treated by default as if they were annotated with #XmlElement. You can add #XmlElement on the get or set method. You can also annotate the field (instance variable). If you do you should annotate your class with #XmlAccesorType(XmlAccessType.FIELD).
http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html
JAXB does not currently support annotating constructors. If you are dealing with immutable objects then the following may help:
http://blog.bdoughan.com/2010/12/jaxb-and-immutable-objects.html
I have a Java class with ~90 fields. I want to be able to do things to every field (generate an XML element for instance) without writing the same 5 lines of code with slight substitutions 90 times. In Objective C I think you can get to instance variables in ways similar to accessing Dictionary elements (ObjectForKey). Is there anything similar in Java such that I can get an array of the fields then do something to each of them?
Yes, it's called Reflection API.
In particular, MyClass.class.getDeclaredFields() will return a full list of fields declared by this class (see API for details)
Here's another approach: Use the Introspector API with the JDK to obtain bean-like properties of a class. This is helpful if you have getters and setters for your class and do not want to access the private fields directly.
Obtain a BeanInfo via the Introspector and get all the propertyDescriptors from it. To find getter of that property.
I'll have to admit that using this API is a bit cumbersome and reflection (suggested by Nikita Rybak) is more straight forward.
But there's a utility Apache BeanUtils that does all the hardwork internally so working with beans becomes simple.
Add:
If you are using the reflection API, I'd suggest you annotate your bean fields or your getters with a custom annotation.
public class MyClassWith90Fields {
#XmlSerialize("name")
private String screenName; // shoudl serialize as <name>...</name>
#XmlSerialize
private String email; // shoud serialize as <email>...</email>
#XmlSerializeIgnore
pirvate boolean flag; // shoud not serialize as annotated as ignore
}
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.FIELD, ElementType.METHOD})
public #annotation XmlSerialize {
public String value;
}
Once done, your generation code can check (using reflection) annotated fields and serialize them to XML appropriately.
I'm borrowing the "slice" meaning from C++.
Let's say I hava a simple POJO that's persisted via Hibernate:
class Person {
private long id;
private String name;
...
// getters and setters here
...
}
Now, when I retrieve an object from the database I know it was "instrumented" by Hibernate (its real class is a Person-derived generated automatically). I want to convert it back to a "plain" person object. Tnat would be used, for instance, to submit the object to XStream and have the result containing only what Person contains.
I could do it by defining a copy constructor, but I don't want to have the hassle of having to write copy constructors for every ORM class (not to mention the violation of DRY principle).
So I was wondering if
a) is there already a Java lib that does it?
b) If not, would it be practical to write one using reflection?
In case of (b), any recomendations/guidelines/code skeletons would be appreciated.
The bean mapping library Dozer does an excellent job of this and is dead simple to use.
Simply map an instance of the bean returned by Hibernate to it's own class:
Person person = session.load(...);
BeanMapper mapper = ...;
Person cleanPerson = mapper.map(person, Person.class);
voila, no more Hibernate proxies or lazy-loaded collections!
The class org.apache.commons.beanutils.BeanUtilsBean probably does almost everything you want. The copyProperties method will go through calling the getters on your Entity and looking for setters with a matching property name on a target object you provide. You may need to handle some nested entities, depending on what kind of behavior you want and if/how you map relationships.
If you need to get more sophisticated you can register a Converter for turning your nested entity types into something else as well.
There is an interesting discussion about your problem here
http://www.mojavelinux.com/blog/archives/2006/06/hibernate_get_out_of_my_pojo/
Several solutions are proposed in the comments. In particular
http://code.google.com/p/entity-pruner/
http://www.anzaan.com/2010/06/serializing-cglib-enhanced-proxy-into-json-using-xstream/
I personally am huge on layer separation, and would argue that classes that you want to serialize across the wire or to XML should actually be separate from your data access layer classes, which would also solve the problem.
class SerializablePerson
{
... fields you care about ...
SerializablePerson(Person person)
{
... set only what you care about ...
}
}
You could have a Person class without persistence information wrapped by a persistent counterpart, like this:
public class Person implements Serializable
{
private String name;
// others.
}
public class PersistentPerson
{
private Long id;
private Person data; //
public Person getPerson() { return this.data; }
}
I'm not sure the design is worth it. The dual model makes me throw up in my mouth a little, just while writing this example.
The larger question is: Why do you think this is necessary? IF there's no good way to tell XStream to not include the id when serializing, I'd say it'd be better to write your own javax.xml.bind.Marshaller and javax.xml.bind.Unmarshaller to get what you want.
There are better ways to solve this problem than bastardizing your entire design.