1

I have timezone POJO as below:

@Entity
public class TimeZoneDto implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Column(name = "id", nullable = false)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "timezone_sequence")
    @SequenceGenerator(name = "timezone_sequence", sequenceName = "t_timeZone_master_id_seq", initialValue = 1, allocationSize = 1)
    private Long id;
    @Column
    private String timeZone;
    @Column
    private String name;
    @Column
    private double hourDifference;
    /* all gettet/setter */
}

I have updateTimeZone method in Spring Controller as below:

@RequestMapping(value = "updateTimezone", consumes = "application/json", produces = "application/json", method = RequestMethod.POST)

    public ResponseEntity<Object> updateTimezone(@RequestBody TimeZoneDto timeZoneDto){

}

when I pass request as below:

{"id":14,"name":"America/Los_Angeles -7:00 GMT"}

then it automatically convert other values with default values when map with POJO and it becomes:

id=14, timeZone=null, name=America/Los_Angeles -7:00 GMT, hourDifference=0.0

because of this when I update this POJO as below

getEntityManager().merge(timezoneDto);

it override TimeZone = null and hourDifference = 0.0 automatically,

so is there any way by which my TimeZoneDto in @RequestBody has only those columns which I pass in request JSON.

EDIT

I have used below on Class but its not work

  @JsonInclude(value=Include.NON_EMPTY)
                 OR  
  @JsonInclude(value=Include.NON_DEFAULT)
Ilesh Patel
  • 2,053
  • 16
  • 27

2 Answers2

1

I think the issue is with your design. You mix your Entities with DTOs. A mostly used solution is to separate these two layers. You can have a common interface say TimeZoneInfo then have two implementations

  • TimeZoneDto - responsible for transferring data between client and server, you only declare what you need in this object. (ex: without timeZone field)
  • TimeZoneEntity - represent a persistent entity (JPA/Hibernate)

Then you can have TimeZoneDto as the request body and adapt (i.e get required values and set to entity) that object as TimeZoneEntity. You may need to fetch the TimeZoneEntity from DB before adapting this DTO. I would say preferably in a service/delegate class not in rest controller.

Laksitha Ranasingha
  • 4,321
  • 1
  • 28
  • 33
0

This is the classic pattern where you first need to fetch the TimeZone entity from your storage repository and then merge the incoming JSON data with the existing record data.

public ResponseEntity<Object> updateTimeZone(@RequestBody TimeZoneDto dto) {
  final TimeZone timeZone = timeZoneRepository.findById( dto.getId() );
  // use object mapper or whatever and merge dto onto timeZone
  timeZoneRepository.saveOrUpdate( timeZone );
  return timeZone;
}
Naros
  • 19,928
  • 3
  • 41
  • 71
  • so is there any way by which my TimeZoneDto in @RequestBody has only those columns which I pass in request JSON.? – Ilesh Patel Aug 10 '16 at 20:40
  • Your DTO will be populated by Jackson with the fields your JSON contains. The other fields will simply be null; that is the way Jackson hydrates a JSON stream to an Object. From this point forward, you have to address the logical merge of attributes as I described above. – Naros Aug 10 '16 at 20:59
  • 1
    if all those fields are NULL which are not in JSON than I can merge using some conditions, but in my case some Long , boolean variable takes default , so sometimes that may be actual values and sometimes they are default. so its hard for me to distinguish – Ilesh Patel Aug 10 '16 at 21:02