0

I have a Spring Boot 2.x application backed by MongoDB. I'm trying to add some simple inheritance to my domain model along the lines of:

Parent: Person.java

// JSON annotations to assist in serializing requests to the right class
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "_class")
@JsonSubTypes({
  @JsonSubTypes.Type(value = Buyer.class, name = "com.company.domain.Buyer"),
  @JsonSubTypes.Type(value = Seller.class, name = "com.company.domain.Seller")
})
@Document(collection = "people")
public abstract class Person {
  ...
}

Subclass 1: Buyer.java

@Document(collection = "people")
public class Buyer extends Person {
  ...
}

Subclass 1: Seller.java

@Document(collection = "people")
public class Seller extends Person {
  ...
}

Essentially I would like Buyers and Sellers to be stored in the same Mongo collection and use the same REST path to operate upon them:

Repository: PeopleRepository.java

@RepositoryRestResource(path = "people", collectionResourceRel = "people")
public interface PeopleRepository extends MongoRepository<Person, String> {
}

This almost works except the HATEOAS links that come back look like:

{
  _links: {
    self: {
      href: http://localhost/services/buyer/5b96c785ba3e18ac91aa8cc9
    }
  }
}

What I need is for the "buyer" in the href to instead become "people" so that it lines up with the repository endpoint above.

I have tried adding an annotation @ExposesResourceFor(Buyer.class) to the repository which didn't seem to change anything (and I would need another annotation for Seller.class but it's not possible to add two @ExposesResourceFor annotations). I was able to get the links to work by making a second repository just for Sellers:

@RepositoryRestResource(path = "people", collectionResourceRel = "people", export = false)
  public interface SellerRepository extends MongoRepository<Seller, String> {
}

...but even with export set to false this seems to interfere with the other repository. There seems to be a 50/50 chance on whether the application will bind the endpoint to the SellerRepository or the PeopleRepository.

Is there anyway to set the resource path for subclasses here?

Bill
  • 347
  • 4
  • 13

1 Answers1

0

It looks like I was finally able to get this to work by adding additional repositories (which extend the base repository). It's important not to annotate these repositories.

@RepositoryRestResource(path = "people", collectionResourceRel = "people")
public interface PeopleRepository<T extends Person> extends MongoRepository<T, String> {
  ...
}

public interface SellerRepository extends PeopleRepository<Seller> { }

public interface BuyerRespository extends PeopleRespository<Buyer> { }
Bill
  • 347
  • 4
  • 13