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 存储库,以便获得链接。
具有以下实体(省略不相关的字段):
@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 存储库,以便获得链接。