1

Spring Boot (2.1.1) を使用して、インターフェースの HAL REST API を自動的に作成していJpaRepositoryます。

ほとんどの場合、これらのインターフェイスは空です。次に例を示します。

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です。

これらのリンクは自動的に生成されるため、この動作を変更する方法は明らかではありません。

4

1 に答える 1

1

Spring の内部をデバッグしているときにPersistentEntityResourceAssembler、 のインスタンスを使用しDefaultSelfLinkProviderてセルフリンクを作成することがわかりました。そのクラスをデバッグしたところ、Hibernate によってプロキシされるオブジェクトに対してセルフ リンクが生成されると、クラスが正しく機能しないことに気付きました。

したがって、私は を-interfaceDefaultSelfLinkProviderの独自の実装に置き換えようとしました。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は a の単純なラッパー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". しかし、これが動作を変更するのに最適な場所であるかどうかはわかりません。

于 2019-01-31T11:05:19.703 に答える