我正在使用Spring Boot(2.1.1)自动创建JpaRepository
接口的HAL REST API。
在大多数情况下,这些接口为空,例如:
public interface ProjectRepository extends JpaRepository<Project, Long> {}
public interface ProtocolRepository extends JpaRepository<Protocol, Long> {}
一个Project
实体包含许多Protocol
实体。
Protocol
实体具有与其Project
实体的反向链接。
当我访问http://localhost:8080/admin/protocols/4711
时,会获得指向其项目的链接:
...
"project": {
"href": "http://localhost:8080/admin/protocols/4711/project"
}
...
但是当我按照该链接进行操作时,所有其他链接都会生成错误:
...
"_links": {
"self": {
"href": "http://localhost:8080/admin/project/1"
},
"project": {
"href": "http://localhost:8080/admin/project/1"
}
...
}
...
链接中的错误是使用单数名词project
,而不是复数形式projects
。
由于这些链接是自动生成的,因此如何更改此行为并不明显。
答案 0 :(得分:1)
在调试Spring内部时,我发现PersistentEntityResourceAssembler
使用DefaultSelfLinkProvider
的实例创建自链接。
当我调试该类时,我意识到为由Hibernate代理的对象生成自链接时,该类无法正常工作。
因此,我尝试用自己的DefaultSelfLinkProvider
接口实现替换SelfLinkProvider
。
这可以通过BeanPostProcessor
完成:
@Bean
public BeanPostProcessor entityManagerBeanPostProcessor()
{
return new BeanPostProcessor()
{
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException
{
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException
{
if (bean instanceof SelfLinkProvider)
{ return new HibernateSelfLinkProvider((SelfLinkProvider) bean); }
return bean;
}
};
}
HibernateSelfLinkProvider
是SelfLinkProvider
周围的一个简单包装:
public class HibernateSelfLinkProvider implements SelfLinkProvider
{
private final SelfLinkProvider selfLinkProvider;
public HibernateSelfLinkProvider(SelfLinkProvider selfLinkProvider)
{
this.selfLinkProvider = selfLinkProvider;
}
@Override
public Link createSelfLinkFor(Object instance)
{
instance = Hibernate.unproxy(instance);
return selfLinkProvider.createSelfLinkFor(instance);
}
}
Hibernate.unproxy()
的优点是,如果它不是代理对象,则它会使给定对象保持不变。
通过此添加,我获得了正确的链接:"http://localhost:8080/admin/projects/1"
。
但是我不确定这是否是修改行为的最佳场所。