问题
The problem:
I have a simple Spring Boot app, using Spring Data REST and HATEOAS, with a JPA Entity class which calls a MySql Function (not a table). The rest of my repos are displayed in a nice HAL set of hyperlinks, but this one function is not discoverable (not in the list). How do I add it into the HAL links?
@Entity(name = "GetOptionsForStyle")
@Table(name = "get_options_for_style")
@NamedNativeQueries({
@NamedNativeQuery(name = "getOptionsByStyleId",
query = "SELECT `f1`.`get_options_for_style`(?) AS `value`, FLOOR(1 + (RAND() * 10000)) AS `id`", resultClass = GetOptionsForStyle.class) })
/**
* GetOptionsForStyle
*/
public class GetOptionsForStyle implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private Integer id;
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
The Entity is exposed to the Spring Boot app in a simple repo:
@Repository
public class FunctionsRepo {
@PersistenceContext
private EntityManager manager;
public GetOptionsForStyle getOptionsForStyle(Integer styleId) {
GetOptionsForStyle getOptionsForStyle = manager
.createNamedQuery("getOptionsByStyleId", GetOptionsForStyle.class)
.setParameter(1, styleId)
.getSingleResult();
return getOptionsForStyle;
}
}
I am using Spring Data REST, and I would like to provide a link to this entity in the HAL links created automatically by SDR, but SDR runs on repo interfaces to entities for tables, not repo implementations calling named queries.
I can return the result of the MySql Function via a standard controller, but the link is not integrated into HAL:
@BasePathAwareController
public class SitesRestController {
private FunctionsRepo funcRepo;
SitesRestController(FunctionsRepo funcRepo) {
this.funcRepo = funcRepo;
}
@GetMapping(path="func/get_options_for_style/{styleId}")
@ResponseBody
public ResponseEntity<GetOptionsForStyle> getOptionsForStyle(@PathVariable("styleId") final Integer styleId) {
GetOptionsForStyle optForStyle = funcRepo.getOptionsForStyle(styleId);
return new ResponseEntity<GetOptionsForStyle>(optForStyle, HttpStatus.OK);
}
}
A similar question on StackOverflow (Q) points to these two answers (A and B). These answers both use ResourceProcessor, which was removed in v1 of spring-hateoas. The "spring-hateoas-examples/spring-hateoas-and-spring-data-rest" GitHub repo by GregTurn (one of the Spring HATEOAS contribs) uses a standard Repo interface also. I can get this to work on regular repo interfaces.
Is it possible to integrate into the HAL links produced by Spring Data REST? Is there a way to get a handle to that set of links before it is rendered? I can get a RepresentationModelProcessor to catch an entity before it is rendered, perhaps there is a similar hook to the main HAL links?
来源:https://stackoverflow.com/questions/59314771/spring-boot-add-non-repository-rest-controller-to-hal-links