Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate data mapping into child objects

Tags:

java

hibernate

I'm trying to figure out how to map data coming in on a request to a Hibernate object, and the issue is that the data coming in could be on the object or the child objects, and the field data is not necessarily known - the forms are user configured to contain and collect the desired data.

Roughly, the objects are like this:

Job {
  String title;

  @ManyToOne
  @JoinColumn(name = "location_id")
  JobLocation location;
}

JobLocation {
  int id;
  String description;
  double latitude;
  double longitude;
}

So if the user has defined that they want to edit the JobLocation description, we will get back in the request something along the lines of

{ jobLocationDescription: 'Santa Fe' }

How does that get mapped back to the child of the Job I'm dealing with? All I have at save time is the reference to the Job, all other items could be varying depending on what they have selected in dropdowns, etc. One option is to store a reference such as job.location.description, and have getters and use reflection to do a process-driving option:

String[] field = requestField.split(".");
Entity ent = (get object from field[0]);
if (field.length > 2) {
  ent = ent.get[get method name from next field position]();
}
ent.set[get method name from last field[] value](requestValue);

Sadly, there is nothing saying it couldn't be multiple levels, and to get the methods we are currently thinking we would have to use reflection. Are there other, better ways to do this type of operation or do we just have to slog through this?

like image 684
josh.trow Avatar asked Jul 27 '15 16:07

josh.trow


1 Answers

I had almost similar type of requirement in our project. We ended up using the reflection + annotation for mapping. On a nutshell, we were having something like this to construct the object.

class Job {
  String title;

  @ManyToOne
  @JoinColumn(name = "location_id")
  @EntityMapper(isRef="true")//Custom Annotation
  JobLocation location;
}

class JobLocation {
  @EntityMapper(fieldName="jobLocationId")
  int id;
  @EntityMapper(fieldName="jobLocationDescription")//Custom Annotation
  String description;
  double latitude;
  double longitude;
}

If you haven't got what I mean, we created custom annotation and we wrote a utility method that via reflection loops through the elements that has annotations as follows:

for (Field field : object.getClass().getDeclaredFields()) {
   //check for the EntityMapper annotation
   if (field.getAnnotation(EntityMapper.class) != null) {
       .
       .
       .//Use more reflection to use getters and setters to create and assign values from the JSON request.
   }
}
like image 173
Karthik R Avatar answered Oct 14 '22 17:10

Karthik R