spring-projects / spring-projects/spring-data-rest
Unable to make a PUT for entity with OneToMany collection [DATAREST-1169]
@odrotbohm is already working on this.
Since Dec 31, 2020.
- Dominant language
- Java
- Stars
- 958
- Forks
- 568
- PR merge metrics
- No merged PRs in 30d
Description
Slawek Mazur opened DATAREST-1169 and commented
Having a very simple domain like this:
@Entity
@Getter
@Table(name = "project")
public class Project extends AbstractEntity {
@NotEmpty
private String name;
@Column(unique = true)
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "project")
@OrderBy("position ASC")
private final List<Module> modules = new ArrayList<>();
Project(String name, Module... modules) {
this.name = name;
this.modules.addAll(Arrays.asList(modules));
}
Project() {
this("", new Module[0]);
}
public void orderModules() {
int position = 0;
for (Module module : modules) {
module.onPosition(position++);
}
}
}
@Data
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) // not the best choice ?
@Table(name = "module")
@NoArgsConstructor(force = true)
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
abstract class Module
extends AbstractEntity {
@ManyToOne
@JoinColumn(name = "project")
private Project project;
@Column(name = "content", columnDefinition = "text")
private String content;
abstract String getType();
private int position;
public void onPosition(int position) {
this.position = position;
}
}
@Data
@Entity
@NoArgsConstructor(force = true)
@EqualsAndHashCode(callSuper = true)
class Article extends Module {
@Override
public String getType() {
return "Article";
}
}
@Data
@Entity
@NoArgsConstructor(force = true)
@EqualsAndHashCode(callSuper = true)
class Footer extends Module {
@Override
public String getType() {
return "Footer";
}
@Override
public void onPosition(int position) {
super.onPosition(Integer.MAX_VALUE);
}
}
@Data
@Entity
@NoArgsConstructor(force = true)
@EqualsAndHashCode(callSuper = true)
class Header extends Module {
@Override
public String getType() {
return "Header";
}
@Override
public void onPosition(int position) {
super.onPosition(Integer.MIN_VALUE);
}
}
@MappedSuperclass
@Getter
@ToString
@EqualsAndHashCode
public class AbstractEntity implements Identifiable<Long> {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private final Long id;
@Version
private Long version;
protected AbstractEntity() {
this.id = null;
}
@CreatedDate
@Column(name = "created_at", nullable = false)
@JsonIgnore
private Instant createdAt = Instant.now();
@LastModifiedDate
@Column(name = "updated_at")
@JsonIgnore
private Instant updatedAt = Instant.now();
}
@RepositoryRestResource
interface ProjectRepository extends PagingAndSortingRepository<Project, Long> {}
I do POST to create new Project with few modules
{
"name": "Test project",
"modules": [
{
"type": "Header",
"content": "Header - content"
},
{
"type": "Article",
"content": "Article - content"
},
{
"type": "Footer",
"content": "Footer - content"
}
]
}
and then when I do PUT to update it
{
"name": "Real project",
"modules": [
{
"id": "1",
"type": "Header",
"content": "Header - content"
},
{
"id": "2",
"type": "Article",
"content": "Article 1 - content"
},
{
"id": "3",
"type": "Article",
"content": "Article 2 - content"
},
{
"id": "4",
"type": "Article",
"content": "Article 3 - content"
},
{
"id": "5",
"type": "Footer",
"content": "Footer - content"
}
]
}
org.springframework.http.converter.HttpMessageNotReadableException: Could not read an object of type class com.example.Project from the request!; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: Could not read payload!; nested exception is java.lang.IllegalArgumentException: Target bean of type com.example.Article is not of type of the persistent entity (com.example.Footer)!
at org.springframework.data.rest.webmvc.config.PersistentEntityResourceHandlerMethodArgumentResolver.readPutForUpdate(PersistentEntityResourceHandlerMethodArgumentResolver.java:228) ~[spring-data-rest-webmvc-2.6.9.RELEASE.jar:na]
at org.springframework.data.rest.webmvc.config.PersistentEntityResourceHandlerMethodArgumentResolver.read(PersistentEntityResourceHandlerMethodArgumentResolver.java:194) ~[spring-data-rest-webmvc-2.6.9.RELEASE.jar:na]
at org.springframework.data.rest.webmvc.config.PersistentEntityResourceHandlerMethodArgumentResolver.resolveArgument(PersistentEntityResourceHandlerMethodArgumentResolver.java:141) ~[spring-data-rest-webmvc-2.6.9.RELEASE.jar:na]
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:158) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) ~[spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) ~[spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) ~[spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) ~[spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) [spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPut(FrameworkServlet.java:883)
Complete project with test case attached.
Affects: 2.6.9 (Ingalls SR9)
Attachments:
- comexample.zip (13.40 kB)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.