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.
Related
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?
In my project, lombok is used to avoid writing getters and setters for a class.
I have two classes Child extends Parent:
#Value
#Builder
#AllArgsConstructor
#JsonIgnoreProperties(ignoreUnknown = true)
public class Parent {
#Nonnull
#JsonProperty("personId")
private final String personId;
#JsonProperty("personTag")
private final String personTag;
...
}
And
#Value
#Builder
#AllArgsConstructor
#JsonIgnoreProperties(ignoreUnknown = true)
public class Child extends Parent {
#Nonnull
#JsonProperty("childId")
private final String childId;
...
}
But this doesn't seems work as no default constructor available in Parent. I'm not familiar with the lombok annotation. Is there any good way to extend the Base class and use the lombok annotation at the same time?
TL;DR: add #NonFinal annotation to your superclass
Details: #Value annotation makes the class final, so you cannot inherit from it. Experimental #NonFinal annotation should prevent this.
import lombok.Value;
import lombok.experimental.NonFinal;
#Value
#NonFinal
public class Parent {
REF: https://projectlombok.org/features/Value
NOTE: For performance reasons (if it matters) final (value) objects can be (theoretically) super fast. The optimizer can allocate them in the stack memory, or reuse the same stack block in cycles, so no GC overheads.
(This is similar to how .NET structure value objects are usually allocated by .NET framework)
By adding #NonFinal such an optimization opportunity disappears.
Class hierarchies + lombok doesn't work particularly well, in the sense that the lombok operations done on your Child class don't know anything about parent.
However, your specific question seems answerable:
The Parent class has a constructor that takes all fields, because you asked lombok to make this constructor via #AllArgsConstructor. Therefore, it does not have a no-args constructor. If you want both constructors (the one that takes all fields + a second one that takes no arguments, a.k.a. the default constructor), also add a #NoArgsConstructor annotation to tell lombok that you want that.
NB: #Builder does not work with hierarchy either, but the fresh new #SuperBuilder feature does. I'm pretty sure you want to replace #Builder with #SuperBuilder here. SuperBuilder requires that ALL classes in the hierarchy are annotated with #SuperBuilder and not #Builder.
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'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.