Spring 数据 REST - 抽象类型关联的投影

Spring Data REST - projection of association of the abstract type

具有以下实体(省略不相关的字段):

@Entity
public class TransferConfiguration {

    @ManyToOne
    @JoinColumn(name = "RECIPIENT_ID", nullable = false)
    private Party recipient;    
}  

@Entity
@Inheritance
@DiscriminatorColumn(name = "type")
public abstract class Party {

}

@Entity
@DiscriminatorValue("C")
public class Customer extends Party {

} 

@Entity
@DiscriminatorValue("O")
public class OtherParty extends Party {

} 

关联基于摘要class。

现在我想在获得资源时将 link 加入关联,但是 Spring Data REST 总是内联关联,在 _[= 中没有给出 link结果 JSON.

的 30=]s 部分

输出如下:

{
  "recipient": {
    // recipient attributes inlined here
  },
  // other attributes here
  "_links": {
    "self": {
      "href": "http://myhost/api/transferConfigurations/20"
    },
    "transferConfiguration": {
      "href": "http://myhost/api/transferConfigurations/20"
    }
  }
}

我有两个具体 classes(Customer、OtherParty)的存储库接口,但没有 superclass 本身的存储库接口。现在,当 spring-data-rest 决定是否内联关联时,它会尝试找到 Party superclass 的接口,该接口不存在,因此内联关联。

是否可以通过某种方式改变行为?

我想要 link 而不是内联关联。像这样:

{
  // other attributes here
  "_links": {
    "self": {
      "href": "http://myhost/api/transferConfigurations/20"
    },
    "transferConfiguration": {
      "href": "http://myhost/api/transferConfigurations/20"
    },
    "recipient": {
      "href": "http://myhost/api/transferConfigurations/20/recipient"
    },
  }
}

Spring 如果目标实体没有定义存储库或存储库未导出,则数据 rest 正在嵌入关联。我会尝试为 Customer/OtherParty/Party 创建一个存储库。

另外,了解您的 Party 超类是如何映射的也会很有趣 - 它是 @MappedSuperclass

最终对该主题进行了一些研究,上面的场景根本不可能在 Spring Data Rest 中实现(我使用的是 2.4 版。1.RELEASE)。

问题在于如何确定关联类型。 SDR 使用 JPA 元模型(而不是检查被序列化的实际负载)来确定类型,这显然是超类型(在本例中为 Party)。 然后框架检查是否有该类型的存储库,因为没有,关联是内联的。

有问题的代码在 class AssociationLinks 方法 isLinkableAssociation() 中,其中 metadata.isExported() 检查是否根据关联超类型导出存储库。

public boolean isLinkableAssociation(PersistentProperty<?> property) {

    if (property == null || !property.isAssociation()) {
        return false;
    }

    ResourceMetadata metadata = mappings.getMetadataFor(property.getOwner().getType());

    if (metadata != null && !metadata.isExported(property)) {
        return false;
    }

    metadata = mappings.getMetadataFor(property.getActualType());
    return metadata == null ? false : metadata.isExported();
} 

最后,我硬着头皮导出了 superclass 存储库,以便获得链接。