Lombok #Getter and copies of Collections - java

Using #Getter on a List field works fine, but on attempting to upgrade to Java 8 I encounter ConcurrentModificationExceptions because the getter generated by Lombok does not perform a copy of the field, which is essential should you wish to prevent external modification of the instance's state.
Any ideas how I can get Lombok to copy the Collection on getters, or am I restricted to writing my own?

From #Getter and #Setter documentation:
You can annotate any field with #Getter and/or #Setter, to let lombok generate the default getter/setter automatically.
A default getter simply returns the field, and is named getFoo if the field is called foo (or isFoo if the field's type is boolean). A default setter is named setFoo if the field is called foo, returns void, and takes 1 parameter of the same type as the field. It simply sets the field to this value.
Since you want more functionality then the default getter you'll have to write your own.

Related

In Lombok, what is the difference between #AllArgsConstructor and #RequiredArgsConstructor?

Lombok offers a variety of annotations for java constructors, including but not limited to #AllArgsConstructor and #RequiredArgsConstructor. What is the difference between these two and when do you use one over the other? I found this documentation but the verbiage is a little convoluted and I'm having trouble following the basic differences between the two.
In short, use #AllArgsConstructor to generate a constructor for all of your class's fields and use #RequiredArgsConstructor to generate a constructor for all class's fields that are marked as final.
From the documentation,
#AllArgsConstructor generates a constructor with 1 parameter for each field in your class.
#RequiredArgsConstructor generates a constructor with 1 parameter for each field that requires special handling. All non-initialized final fields get a parameter, as well as any fields that are marked as #NonNull that aren't initialized where they are declared.

How to tell lombok that dont create getter and setter for a specific field [duplicate]

I want to use a data class in Lombok. Since it has about a dozen fields, I annotated it with #Data in order to generate all the setters and getter. However there is one special field for which I don't want to the accessors to be implemented.
How does Lombok omit this field?
You can pass an access level to the #Getter and #Setter annotations. This is useful to make getters or setters protected or private. It can also be used to override the default.
With #Data, you have public access to the accessors by default. You can now use the special access level NONE to completely omit the accessor, like this:
#Getter(AccessLevel.NONE)
#Setter(AccessLevel.NONE)
private int mySecret;
According to #Data description you can use:
All generated getters and setters will be public. To override the
access level, annotate the field or class with an explicit #Setter
and/or #Getter annotation. You can also use this annotation (by
combining it with AccessLevel.NONE) to suppress generating a getter
and/or setter altogether.

Hibernate Annotations : No default constructor for entity

I am trying to persist the objects generated by JAXB. Here is the sample structure:
#Column(name = "reporting_identifier")
private String reportingIdentifier;
#Column(name = "apply_quiet_time")
private boolean applyQuietTime;
#Embedded
private RecipientDetailsList recipientDetailsList;
Below is the structure of RecipientDetailsList class:
#ElementCollection(targetClass=String.class)
private List<RecipientDetails> recipientDetails;
Now, the RecipientDetails class has one argument constructor, which accepts a String. That String I want to persist in the database as a part of the whole record. I am seeing
org.hibernate.InstantiationException: No default constructor for entity: RecipientDetailsList
exception when I try to save an object. I have two questions:
Do we have any work around this exception? I can't change the class as it is designed for JAXB marshalling/unmarhsalling. Can I somehow store the objects without altering the structure? Also, I am interested in only storing the first record of the list referenced by
recipientDetails as I want only one row for object. I want it to ignore the rest of the records if it has more than 1 record. Is it possible?
Is this good design to use the annotation directly into classes which are generated by JAXB? Should I create another classes (and possibly mappers/converters) just to store and retrieve the information?
For your first question: this is happening because when Hibernate tries to create a bean, it does it via reflection. It does the object creation by calling the no-arg constructor, and then using the setter methods to set the properties. You can't use a bean that doesn't have a no-arg constructor.
For the second question: if something else has generated classes for you that don't have a no-arg constructor, really your only option (if you can't modify the class) is to create a wrapper round it, or a subclass that has a no-arg constructor. I don't see any other way of doing it if you can't modify the class directly. But the subclassing should be fine as long as the class you've got has enough visibility on the methods (i.e., doesn't have private methods that you then can't get to).

What is the purpose of AccessType.FIELD, AccessType.PROPERTY and #Access

I just want to know what is the difference between all these annotations. Why are we using these... means they have no effect especially field level and property level.
And what is the purpose of using mixed level annotation like:
#Entity
#Access(AccessType.FIELD)
class Employee {
// why their is a field level access
private int id;
// whats the purpose of transient here
#Transient
private String phnnumber;
// why its a property level access
#Access(AccessType.property)
public String getPhnnumber() {
return "1234556";
}
}
what exactly this class says?
By default the access type is defined by the place where you put your mapping annotations. If you put them on the field - it will be AccessType.FIELD, if you put them on the getters - it will be AccessType.PROPERTY.
Sometimes you might want to annotate not fields but properties (e.g. because you want to have some arbitrary logic in the getter or because you prefer it that way.) In such situation you must define a getter and annotate it as AccessType.PROPERTY.
As far as I remember, if you specify either AccessType.FIELD or AccessType.PROPERTY on any of the entity fields / methods you must specify the default behaviour for the whole class. And that's why you need to have AccessType.FIELD on the class level (despite that AccessType.FIELD is the default value.)
Now, if you wouldn't have #Transient on the phnnumber field, the JPA would provide you with a 3 columns table:
id,
phnnumber,
getphnnumber.
That's because it would use AccessType.FIELD for all of the entity fields (id and phnnumber) and, at the same time, it'd use AccessType.PROPERTY for your getter (getPhnnumber()).
You'll end with phone number mapped twice in the database.
Therefore, the #Transient annotation is required - it means that the entity won't store the value of the field in the underlying storage but the value returned by your getter.

can BeanUtils.setProperty() set value without setter?

I'm currently taking an example from here to map my ResultSet to custom Object. I've tested BeanUtils.setProperty() and it seems like the object would need setters to work. Is there any way to map values like what Gson does? I don't want to have public setters.
No it can't.
As the name implies the BeanUtils deal with Java Beans
They are serializable, have a zero-argument constructor, and allow access to properties using getter and setter methods.
(Emphasis mine.)
Though the Javadoc of the BeanUtils methods is quite vague clues can also be found in the source code of BeanUtilsBean.setProperty() and PropertyUtilsBean.setSimpleProperty().
See the documentation too:
The Java language provides classes like java.beans.Introspector, which can examine a Java class at runtime and identify for you the names of the property getter and setter methods, [...]. The APIs in the BeanUtils package are intended to simplify getting and setting bean properties dynamically, [...].
(Emphasis mine.)
You can use #Data annoation from Lombok library in the Entities.

Categories