java reflection library which support to get nested object field values. - java

Is there knowing java reflection library which can get value of fields easily.
Ex .
If I have Address Object inside User Object. And Address object have city attribute.
public class Address {
private String city;
}
public class User {
private String name;
private Address address;
}
Then i want to pass address.city as parameter with User Object and i want to get city of user.
Is there any library which support my requirement.

Apache commons beanutils has
PropertyUtils.getNestedProperty(user, "address.city").
You can also do PropertyUtils.setNestedProperty(user, "address.city", "new city") but you need to make sure that address is not null.

Related

When all columns of an #Embedded field are NULL (JPA / Hibernate) - how to prevent null pointer?

Is there any way to init a empty object, even if all values are null?
#Embeddable
public class Address {
private String street;
private String postalCode;
private String city;
}
#Entity
public class Person {
#Embedded
private final Address home = new Address();
}
The problem is, when you hydrate a Person, if all fields of the embedded Address are null, it seems like hibernate is initializing home to null.
It is not initializing it as a "new Address()".
Is there any way to force hibernate to initialize home as "new Address()" even with all fields null?
Trying to avoid things like:
public Address getHome(){
if(home == null){
this.home = new Address();
}
return this.home;
}
You can control this with the hibernate.create_empty_composites.enabled configuration which you can read about in the documentation: https://docs.jboss.org/hibernate/orm/5.6/userguide/html_single/Hibernate_User_Guide.html#_misc_options
If this is your only code, then there is nothing here that will produce a NPE. If you are calling something like getHome().getStreet().length() then it will if the field street was set to null based on the results of the query. This is the correct behavior, and you shouldn't attempt to change it. This way it's up to you to write your code in a manner that's null-safe.
If you still just want to have these fields as an empty String rather than Null, then you can create a custom type in Hibernate. Implement org.hibernate.usertype.UserType, in the nullSafeGet and nullSafeSet methods, you'll return an empty String in place of any null values. Then you'd simply annotate your fields with #Type()
#Type(type = "com.acme.MyCustomType")
private String street;
Again, I would highly recommend AGAINST taking this approach as you're going to end up with more headaches than just dealing with NPEs

How do I return a serialized response for field data not stored in ES

class Address {
String address1, country, state, zip;
}
class Foo {
#Field(type = FieldType.Object)
Address work;
boolean workAddressSameAsHome;
#Field(type = FieldType.Object)
Address home;
}
I would like to return work value as home in the JSON response if workAddressSameAsHome=true, as the value will not be stored in ES. How do I make this work for a GET request /foo/<id>
Spring Data Elasticsearch does not offer any REST URLs, so I assume you are using Spring Data Rest on top.
BTW, your Foo class has no #Document and #Id property, I guess your real class has one.
What you can do in Spring Data Elasticsearch is to provide a bean that implements the AfterConvertCallback interface - available since Spring Data Elasticsearch 4.0:
#Component
public class SetWorkAddressAsHomeCallback implements AfterConvertCallback<Foo> {
#Override
public Foo onAfterConvert(Foo foo, Document document, IndexCoordinates indexCoordinates) {
if (foo.workAddressSameAsHome) {
foo.home = foo.work;
}
return foo;
}
}
This callback is invoked after the document is read from Elasticsearch. Here I just copy the work address to the home address field.
For more information about the callbacks check the documentation at https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#elasticsearch.entity-callbacks
You might consider to implement a BeforeConvertCallback as well where you would clear the home address when the workAddressSameAsHome is true, this would be invoked before the entity is saved in Elasticsearch, thus preventing to store a home address in this case. But keep in mind that you won't be able to do an Elasticsearch search for the home address in this case.

Hibernate - how to load different view of same object

