Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring数据REST连接继承问题_Java_Jpa_Spring Data_Spring Data Rest - Fatal编程技术网

Java Spring数据REST连接继承问题

Java Spring数据REST连接继承问题,java,jpa,spring-data,spring-data-rest,Java,Jpa,Spring Data,Spring Data Rest,我在一个JPA实体上有一个Spring数据存储库。该实体通过联合继承进行子类化 SpringDataREST似乎在解释这种结构时遇到了问题,至少是自动地。或者我误解了继承的用法。加入了 对具有事件的任何实体的任何请求都会返回以下内容: { cause: null, message: "Cannot create self link for class com.foo.event.SubEvent! No persistent entity found!" } 也许我对这个项目的

我在一个JPA实体上有一个Spring数据
存储库
。该实体通过联合继承进行子类化

SpringDataREST似乎在解释这种结构时遇到了问题,至少是自动地。或者我误解了继承的用法。加入了

对具有
事件的任何实体的任何请求都会返回以下内容:

{
    cause: null,
    message: "Cannot create self link for class com.foo.event.SubEvent! No persistent entity found!"
}
也许我对这个项目的要求太高了,不知道如何处理这个问题,但是是否有一种变通方法可以将我所有的
事件
分组到同一个
/Events
下?甚至可以让我根据类型过滤

我在下面留下了应用程序结构的基础知识

Event.java

SubEvent.java

EventRepository.java

@RepositoryRestResource(path=“events”)
公共接口事件存储库扩展了分页和排序存储库{
...    
}

我认为这个问题与JPA无关,而是一个循环序列化问题。由于您没有显示实体,我只能假设子事件实体与另一个(子)事件有关系,并且一个子事件引用自身,这导致了问题。当然,也有可能这种关系不是直接的,而是通过一些其他实体类,如SubEvent->EntityG->Event


要解决这个问题,只需使用一个函数,其中只映射子事件的所有字段,而不映射那些产生循环依赖项的字段。

我认为您缺少使用
鉴别器来让JPA了解对给定对象使用哪个子类(它如何知道其他情况?)

我倾向于使用抽象类来表示table per子类hireachies,因此这里有一个适合您的示例:

Event.java

SubEvent.java

使用上面的代码,您会注意到一些奇怪的事情—但是,当为其中一个对象生成资源路径时,它假定您为每个子类都有一个
存储库
,并生成如下内容:

{
  "type" : "subevent",
  "code" : "bacon",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8081/subEvents/1"
    },
    "peeringService" : {
      "href" : "http://localhost:8081/subEvents/1"
    }
  }
}
但这很容易修复,只需将以下注释添加到基类:

@RestResource(path = "events")
它将生成您期望的资源路径


希望这有帮助:)

我在一个简单的spring boot项目中试用了您的类,它们没有给我任何问题,我无法重现您遇到的问题。但是,在您描述的错误消息上搜索会给出一些帖子,建议您需要创建一个
子事件
存储库,即使您不使用它,并且问题会出现在更复杂的项目中,例如使用REST

参考文献:

因此,请尝试添加子事件存储库:

interface SubEventRepository extends CrudRepository<SubEvent, Long> {
}
接口子事件存储库扩展了Crudepository{
}

我尝试了很多选项,但没有一个像预期的那样有效,而且在某一点上总是有问题(链接生成、存储库映射、url映射等等)

即使对于分离的存储库(每个子类型一个),我也没有成功。我的“脏兮兮但仍在工作”解决方案是使用
ResourceProcessor
实现对所有子类型的链接进行后期处理。这个实现基本上用资源上存在的每个链接上的类型名替换了子类型名


此外,还引入了
RelProvider
来处理不同类型的属性名称。

Hey Andrei。在这个练习中,实体的命名可能很糟糕,因为我只是为了这个问题而擦洗了它们。实际上,此模型中没有循环引用:-/为了找到原因并最终确保没有循环引用,请开始逐个注释JPA映射属性,直到找到问题的原因。使用spring data rest 2.5.1的此解决方案不起作用,感谢大家的提醒,我正在运行
2.4.4.RELEASE
(当前
spring boot
推荐的版本)。下周我将在新版本上试一试:)在我的例子中,似乎只有一个(不确定的)存储库(具有相同的路径)处理了请求,这导致rest控制器只提供了部分行(只有存储库负责的行)。让我知道你的测试进展如何,我很想知道解决方案。问题不仅仅在于
连接的继承类型。使用
单表
时也会发现同样的问题。
@Entity
@DiscriminatorColumn(name = "type")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Event {
    @Id
    @GeneratedValue
    public Long id;

    public String type;
}
@Entity
@DiscriminatorValue("subevent")
@PrimaryKeyJoinColumn(name = "event_id")
public class PeeringService extends Service {
    private String code;
}
{
  "type" : "subevent",
  "code" : "bacon",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8081/subEvents/1"
    },
    "peeringService" : {
      "href" : "http://localhost:8081/subEvents/1"
    }
  }
}
@RestResource(path = "events")
interface SubEventRepository extends CrudRepository<SubEvent, Long> {
}