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...