【问题标题】:Cannot create self link for class X. No persistent entity found无法为 X 类创建自链接。未找到持久实体
【发布时间】:2014-10-02 23:07:53
【问题描述】:

使用 Spring Data REST 时出现标题中的错误。如何解决?

派对.java:

@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, property="@class")
@JsonSubTypes({ @JsonSubTypes.Type(value=Individual.class, name="Individual") })
public abstract class Party {
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  protected Long id;

  protected String name;

  @Override 
  public String toString() {
    return id + " " + name;
  }

  ...getters, setters...
}

个人.java:

@Entity
public class Individual extends Party {

  private String gender;

  @Override
  public String toString() {
    return gender + " " + super.toString();
  }

  ...getters, setters...
}

PartyRepository.java:

public interface PartyRepository extends JpaRepository<Party,Long> {
}

如果我发布,它会正确保存到数据库:

POST /parties {"@class":"com.example.Individual", "name":"Neil", "gender":"MALE"}

但返回 400 错误:

{"cause":null,"message":"Cannot create self link for class com.example.Individual! No persistent entity found!"}

从存储库检索后看起来像是个人:

System.out.println(partyRepository.findOne(1L)); 
//output is MALE 1 Neil

看起来杰克逊可以确定这是一个人:

System.out.println( new ObjectMapper().writeValueAsString( partyRepository.findOne(1L) ) );
//output is {"@class":"com.example.Individual", "id":1, "name":"Neil", "gender":"MALE"}

为什么 SDR 想不通?

如何解决?最好使用 XML 配置。

版本:
SDR 2.2.0.RELEASE
SD JPA 1.7.0.RELEASE
Hibernate 4.3.6.Final

【问题讨论】:

    标签: spring-data spring-data-jpa spring-data-rest


    【解决方案1】:

    SDR 存储库需要一个非抽象实体,在您的情况下它将是个人。您可以在此处搜索或搜索有关 SDR 为何需要非抽象实体的解释。

    我自己尝试了您的代码,但 SDR 甚至无法用于 POST,我看到以下错误消息。

    {
        "cause": {
            "cause": null,
            "message": "Can not construct instance of com.spring.data.rest.test.Party, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information\n at [Source: org.apache.catalina.connector.CoyoteInputStream@30217e25; line: 1, column: 1]"
        },
        "message": "Could not read JSON: Can not construct instance of com.spring.data.rest.test.Party, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information\n at [Source: org.apache.catalina.connector.CoyoteInputStream@30217e25; line: 1, column: 1]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.spring.data.rest.test.Party, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information\n at [Source: org.apache.catalina.connector.CoyoteInputStream@30217e25; line: 1, column: 1]"
    }
    

    我建议你将存储库从 PartyRepository 更改为 IndividualRepository

    public interface IndividualRepository extends JpaRepository<Individual,Long> {
    }
    

    您看到该错误是因为 SDR 在构建链接时找不到引用个人的存储库。只需添加个人存储库而不导出它即可解决您的问题。

    @RepositoryRestResource(exported = false)
    public interface IndividualRepository extends JpaRepository<Individual,Long> {
    }
    

    【讨论】:

    • 谢谢。 1. 我需要在同一个响应中返回个人以及党(组织)的其他子类型。 2. 您是否在 JSON 中添加了“@class”="Individual"?
    • 抱歉没有注意到杰克逊注解@class。您的问题的解决方案是创建 IndvidualRepository 并设置为不导出。更新我的答案。
    猜你喜欢
    • 2021-03-24
    • 2015-01-15
    • 1970-01-01
    • 1970-01-01
    • 2012-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多