spring-projects / spring-data-rest

Simplifies building hypermedia-driven REST web services on top of Spring Data repositories
https://spring.io/projects/spring-data-rest
Apache License 2.0
919 stars 563 forks source link

@Relation annotation not considered for link relation defaults #1974

Closed dlynch158 closed 3 years ago

dlynch158 commented 4 years ago

Hello,

The JSON that gets returned is this:

{
    "_embedded": {
        "employees": [

I am attempting to change an entity name from employees to "workers" by using the following Relation annotation:

@Entity
@Relation(collectionRelation = "workers", itemRelation = "worker")
public class Employee {

This has no effect on what gets returned.

The full source code of my test case is at:

https://github.com/dlynch158/relationtest

Thank you.

mschout commented 4 years ago

I'm seeing the same issue, running under spring-boot-start-parent 2.3.4.RELEASE. Adding @Relation to the model class seems to have no effect on the _embedded name.

laobuda commented 3 years ago

we are encountering the same problem after migrating to spring-boot-start-parent 2.3.6.RELEASE.

odrotbohm commented 3 years ago

The linked project actually builds fine using ./gradlew test. Anything I am missing?

odrotbohm commented 3 years ago

Nevermind, I made my way through it. There are a couple of things that are problematic / wring with the project but ultimately also a challenge I'd like to get you folks' input on:

The project pulls in Spring Data REST. I.e. the requests are not answered by the code contained in the project but Spring Data REST. That in turn uses repository metadata and defaults to determine the link relations. Those are not customized and thus the defaults derived from the repository apply. More on that below. If I remove Spring Data REST, annotate the controller and representation model assembler properly, the link relations are customized as expected.

With Spring Data REST in play, we currently order the repository based metadata inspection to trump the one base on entities. Otherwise @RepositoryRestResouce would be largely without effect. It appears that the lookup of the mapping metadata of Spring Data REST currently does not consider @Relation. We're running into a chicken and egg problem here as the SD REST LinkRelationProvider implementation would need access to all other LinkRelationProvider implementations but itself and the delegating wrapper instance to delegate to those to properly consider the overall arrangement.

Long story short, I am inclined to move this over to Spring Data REST as it clearly needs to be fixed there. The workaround in the meantime is to use @RepositoryRestResource on the repository to define alternate link relations if you use Spring Data REST.

odrotbohm commented 3 years ago

Looks like this a rather trivial fix as the metadata detection already uses the LinkRelationProvider coming from RepositoryRestConfiguration, which is currently set up to only use the one based on the Evo Inflector library. Tweaking that to a DelegatingLinkRelationProvider with the one considering @Relation first is rather easy. That's also a good way of getting the annotation to work with the current state of affairs: just configure an LRP as just described via RepositoryRestConfiguration.setRelProvider(…).

odrotbohm commented 3 years ago

Fixed for 3.5, 3.4 and 3.3.