【问题标题】:Spring Data REST: Return One-To-Many-To-One as Many-To-Many relationSpring Data REST:将一对多对一作为多对多关系返回
【发布时间】:2019-07-22 10:10:35
【问题描述】:

我想用 Spring Boot 和 Spring Data REST 构建一个简单的 HATEOAS API。

因此,我创建了 2 个不同的实体 A 和 B。两者之间存在多对多关系。因为该关系还需要 2 个属性,所以我用这些属性添加了一个新的关系 R。

对于 API,只有 A 和 B 应该是可见的,R 只是内部的并且没有存储库。我想用指向 B 集合的链接来表示 A。

应该可以在不提供和返回 R 的内部属性的情况下创建 A、创建 B、将 A 链接到 B 或 B 到 A。

我猜是设计问题?

可能的解决方案:

我尝试创建一个自定义方法 findByR_Bid() 但我无法为该方法提供自己的 id,因此“/a/b”是不可能的,它始终是“/a/search/...”。

接下来,我添加了一个带有 ResponseEntities.linkToCollection(B.class) 的自定义链接,但这将表示一个指向“/b​​”的链接,而不引用 A 自己的 id。

接下来,我在 A 中实现了一个从 R 返回 List 的方法。但是这个列表作为属性包含在内部,而不是创建一个 Link。

位码:

@Entity
public class A {
  @Id
  private Long id;

  @OneToMany(mappedBy = "a")
  private List<R> r;

  // getters
}

@Entity
public class B {
  @Id
  private Long id;

  @OneToMany(mappedBy = "b")
  private List<R> r;

  // getters
}

@Entity
public class R {
  @Id
  private Long id;

  @ManyToOne(optional = false)
  private A a;

  @ManyToOne(optional = false)
  private B b;

  // internal properties

  @JsonIgnore
  private String foo;

  @JsonIgnore
  private String bar;

  // getters
}

对于 JSON 响应,我想要这样的东西:

获取 /a/1

"_links" : {
    "self": {
        "href": "http://localhost:8080/a/1"
    },
    "a": {
        "href": "http://localhost:8080/a/1"
    },
    "bs": {
        "href": "http://localhost:8080/a/1/b{?page,size,sort}",
        "templated": true
    }
}

【问题讨论】:

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


    【解决方案1】:

    这很棘手,但并非不可能!

    您可以使用同一张表以多对多关系(反之亦然)将 B 添加到 A:

    @Entity
    public class A {
      @Id
      private Long id;
    
      @OneToMany(mappedBy = "a")
      private List<R> r;
    
      @ManyToMany
      @JoinTable(name = "table_r", inverseJoinColumns = { @JoinColumn(name = "b_id") })
      private list<B> b;
    
      // getters
    }
    

    通过这种方式,您可以强制 hibernate 将同一个表用于支持 R 实体的多对多关系。 Spring Data Rest 还将这种多对多关系映射到端点,因此/a/1/bs 将起作用。

    但是,访问关系的额外属性仍然很棘手。 (您需要使用 /search 端点。)

    另一种解决方案,如果您为 R(来自 A+B)而不是标准 id 创建复合键。 (实际上已经存在,因为多对多关系的支持表一个基于a_id+b_id的复合键) 如果为复合键创建转换器,则可以访问关系属性,例如: /R/23-34(a-23 和 b-34 的关系)

    这不是太好,但很管用。

    【讨论】:

    • 使用@JoinTable 注释的好主意。我会试试这个。谢谢!
    猜你喜欢
    • 2021-10-26
    • 1970-01-01
    • 1970-01-01
    • 2018-04-14
    • 2017-08-19
    • 2022-01-20
    • 2014-03-18
    • 2014-12-10
    • 1970-01-01
    相关资源
    最近更新 更多