Spring Data REST - 抽象类型

时间:2015-12-18 16:58:19

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

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

@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"
    },
  }
}

2 个答案:

答案 0 :(得分:2)

最后对该主题做了一些研究,上面的场景根本无法在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();
} 

最后,我确实咬了一口子并导出了超类库,以便有链接。

答案 1 :(得分:0)

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

了解你的Party超类是如何映射的 - 这是@MappedSuperclass

也很有趣