2017-01-20 11 views
2

私は別のクラスのオブジェクトを含むエンティティを持っている場合は、例えばその中に次のように関連しているPublisher実体があるBookエンティティ:バネブートJPAでは、エンティティ表現が別のエンティティへの外部キーの関連付けを持つオブジェクトを適切にPOSTする方法はありますか?

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

はこれが正しい/安全である(私が見ましたこの例ではDB内の正しいデータですが、すべてのケースで動作するかどうかは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パラメータ入力: 'SC'

上記のコードが実行された後、ブックテーブルには、上記の書籍のエントリがあり、そのPUB_CODEの外部キー列に'SC'と記入され、呼び出されたPOSTコントローラメソッドのList<Book>が返され、新しく追加された書籍にはPUB_CODE='SC'のエンティティ情報(例:フルネーム「Scholastic」)Publisherが既に存在していたデータベースに格納されます。

ありがとうございます。

答えて

0

あなたはもともと掲示技術(あなたのコントローラで手動で検索し、FK IDを渡して、明示的実体でそれを設定するなど、そこに資源のそこに多くを追求したい何かのように感じるはず)は有効で安全です。

あなたはリソースリンクの処理が可能になりますHATEOASプリンシパルに移動しない限り、私はクリーンなアプローチを知らない:私の編集を参照してくださいhttp://projects.spring.io/spring-hateoas/

0

data layer's domain modelからseparate/decoupleあなたのRest Resources/ API specsからあなたは異なるペースで進化することができるように思えます。また、JPAの選択はAPI specsに影響してはなりません。

これはあなたがBest Practices for Better RESTful API

+0

してください。私はドメインとサービスをどのように分離するかをこの印象の下にしていました。違いますか? – ITWorker

関連する問題