How is this called and how to solve my next problem on API. I have to return same object with different views. Some data should not be returned to user. Here is example:
Parent:
public class OrginalObject{
private int id;
private String name;
private String surname;
private int age;
private String school;
private String secret;
private Address Address;
child:
public class Address{
private int id;
private String street;
private String zipCode;
private String Country;
If i want to load list of complete objects i would call:
session.createCriteria(OrginalObject.class).list();
1.) But if don't want someone to know my property secret, i need to hide it. But i don't know how to call it from database the way it would have every other property. Something like:
session.createCriteria(OrginalObjectPublic.class).list();
2.) Also I would like to have option to load only "important" data. That means only properties id, name, school.
session.createCriteria(OrginalObjectImportant.class).list();
Is there a way to do an adapter/"custom view" to directly load it from database? I know i can write pure sql, but i would like to use it on objects with 20+ properties that have nested lists/objects.
3.) Also how to use this transformation to load only few properties of nested object with those from orginal. Example json (only id, name, school from OrginalOBject and id, street from Address:
{
"id": 1,
"name": "testname",
"school": "testschool",
"Address": {
{
"id": 33,
"street": "testStreet 33"
}
}
4.) also how to use it on nested Lists if Address would be array:
public class OrginalObject{
...
private List<Address> AddressList;
Since hibernate is a persistence-framework and you can not save/persist to a view, this is not possible. Yes you can make a view having the name like the table and preferr the view but you will not be able to store to that entity anymore.
You can remove the getter (getSecret) from the entity. So the database still have the field but your entity is not aware of it. This may cause problems if you try to store data using that entity, you may not be able to set the secret.
You can make the getter default (package-level-access) and seal the package to let noone else than the sealed projects access the getter.
You can use spring's method authorization mechanism
First no one have access to your secret,
only you the programmer who is supposed to see it.
Second if no one is supposed to have it why store it.
And if you want to pull it out you can use inheritance.
something like
public abstract PublicObject {
...
}
public OriginalObject extends PublicObject {
String secret;
}
Edit:
2nd & 4th questions you can solve them with hql:
String hql = "SELECT O.id, O.name, O.school FROM OrginalObject O";
Query query = session.createQuery(hql);
List results = query.list();
as for your 3th question it depends on your api. if you're using jackson for example you can use #JsonIgnore
You can map more than one entity to the same table, each one with the set of properties you want to expose.
Take a look to this question.

Serialization pojo into different json structure

I need to serialize a pojo into different json structure depending on whom I am sending request. Also I should be able to configure in some config that how field of pojo are mapped to json properties for a given request.
Can this be achived using jackson?
Is there some library or api to do this?
Edit:
For example:
public class Universal {
private int id;
private Date date;
private String name;
private Inner inner;
private Map<String,Object> others;
private List<Inner> inners;
}
public class Inner {
private String value;
}
now above are two object i need to create dynamic json, one example for some of transformation is below
{
"id":"",//value will be id of Universal
"detials":{
"name":"",//value will be name of Universal
},
"data":[], // array of value(field of Inner) from inners
"ext":{
"prop1":""// value of this field will be some (key1) value from others
}
}
You can use Google Gson and rely on its type adaptors.
http://www.javacreed.com/gson-typeadapter-example/ is a good article from web

Configure Gson to change key in json

I am thinking of using Gson in my web-service, but i observed that Gson returns name of a variable in class as a key in Json format.
E.g
interface Animal{
}
class Dog implements Animal{
public String name, age;
#Override
public String toString() {
return name+"\t" + age;
}
}
Json for object of Dog is as follows:
{"name":"Tommy","age":"12"}
Now, my problem is since Key(name and age) in Json are dependent on name of variable, So if my variable name changes then key also changes. Then client for this web-service has to change the code whenever a variable name changes in web-service.
So Is their any way, so that i can map every variable with a key name. For e.g mapping name to nameOfDog and age to ageOfDog, so that json will look like
{"nameOfDog":"Tommy","ageOfDog":"12"}
Yes, using the SerializedName annotation.
Since is has a #Target(value=FIELD), it can (only) be applied to instance fields.
So:
#SerializedName("nameOfDog")
String name;
(in Jackson that would be #JsonProperty("nameOfDog"))

Categories

Resources