在 spring boot JPA 中,如何正确 POST 一个对象,其实体表示具有与不同实体的外键关联? [英] In spring boot JPA, how to properly POST an object whose entity representation has a foreign key association to a different entity?

查看:37
本文介绍了在 spring boot JPA 中,如何正确 POST 一个对象,其实体表示具有与不同实体的外键关联?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一个包含另一个类的对象的实体,例如一个 Book 实体,其中包含一个 Publisher 实体,其关联如下:

If I have a entity that contains an object of an another class, for example a Book entity that has within it a Publisher entity that is associated as follows:

@ManyToOne
@JoinColumn(name="PUB_CODE", referencedColumnName = "PUB_CODE")
private Publisher pub;

在数据库中发布具有外键关联的对象的方法是否安全/正确(我在本示例中在数据库中看到了正确的数据,但不能 100% 确定它是否适用于所有情况)?我不知道这在事务原子性或线程方面是否安全,或者是否有效.相关代码如下:

Is this a secure/correct (I saw the correct data in the DB in this example, but not 100% sure if it would work in all cases) approach to post an object that has foreign key association in the database? I don't know if this is safe to do in terms of transaction atomicity or in terms of threading, or if it is efficient. Relevant code below:

Book.java

package app.domain;

/*imports*/

@Entity
public class Book implements Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = -6902184723423514234L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @Column(nullable = false, unique=true)
    private String bookName;

    @Column(nullable = false)
    private int pageCount;

    @ManyToOne
    @JoinColumn(name="PUB_CODE", referencedColumnName="PUB_CODE")
    private Publisher pub;


    /*public getters and setters*/

}

Publisher.java

package app.domain;

/*imports*/

@Entity
public class Publisher implements Serializable {

    private static final long serialVersionUID = 4750079787174869458L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @Column(name="PUB_CODE",nullable = false, unique = true)
    private String publisherCode;

    @Column(nullable = false)
    private String publisherName;

    /*public getters and setters*/

}

BookRepo.java

package app.service;

/*imports*/

public interface BookRepo extends JpaRepository<Book, Long>{

    @Query("SELECT pb FROM Publisher pb WHERE pb.publisherCode = TRIM(UPPER(:pubCode))")
    public Publisher findPublisherByPubCode(@Param("pubCode")String pubCode);
}

BookController.java

package app.controller;

/*imports*/

@RestController
@RequestMapping(value = "/books")
public class BookController {

    private BookRepo bookRepo;

    @Autowired
    public BookController(BookRepo bookRepo) {
        this.bookRepo = bookRepo;
    }
    //The ApiPathParam is for JSONDOC purposes
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    public List<Book> create(@ApiPathParam(name = "book") @RequestBody Book book, @ApiPathParam(name = "pubCode") @RequestParam("pubCode") String pubCode) {
        // Assume exception handling
        Publisher pbToAttachToThisBook = bookRepo.findPublisherByPubCode(pubCode);
        book.setPub(pbToAttachToThisBook);
        bookRepo.save(book);
        return bookRepo.findAll();
    }
}

发布对象正文(输入到 POST 工具中):

{
  "bookName": "goosebumps",
  "id": 0,
  "pageCount": 332,
  "pub": {
    "id": 0,
    "publisherCode": "",
    "publisherName": "",
    "serialVersionUID": 0
  },
  "serialVersionUID": 0
}

提供的pubCode参数输入,也输入到POST工具中,与上面相同的调用:'SC'

上述代码执行后,在Book表中,出现了上面那本书的条目,其PUB_CODE外键列填充了'SC', 并且返回的 POST 控制器方法的 List 显示新添加的书包含了 Publisher 实体信息(如全名Scholastic") 用于已存在于数据库中的 PUB_CODE='SC' 的发布商.

After the above code was executed, in the Book table, there was an entry for the book above, with its PUB_CODE foreign key column filled in with 'SC', and the returned List<Book> of the POST controller method that was called showed that the newly added book included the Publisher entity information (such as the full name "Scholastic") for publisher with PUB_CODE='SC' that was already existing in the database.

谢谢.

推荐答案

您最初发布的技术(传递 FK ID,在控制器中手动检索它,并在实体上显式设置它)是有效且安全的.

The technique you posted originally (passing the FK ID, retrieving it manually in your controller, and setting it on the entity explicitly) is valid and secure.

>

我不知道有什么更简洁的方法,除非你转向 HATEOAS 主体,它允许处理资源链接:http://projects.spring.io/spring-hateoas/

这篇关于在 spring boot JPA 中,如何正确 POST 一个对象,其实体表示具有与不同实体的外键关联?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