Pregunta

EDIT: This appears to be happening with PUTs as well.

Using spring-data-rest-webmvc version 2.1.0.BUILD-SNAPSHOT I have found that I am unable to POST a resource with a relation pointing to an already existing resource. I have 2 such entities which require references to be instantiated and POSTing to either of their endpoints results in the behavior below.

POSTing a resource without required references works well.

I did a bit of digging and it appears that PersistentEntityResourceHandlerMethodArgumentResolver finds the MappingJackson2HttpMessageConverter just fine, but it ends up throwing an exception while checking whether the ObjectMapper can deserialize the type. The cause of the exception is a NullPointerException.

example POST w/ relations to /reservations:

{ "description" : "test_post", "dateMade" : "2014-03-03T08:04:44.293-0600", "timeLastChanged" : null, "userLastChanged" : null, "courseTypeId" : null, "numCredits" : null, "instructor" : null, "numParticipants" : null, "reservationType" : "MCU", "status" : "REQUESTED", "abstract" : null, "requestor" : "http://localhost:8080/users/2", "submitter" : "http://localhost:8080/users/2", "conferences" : [] }

RESPONSE:

{ cause: null message: "No suitable HttpMessageConverter found to read request body into object of type class domain.Reservation from request with content type of application/json!" }

POST w/ no relations to /roomGroups:

{ "description" : "All Rooms", "isOffNetwork" : false, "roomGroupType" : "STANDARD" }

RESPONSE:

201 Created

Is there something wrong about the JSON I am POSTing which is resulting in an NPE from the ObjectMapper? Is there a workaround of some kind? This was working for me in 2.0.0.RC1 using a slightly different scheme for including reference links in the JSON and since the version of the Jackson dependencies appears to have stayed the same I wonder what is causing this issue...

Thanks for any help!

UPDATE:

This issue now seems un-related to the associated entities...

I created a new @Entity ConnectionRequest as follows:

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "CONNECTION_REQUEST_ID")
private Long id;

@Column(name = "FROM_ENTITY_ID", nullable = false)
private Long fromId;

@Column(name = "TO_ENTITY_ID", nullable = false)
private Long toId;

@Convert(converter = EntityTypeConverter.class)
@Column(name = "FROM_ENTITY_TYPE_ID", nullable = false)
private EntityType fromType;

@Convert(converter = EntityTypeConverter.class)
@Column(name = "TO_ENTITY_TYPE_ID", nullable = false)
private EntityType toType;

@ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.MERGE})
@JoinColumn(name = "CONFERENCE_ID", nullable = false)
private Conference conference;

I can POST a new ConnectionRequest record with a Conference relation included in the json as such {"conference" : ".../conferences/1"}.

I am however still getting the same exception w/ this @Entity Reservation:

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "RESERVATION_ID")
private Long id;

@Column(name = "DESCRIPTION", length = 50, nullable = false)
private String description;

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "DATE_MADE", nullable = false)
private Date dateMade;  

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "TIME_LAST_CHANGED")
private Date timeLastChanged;

@Column(name = "USER_LAST_CHANGED")
private Integer userLastChanged; // TODO why is this an int?

@Column(name = "ABSTRACT", length = 2000)
private String _abstract;

@Column(name = "COURSE_TYPE_ID")
private Integer courseTypeId;

@Column(name = "NUMBER_OF_CREDITS")
private Integer numCredits;

@Column(name = "INSTRUCTOR", length = 255)
private String instructor;

@Column(name = "NUMBER_OF_PARTICIPANTS")
private Integer numParticipants;

@Convert(converter = ReservationTypeConverter.class)
@Column(name = "RESERVATION_TYPE_ID", nullable = false)
private ReservationType reservationType;

@Convert(converter = StatusConverter.class)
@Column(name = "STATUS_ID") 
private Status status;

@ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.MERGE})
@JoinColumn(name="REQUESTOR_USER_ID", nullable=false)
private User requestor;

@ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.MERGE})
@JoinColumn(name="SUBMITTER_USER_ID", nullable=false)
private User submitter;

@OneToMany(fetch = FetchType.LAZY, mappedBy = "reservation", cascade = {CascadeType.REMOVE})
private Set<Conference> conferences = new HashSet<>();

I'm not sure what's special about this class that's causing things to go awry...

¿Fue útil?

Solución

The issue was the following:

Both of the non-postable entities had a property called _abstract due to it being a reserved word in Java. I had named the getter and setter for this property getAbstract() and setAbstract() respectively.

Jackson appears to have been throwing a null pointer exception since the getter and setter did not match the property name as expected.

When I changed the property name to resvAbstract and updated the accessors to getResvAbstract() and setResvAbstract() everything came together and started working.

I'm still curious about the change that led to this issue showing up, but I'm glad it's working!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top