Home > front end >  Jackson Hibernate relationship by id
Jackson Hibernate relationship by id

Time:05-30

Note: I unfortunately don't really have an idea of what library my problem concerns, if you need any further information please just write a comment!

I have two hibernate panache entity classes declared like this:

@Entity
public class FirstObj extends PanacheEntity {
  @ManyToOne(cascade = CascadeType.ALL)
  @JoinColumn(name = "secondobj_id", referencedColumnName = "id")
  public SecondObj secondObj;
  public String name;
}

@Entity
public class SecondObj extends PanacheEntity {
  public String name;
  public int weight;
}

And I want to be able to deserialize this object with this json (deserialized by jackson, assuming there's an entry in the SecondObj table with the id 1):

{
  "name": "hello",
  "secondObj": 1
}

Is this possible? I don't want it to automatically create a new SecondObj entity on requests.

CodePudding user response:

I recommend achieving this using the DTO pattern. When applied to your example, in addition to

@Entity
public class FirstObj extends PanacheEntity {
  @ManyToOne(cascade = CascadeType.ALL)
  @JoinColumn(name = "secondobj_id", referencedColumnName = "id")
  public SecondObj secondObj;
  public String name;
}

You will have another class -

public class FirstObjDTO extends PanacheDTO {
  public String name;
  public long secondObjId;
}

From that point you can use a mapping library or a mapping function to map FirstObj.secondObj.id to FirstObjDTO.secondObjId prior to serialization.

Example mapping function:

FirstObjDTO toFirstObjDto(FirstObj from) {
  FirstObjDTO dto = new FirstObjDTO();
  dto.setName(from.getName());
  if (from.getSecondObj() != null) {
    dto.setSecondObjId(from.getSecondObj().getId());
  }
  return dto;
}

You can also use a mapping library, one such library is ShapeShift. (Disclaimer: I am a contributor to ShapeShift)

Mapping example

@Entity
public class FirstObj extends PanacheEntity {
  @MappedField(target = FirstObjDTO.class, mapFrom = "id", mapTo = "secondObjId")
  @ManyToOne(cascade = CascadeType.ALL)
  @JoinColumn(name = "secondobj_id", referencedColumnName = "id")
  public SecondObj secondObj;

  @MappedField(target = FirstObjDTO.class)
  public String name;
}

Then wherever you intend to perform this mapping:

ShapeShift shapeShift = ShapeShift();
FirstObjDTO firstObjDTO = shapeShift.map(firstObj, FirstObjDTO.class);

CodePudding user response:

Please try some annotation like this link : https://www.baeldung.com/jackson-annotations

Int the case it is not enough for your answer please validate your input before use it

  • Related