首页 > 解决方案 > 使用现有关系创建新模型

问题描述

所以我有一个模型叫做Issue,这个模型有一个关系叫做IssueType
AIssue有一个type_id,它将它们链接在一起。
AIssueType有 aid和 aname是唯一的。

问题是当我想创建一个问题时,我想发送这样的请求

POST https://server/issues
Content-Type: application/json

{
  "description": "just some random description",
  "type": "Generic"
}

所以这里type是 的name,IssueType创建它时。

我该怎么做呢?

@Table(name = "issues")
@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
public class Issue {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "description")
    private String description;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "type_id", referencedColumnName = "id")
    private IssueType type;
}
@Table(name = "issue_types")
@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
public class IssueType {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column()
    private String name;
}
@RepositoryRestResource(
    collectionResourceRel = "issues",
    path = "issues",
    excerptProjection = IssueProjection.class
)
public interface IssueRepository extends JpaRepository<Issue, Long> {
}
@Projection( types = Issue.class)
public interface IssueProjection {
    Long getId();

    Double getLongitude();

    Double getLatitude();

    Integer getFloor();

    String getDescription();

    @Value("#{target.type.name}")
    String getType();
}

标签: springhibernatespring-data-jpaspring-data-rest

解决方案


我相信您在这里想要的是 Spring Data Rest 所指的定义查找类型:

很多时候,域模型包含的类型是值对象,但实际上代表了一组专用的可能值中的特定值。上面示例的 Country 类实际上属于该类别。因为我们需要管理超级值集,所以有一个存储库。如果还应允许它通过 REST 管理集合,则也需要导出存储库。由于存储库通常指示正在管理的聚合,因此 Spring Data REST 处理该场景的默认方式是在遇到 Country 实例的任何地方呈现到关联资源的链接。 Hopper 发布系列增加了声明所谓的查找类型的方法,然后 Spring Data REST 会为此呈现一个内联在表示中的单个属性,并注册相应的 Jackson Deserializer 以确保该属性值被转换回该值的实例PUT 和 POST 请求的类型。

https://spring.io/blog/2016/05/03/what-s-new-in-spring-data-hopper#lookup-types

https://docs.spring.io/spring-data/rest/docs/current/reference/html/#_customizing_item_resource_uris

所以像:

  @Override
  public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
    config.withEntityLookup()
      .forRepository(IssueType.class)
      .withIdMapping(IssueType::name)
      .withLookup(IssueTypeRepository::findByName); 
  }
}

推荐阅读