spring-projects / spring-projects/spring-data-rest
Nested projection of abstract entities does not show links [DATAREST-1002]
@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
Benjamin Legendre opened DATAREST-1002 and commented
Despite it does not seems to be documented elsewhere, the common method to make "links.self.href" for nested inlined entities in projection to appear is to make themselves projections. It is well explained here: http://stackoverflow.com/a/38165158/5276344 and i confirm it works.
But not when the nested entity is a Parent abstract entity in a inheritance tree.
Given theses entity/repository/projection (assessors removed for clarity):
@Entity
@Table(name="items")
@DiscriminatorColumn(name="type")
@DiscriminatorOptions(force=true)
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class AbstractItem {
@Id
@GeneratedValue
private Integer id;
private String name;
@ManyToOne
@JoinColumn(name="some_entity_id", nullable=false)
private SomeEntity someEntity;
}
@Entity
@DiscriminatorValue(value="concrete-item-1")
public class ConcreteItemOne extends AbstractItem{
private String itemOneField;
}
@Entity
@DiscriminatorValue(value="concrete-item-2")
public class ConcreteItemTwo extends AbstractItem{
private String itemTwoField;
}
@Entity
public class SomeEntity {
@Id
@GeneratedValue
private Integer id;
private String name;
@OneToMany(mappedBy="someEntity", orphanRemoval=true, cascade = CascadeType.ALL)
private List<AbstractItem> items = new ArrayList<>();
@OneToMany(mappedBy="someEntity", orphanRemoval=true, cascade = CascadeType.ALL)
private List<WithoutInheritanceEntity> withoutInheritanceEntities = new ArrayList<>();
@Entity
public class WithoutInheritanceEntity {
@Id
@GeneratedValue
private Integer id;
private String name;
@ManyToOne
@JoinColumn(name="some_entity_id", nullable=false)
private SomeEntity someEntity;
}
public interface AbstractItemRepository
extends CrudRepository<AbstractItem, Integer> {
}
public interface SomeEntityRepository
extends CrudRepository<SomeEntity, Integer> {
}
public interface WithoutInheritanceEntityRepository
extends CrudRepository<WithoutInheritanceEntity, Integer> {
}
@Projection(name = "abstractItemProjection", types = { AbstractItem.class })
public interface AbstractItemProjection {
String getName();
}
@Projection(name = "someEntityProjection", types = { SomeEntity.class })
public interface SomeEntityProjection {
String getName();
List<AbstractItemProjection> getItems();
List<WithoutInheritanceEntityProjection> getWithoutInheritanceEntities();
}
@Projection(name = "withoutInheritanceEntityProjection", types = { WithoutInheritanceEntity.class })
public interface WithoutInheritanceEntityProjection {
String getName();
}
When executing this test case:
this.mockMvc.perform(get("/someEntities/1?projection=someEntityProjection")
.accept(MediaType.parseMediaType("application/json;charset=UTF-8")))
.andDo(MockMvcResultHandlers.print())
.andExpect(jsonPath("$.withoutInheritanceEntities[0]._links.self.href").exists())
.andExpect(jsonPath("$.items[0]._links.self.href").exists());
The returned json is:
{
"items" : [ {
"name" : "item-1"
}, {
"name" : "item-2"
} ],
"withoutInheritanceEntities" : [ {
"name" : "without-inheritance-entity-1",
"_links" : {
"self" : {
"href" : "http://localhost/withoutInheritanceEntities/1{?projection}",
"templated" : true
},
"someEntity" : {
"href" : "http://localhost/withoutInheritanceEntities/1/someEntity"
}
}
}, {
"name" : "without-inheritance-entity-1",
"_links" : {
"self" : {
"href" : "http://localhost/withoutInheritanceEntities/2{?projection}",
"templated" : true
},
"someEntity" : {
"href" : "http://localhost/withoutInheritanceEntities/2/someEntity"
}
}
} ],
"name" : "some-entity-1",
"_links" : {
"self" : {
"href" : "http://localhost/someEntities/1"
},
"someEntity" : {
"href" : "http://localhost/someEntities/1{?projection}",
"templated" : true
},
"withoutInheritanceEntities" : {
"href" : "http://localhost/someEntities/1/withoutInheritanceEntities"
},
"items" : {
"href" : "http://localhost/someEntities/1/items"
}
}
}
As you can see , items in 'items' array have no links (nested abstract entity) but items in 'withoutInheritanceEntities' array have links (simple nested entity without inheritance).
The test result:
No value at JSON path "$.items[0]._links.self.href", exception: Missing property in path $['items'][0]['_links']
The complete test case can be found as a Maven project on the attached zip. Simply run mvn test
Affects: 2.6 GA (Ingalls)
Attachments:
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.