2017-01-20 12 views
2

如果我有一個包含另一個類的對象,例如具有其中也考慮到如下相關的Publisher實體Book實體實體:在春季啓動JPA時,如何正確地將其實體表示具有外鍵關聯的對象發佈到不同的實體?

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

這是一個安全/正確的(我看到在這個例子中數據庫中的正確數據,但不能100%確定它是否可以在所有情況下工作)的方法來發布數據庫中具有外鍵關聯的對象?我不知道在交易原子性或線程方面是否安全,或者它是否有效。以下相關代碼:

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對象體(輸入到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<Book>表明新添加的書包含已存在的出版商PUB_CODE='SC'的實體信息(例如全名「Scholastic」)Publisher在數據庫中。

謝謝。

回答

0

您最初發布的技術(經過FK ID,在你的控制器手動取回,並明確設置它的實體)是有效和安全的。

我不知道一個更簡潔的方法,除非你移動到HATEOAS校長,這使得資源鏈接處理:http://projects.spring.io/spring-hateoas/

0

聽起來像你需要separate/decoupleRest Resources/ API specs,因爲他們可以以不同的速度發展。另外您的JPA選擇不應影響API specs

如若這感覺就像是你要追求有許多資源,在那裏,包括Best Practices for Better RESTful API

+0

請看看我的編輯。我對這個領域和服務如何分開有這樣的印象。這是錯的嗎? – ITWorker

相關問題