spring-data-rest icon indicating copy to clipboard operation
spring-data-rest copied to clipboard

Subtyped Entity produces invalid (404) "self" reference [DATAREST-821]

Open spring-projects-issues opened this issue 9 years ago • 4 comments

Christian Bongiorno opened DATAREST-821 and commented

I have and entity with subclasses representing different contact methods. For example: Phone, address, twitter, etc.

The problems is that when I fetch a specific resource, the "self" reference is wrong. Following it produces a 404. See screen shot.

GET: http://localhost:8080/hal/contactMethods/1

{
    "method": "PHONE",
    "country": "USA",
    "format": "([0-9])([0-9]{3})([0-9]{3})([0-9]{4}); $1 ($2) $3-$4",
    "extension": null,
    "number": "17778889999",
    "_links": {
        "self": {
            "href": "http://localhost:8080/hal/phoneMethod/1"
        },
        "af:phoneMethod": {
            "href": "http://localhost:8080/hal/phoneMethod/1"
        },
        "curies": [
            {
                "href": "/custom/docs/{rel}.txt",
                "name": "af",
                "templated": true
            }
        ]
   }

Here are the entities:


@Entity
@Getter
@EqualsAndHashCode
@ToString
@NoArgsConstructor
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="method")
public class ContactMethod {

    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE)
    private Long id;


    private String method;

}
@Entity
@Getter
@EqualsAndHashCode(callSuper = true)
@ToString
@NoArgsConstructor
@AllArgsConstructor
public abstract class AddressMethod extends ContactMethod{

    private String country;

}
@Entity
@Getter
@EqualsAndHashCode(callSuper = true)
@ToString
@NoArgsConstructor
@AllArgsConstructor
@DiscriminatorValue("USA_ADDRESS")
public class USAAddressMethod extends AddressMethod {

    private String attention;

    private Integer buildingNumber;

    @NotNull
    private String streetName;

    private String suite;

    @NotNull
    @Enumerated(EnumType.STRING)
    private State state;

    @NotNull
    private String postalCode;
}
@Entity
@Getter
@EqualsAndHashCode(callSuper = true)
@ToString
@NoArgsConstructor
@AllArgsConstructor
@DiscriminatorValue("PHONE")
public class PhoneMethod extends ContactMethod {

    @Length(min = 3, max = 3)
    private String country;

    @NotNull
    private String format;

    private String extension;

    // must include +(cc)
    @Length(min = 12, max = 16)
    private String number;


}

Affects: 2.4.4 (Gosling SR4), 2.5.1 (Hopper SR1)

Attachments:

1 votes, 3 watchers

spring-projects-issues avatar May 11 '16 00:05 spring-projects-issues

Christian Bongiorno commented

by adding:

@RestResource(path = "contactMethods")

To the base class entity where in it matches the exported prefix of the repository then the self reference lines up. Not ideal

spring-projects-issues avatar May 11 '16 01:05 spring-projects-issues

Christian Bongiorno commented

I wanted to follow up: Not ideal, but that it was easy enough to override deserves kudos

spring-projects-issues avatar May 11 '16 17:05 spring-projects-issues

Benjamin Legendre commented

I ran into the same issue today with version 2.6.0 (Spring boot 1.5.1). The issue seems to occurs with the children entities of an inheritance tree, when the repository of the parent (abstract, maybe or not) entity is exposed, but not the repositories of the childrens (or they dont have one). Expected behavior: "_links.self.href" is built with the path of the repository of the parent entity. Actual behavior: "_links.self.href" is built with a path which is the name of child entity not pluralised (Evo Inflector is not applied). This url obviously points to a 404 because 1) the repository of this entity is not exposed or is simply not implemented 2) The resulting URL is above all malformed.

spring-projects-issues avatar Feb 07 '17 13:02 spring-projects-issues

Christian Bongiorno commented

by adding:

@RestResource(path = "contactMethods")

To the base class entity where in it matches the exported prefix of the repository then the self reference lines up. Not ideal

That only solves the self link href path but it doesn't help when a subclass is used in an association, in that case, the whole instance is deserialized rahter than just outputting a link to it. That happens because the repository search for the entity instance does not walk the hierarchy up to check if superclasses do have a repository associated. The following demo project illustrates the problem: demo.zip I think this should be considered a high priority issue

alienisty avatar Dec 30 '21 07:12 alienisty