【问题标题】:Post relational data, Spring JPA REST发布关系数据,Spring JPA REST
【发布时间】:2017-03-13 16:48:24
【问题描述】:

我有一个关系数据库,其中包含规范化形式的数据,但我的 API 需要以非规范化方式接收信息,处理此问题的正确方法是什么?是否需要创建一个具有非规范化字段的新端点?

我如何将它与数据库分离,以便 Spring Boot 不会为我创建新表?

例如,这是我的(一些)表格:

@Entity
public class TestCase {
    @Id @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    private String name;
    private String description;
}

@Entity
public class TestRun {
    @Id @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;    
    private Boolean result;
    private String username;
    @OneToOne 
    private TestData testData;
    @ManyToOne 
    private TestCase testCase;
 }

@Entity
public class TestData {
    @Id @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    private int count;
    @ManyToOne 
    private RecordType recordType;
}

我想创建一个 API 端点,该端点将同时在 TestRun 和 TestData 中创建新条目,同时引用 TestCase 和 RecordType 中的现有条目。

这是怎么做到的?

需要显示完整的答案:

  • 数据在发布到服务器时采用什么格式
  • 哪个组件将处理该帖子
  • 该组件将如何更新不同的实体

【问题讨论】:

  • 非规范化是什么意思?
  • 当我将数据发送到我的 API 时,我想将上面显示的所有字段作为单个请求发送。但我希望将这个请求分解并放入正确的表格中。
  • 您可以发送带有 2 个对象的唯一请求,该请求会将它们读取为 2 个对象,然后您可以根据需要处理它们并将第一个保存到一个表中,然后再保存其他或任何您需要的.此外,如果您将 cascadeType=PERSIST 添加到仅保存父对象的关系中,则将存储所有关系
  • 按照我的理解,每个对象都有自己的 API 端点,那么如何将多个不同的对象发送到一个端点?或者,我可以发送多个请求,但我不确定这将如何工作。如果我发布到 /TestData,我如何表明我希望它与特定的 TestRun id 号(我刚刚创建的)链接?
  • 让我们想象一下,您想创建一个 TestData 类型的对象,然后创建一个 URL /testData (POST),在该请求中您将收到一个 TestData 类型的对象,该对象与RecordType,所以你可以在你的 TestData 对象中说,当你持久化、更新、删除......主要对象 TestData,你想在级联中添加操作,你应该添加到你的 TestData 类:@ManyToOne(fetch = FetchType. LAZY, cascade = CascadeType.PERSIST) 则对象将仅在一个请求操作中创建

标签: hibernate spring-mvc jpa spring-boot h2


【解决方案1】:

如果您在持久化 TestRun 对象时将 @Cascade({CascadeType.SAVE_UPDATE}) 添加到所有 @OneToOne@ManyToOne 关系中,则所有现有对象也应该被持久化。

 public class TestRun {
    @Id 
            @GeneratedValue(strategy = GenerationType.AUTO)
            @Column(name="id", columnDefinition = "numeric")
            private Long id;  //Long so default value is null
            @Column(name="result", columnDefinition ="nchar")
            private Boolean result;
            @Column(name="username")
            private String username;

            @OneToOne
            @JoinColumn(name="id_data")
            @Cascade({CascadeType.SAVE_UPDATE})
            private TestData testData;

            @OneToOne
            @JoinColumn(name="id_case")
            @Cascade({CascadeType.SAVE_UPDATE})
            private TestCase testCase;
}

输入: { "result" : "true", "username" : "clickcell", "testData" : { "count" : "10" }, "testCase" : { "name" : "test1", "description" : "the first test" } }

【讨论】:

  • 谢谢,您能否详细说明我将如何将数据发布到 API?我可以在一个 POST 中发送所有数据吗?我可以通过 ID 号引用现有记录吗?例如我想说我有一个通过的新测试运行(测试用例 id6),它创建了 5 条测试数据记录(记录类型 id4)。
  • 您将能够在一个帖子中发送所有数据。在帖子中发送的对象必须与 TestRun 中的字段结构相匹配。如果有 id,实体管理器将更新数据库中的现有行并插入没有 id 的行。
  • 问题是如何。假设我发送 { "result" : "true", "username" : "clickcell", "testData" : { "count" : "10", "recordType" : "4" }, "testCase" : {"name" : "test1", "description" : "the first test"} } 它不起作用,因为它将 testData 对象创建为空白。你明白我现在在问什么了吗?
  • 我的问题是:实体的 id 应该是 Long 以便默认值为 null,否则值为 ) 并且不会更新或保存新行。除此之外,你的 json 应该是正确的。
  • 谢谢我明白你的意思了,把小写的long改成大写的Long。我已经尝试过了,但我的行为似乎没有改变。没有任何东西被添加到 testData
猜你喜欢
  • 1970-01-01
  • 2021-08-17
  • 2018-08-01
  • 1970-01-01
  • 2014-07-09
  • 2016-05-19
  • 1970-01-01
  • 2017-11-13
  • 1970-01-01
相关资源
最近更新 更多