spring-data-rest icon indicating copy to clipboard operation
spring-data-rest copied to clipboard

RepositoryRestController cant handle complex object deserialization [DATAREST-687]

Open spring-projects-issues opened this issue 10 years ago • 7 comments

George T opened DATAREST-687 and commented

I am trying to override AppointmentRepository POST /appointments using a custom controller annotated with @RepositoryRestController.

@RepositoryRestResource(collectionResourceRel = "appointments", path = "appointments")
public interface AppointmentRepository extends CrudRepository<Appointment, Long> {

}
@RepositoryRestController
public class AppointmentController {

@Autowired
private  AppointmentRepository appointmentRepository;

@RequestMapping(method = RequestMethod.POST, value = "/appointments")
public ResponseEntity<String> post(@RequestBody Appointment appointment) {
	............
    	appointment = appointmentRepository.save(appointment);
    	HttpHeaders httpHeaders = new HttpHeaders();
        return new ResponseEntity<>("{}", httpHeaders, HttpStatus.CREATED);
    }
}

Appointment.java

@Entity
public class Appointment {
	
	public Appointment() {		 
	}

	@Id
	@Column(nullable = false)
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;
	
	@ManyToOne
	Address address;
	
	//Getters, Setters
}

Address.java

@Entity
public class Address {

	@Id
	@Column(nullable = false)
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	public Long id;
	
	@OneToMany(mappedBy="address")
	List<Appointment> appointment;

	//Getters, Setters
}

When I post to /appointments the following

{ "address":"http://localhost:8080/addresses/1"}

I get

{
  "timestamp": "2015-09-24T10:52:02.824+0000",
  "status": 400,
  "error": "Bad Request",
  "exception": "org.springframework.http.converter.HttpMessageNotReadableException",
  "message": "Could not read document: Can not instantiate value of type [simple type, class com.address.Address] from String value ('http://localhost:8080/addresses/1'); no single-String constructor/factory method\n at [Source: java.io.PushbackInputStream@674e5fc9; line: 1, column: 52] (through reference chain: com.appointment.Appointment[\"address\"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class com.address.Address] from String value ('http://localhost:8080/addresses/1'); no single-String constructor/factory method\n at [Source: java.io.PushbackInputStream@674e5fc9; line: 1, column: 52] (through reference chain: com.appointment.Appointment[\"address\"])",
  "path": "/appointments"
}

If I don't include the address property or use @RestController instead of @RepositoryRestController everything works as expected.

Is this expected behavior?


Affects: 2.2.2 (Evans SR2)

8 votes, 10 watchers

spring-projects-issues avatar Sep 24 '15 12:09 spring-projects-issues

Ali Shahbour commented

Have you tried changing the Controller

@RequestMapping(method = RequestMethod.POST, value = "/appointments")

public ResponseEntity<String> post(@RequestBody Resource<Appointment> appointment) {

	............

    	appointment = appointmentRepository.save(appointment);

    	HttpHeaders httpHeaders = new HttpHeaders();

        return new ResponseEntity<>("{}", httpHeaders, HttpStatus.CREATED);

    }

}

spring-projects-issues avatar May 23 '16 11:05 spring-projects-issues

George T commented

Thanks! It works :)

spring-projects-issues avatar Nov 24 '16 22:11 spring-projects-issues

Robert Rackl commented

I am exposing my Repositores with @RepositoryRestResource (as spring-data-rest HATEOAS Resources) I do not have any RepositoryRestController. But I get the same error. How can I work around it?

spring-projects-issues avatar Jan 05 '17 20:01 spring-projects-issues

Daniele Renda commented

I've the same problem and the workaround suggested doesn't work. If I follow that suggestion the Resource object has content null and empty links

What's wrong?

spring-projects-issues avatar Oct 10 '17 13:10 spring-projects-issues

Daniele Renda commented

Some advice? Thanks

spring-projects-issues avatar Feb 15 '18 21:02 spring-projects-issues

Ali Shahbour commented

Have you tried changing the Controller

@RequestMapping(method = RequestMethod.POST, value = "/appointments")

public ResponseEntity<String> post(@RequestBody Resource<Appointment> appointment) {

	............

    	appointment = appointmentRepository.save(appointment);

    	HttpHeaders httpHeaders = new HttpHeaders();

        return new ResponseEntity<>("{}", httpHeaders, HttpStatus.CREATED);

    }

}

i did the same think here but it didn't work for me i'm using Spring Rest Data, any suggestion please ?

abakkari avatar Apr 01 '21 10:04 abakkari

Resource has been renamed to EntityModel in HATEOAS

gd08xxx avatar Feb 23 '22 10:02 gd08xxx