Jackson模块在Spring Data REST中处理抽象聚合根及其子类

Pat*_*čin 5 jackson spring-data spring-data-rest

我有基于Spring Data REST的应用程序和存储库

public interface CriterionRepository extends JpaRepository<Criterion, Long> {
}
Run Code Online (Sandbox Code Playgroud)

Criterion基类是:

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class Criterion extends AbstractEntity {}
Run Code Online (Sandbox Code Playgroud)

并且NameCriterion是它的子类

@Entity
public class NameCriterion extends Criterion {
    private final String name;
}
Run Code Online (Sandbox Code Playgroud)

Spring Data REST将存储库导出为REST资源,可以在http:// localhost:8080/api/criteria /访问它

导出的资源如下所示:

{
    "_embedded": {
        "nameCriteria": [{
                "_links": {
                    "self": {
                        "href": "http://localhost:8080/api/nameCriterion/1"
                    },
                    "nameCriterion": {
                        "href": "http://localhost:8080/api/nameCriterion/1"
                    }
                }
            }
        ]
    },
    "_links": {
        "self": {
            "href": "http://localhost:8080/api/criteria"
        },
        "profile": {
            "href": "http://localhost:8080/api/profile/criteria"
        }
    },
    "page": {
        "size": 20,
        "totalElements": 1,
        "totalPages": 1,
        "number": 0
    }
}
Run Code Online (Sandbox Code Playgroud)

当我尝试关注自我链接时,http:// localhost:8080/api/nameCriterion/1没有映射

我可以按照http:// localhost:8080/api/criteria/1进行操作,但我得到的响应没有名称字段NameCriterion

{
    "_links": {
        "self": {
            "href": "http://localhost:8080/api/nameCriterion/1"
        },
        "nameCriterion": {
            "href": "http://localhost:8080/api/nameCriterion/1"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的假设是它与REST出口定义杰克逊映射器未被正确调整了处理抽象类问题Criterion中所使用JpaRepository的总根源.

我应该申请杰克逊的定制,以使其正常运作?

换句话说,我应该创建什么杰克逊模块?

Cep*_*pr0 3

无需创建 Jackson 模块。要对继承的实体使用单个表,我们可以使用 @RestResource 注释将它们标记为相同的资源:

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Table(name = "criteria")
public abstract class Criterion extends AbstractEntity {
}

@RestResource(rel = "criteria", path = "criteria")
@Entity
public class NameCriterion extends Criterion {

    private String name;
}

@RestResource(rel = "criteria", path = "criteria")
@Entity
public class TitleCriterion extends Criterion {

    private String title;
}

@RepositoryRestResource(path = "criteria", collectionResourceRel = "criteria", itemResourceRel = "criterion")
public interface CriterionRepository extends JpaRepository<Criterion, Long> {
}
Run Code Online (Sandbox Code Playgroud)

因此可以在一个输出中获取所有资源(NameCriterion 和 TitleCriterion):

GET http://localhost:8080/api/criteria

{
  "_embedded": {
    "criteria": [
      {
        "name": "name1",
        "_links": {
          "self": {
            "href": "http://localhost:8080/api/criteria/1"
          },
          "nameCriterion": {
            "href": "http://localhost:8080/api/criteria/1"
          }
        }
      },
      {
        "title": "title1",
        "_links": {
          "self": {
            "href": "http://localhost:8080/api/criteria/2"
          },
          "titleCriterion": {
            "href": "http://localhost:8080/api/criteria/2"
          }
        }
      }
    ]
  }
}

GET http://localhost:8080/api/criteria/1
{
  "name": "name1",
  "_links": {
    "self": {
      "href": "http://localhost:8080/api/criteria/1"
    },
    "nameCriterion": {
      "href": "http://localhost:8080/api/criteria/1"
    }
  }
}

GET http://localhost:8080/api/criteria/2
{
  "title": "title1",
  "_links": {
    "self": {
      "href": "http://localhost:8080/api/criteria/2"
    },
    "titleCriterion": {
      "href": "http://localhost:8080/api/criteria/2"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

工作示例