【问题标题】:Spring Data REST - projection of association of the abstract typeSpring Data REST - 抽象类型关联的投影
【发布时间】:2015-12-18 16:58:18
【问题描述】:

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

@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 {

} 

关联是基于抽象类的。

现在我想在获取资源时链接到关联,但 Spring Data REST 总是内联关联,在生成的 JSON 的 _links 部分中没有提供链接。

输出如下:

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

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

是否有可能以某种方式改变行为?

我想要一个链接而不是内联关联。像这样:

{
  // 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"
    },
  }
}

【问题讨论】:

    标签: java spring spring-data spring-data-rest


    【解决方案1】:

    终于对这个主题做了一些研究,上面的场景根本不可能在 Spring Data Rest 中实现(我使用的是 2.4.1.RELEASE 版本)。

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

    有问题的代码在类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();
    } 
    

    最后,我还是硬着头皮导出了超类存储库以获取链接。

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 我已经改进了描述。 Party 不是 @MappedSuperclass(我使用的是 SINGLE_TABLE 继承策略),并且没有它的存储库。我有一个仅用于具体类的存储库 (Customer,OtherParty)。
      猜你喜欢
      • 2017-07-27
      • 2018-04-18
      • 2016-01-20
      • 2015-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-27
      • 2015-04-19
      相关资源
      最近更新 更多