स्प्रिंग डेटा रीस्ट में एक @OneToMany उप-संसाधन संघ पोस्टिंग


103

वर्तमान में मेरे पास स्प्रिंग डेटा रीस्ट का उपयोग करके स्प्रिंग बूट एप्लिकेशन है। मेरे पास एक डोमेन इकाई है Postजिसका @OneToManyसंबंध किसी अन्य डोमेन इकाई से है Comment। ये वर्ग निम्नानुसार संरचित हैं:

Post.java:

@Entity
public class Post {

    @Id
    @GeneratedValue
    private long id;
    private String author;
    private String content;
    private String title;

    @OneToMany
    private List<Comment> comments;

    // Standard getters and setters...
}

Comment.java:

@Entity
public class Comment {

    @Id
    @GeneratedValue
    private long id;
    private String author;
    private String content;

    @ManyToOne
    private Post post;

    // Standard getters and setters...
}

उनके स्प्रिंग डेटा रीस्ट जेपीए रिपॉजिटरी मूल कार्यान्वयन हैं CrudRepository:

PostRepository.java:

public interface PostRepository extends CrudRepository<Post, Long> { }

CommentRepository.java:

public interface CommentRepository extends CrudRepository<Comment, Long> { }

आवेदन प्रविष्टि बिंदु एक मानक, सरल स्प्रिंग बूट अनुप्रयोग है। सब कुछ कॉन्फ़िगर स्टॉक है।

Application.java

@Configuration
@EnableJpaRepositories
@Import(RepositoryRestMvcConfiguration.class)
@EnableAutoConfiguration
public class Application {

    public static void main(final String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

सब कुछ सही ढंग से काम करता दिखाई देता है। जब मैं एप्लिकेशन चलाता हूं, तो सब कुछ सही ढंग से काम करता है। मैं http://localhost:8080/postsऐसा करने के लिए एक नई पोस्ट ऑब्जेक्ट पोस्ट कर सकता हूं :

तन: {"author":"testAuthor", "title":"test", "content":"hello world"}

परिणाम http://localhost:8080/posts/1:

{
    "author": "testAuthor",
    "content": "hello world",
    "title": "test",
    "_links": {
        "self": {
            "href": "http://localhost:8080/posts/1"
        },
        "comments": {
            "href": "http://localhost:8080/posts/1/comments"
        }
    }
}

हालाँकि, जब मैं GET पर प्रदर्शन करता हूं तो मुझे http://localhost:8080/posts/1/commentsएक खाली वस्तु {}वापस मिल जाती है, और अगर मैं उसी URI के लिए एक टिप्पणी पोस्ट करने की कोशिश करता हूं, तो मुझे HTTP 405 मेथड नॉट अलाउड मिलता है।

Commentसंसाधन बनाने और इसे इसके साथ जोड़ने का सही तरीका क्या है Post? http://localhost:8080/commentsयदि संभव हो तो मैं सीधे पोस्टिंग से बचना चाहूंगा ।


9
7 दिन बाद और अभी भी किस्मत नहीं। अगर किसी को इस व्यवहार को काम करने का तरीका पता है, तो कृपया मुझे बताएं। धन्यवाद!
ccampo

क्या आप @RepositoryRestResource या नियंत्रक का उपयोग कर रहे हैं? उस कोड को भी देखना उपयोगी होगा।
मैग्नस लस्सी

मैं वसंत बूट डेटा बाकी उपयोग कर रहा हूँ, यह मेरे लिए काम किया http://stackoverflow.com/questions/37902946/add-item-to-the-collection-with-foreign-key-via-rest-call
तैमूर

जवाबों:


47

आपको पहले टिप्पणी पोस्ट करनी होगी और टिप्पणी पोस्ट करते समय आप एक एसोसिएशन पोस्ट इकाई बना सकते हैं।

यह कुछ इस तरह दिखना चाहिए:

http://{server:port}/comment METHOD:POST

{"author":"abc","content":"PQROHSFHFSHOFSHOSF", "post":"http://{server:port}/post/1"}

और यह पूरी तरह से ठीक काम करेगा।


2
इसने मेरे लिए काम किया। बस यह सुनिश्चित करें author.postकि लेखन योग्य है (उदाहरण के लिए सेटर या @JsonValueएनोटेशन करके)
स्कैफिल्ड

1
क्या यह एक पैच अनुरोध के साथ भी काम करना चाहिए क्योंकि टिप्पणी को एक पोस्ट से दूसरे में ले जाना चाहिए?
एकैनाडल

2
यह मेरा (अत्यधिक) पसंदीदा तरीका होगा, लेकिन यह मेरे लिए काम नहीं करता है। :( यह टिप्पणी बनाता है, लेकिन संकल्प तालिका (POST_COMMENTS) में पंक्ति नहीं बनाता है। कैसे हल करने के लिए कोई सुझाव?
banncee

3
परिदृश्य के लिए दृष्टिकोण क्या होगा, उदाहरण के लिए स्थान और पता संस्थाओं के साथ, जहां एक स्थान का पता होना चाहिए और पता एक स्थान के साथ जुड़ा होना चाहिए? मेरा मतलब है ... एक अनाथ पता बनाने से बचने के लिए जिसे कभी भी कुछ भी नहीं सौंपा जा सकता है? हो सकता है कि Im गलत हो, लेकिन क्लाइंट ऐप कभी भी डेटाबेस के भीतर स्थिरता बनाए रखने के लिए जिम्मेदार नहीं होगा। मैं एक पता बनाने वाले क्लाइंट ऐप पर भरोसा नहीं कर सकता और फिर निश्चित रूप से एक वेन्यू को असाइन कर रहा हूं। क्या वास्तविक संसाधन के निर्माण के साथ उप-संसाधन (इस मामले में पता इकाई) को पोस्ट करने का कोई तरीका है ताकि मैं विसंगति से बच सकूं?
एपोस्ट्रोपीडॉटिल्ड

2
मैं ऐसा करने की कोशिश करता हूं ( यहां देखें ) लेकिन किसी कारणवश केवल संसाधन नहीं, एसोसिएशन बनाया जाता है।
डिस्प्लेनेम

55

आप पहले से ही URI और इस प्रकार एसोसिएशन संसाधन के URI ( $association_uriनिम्न में माना जाता है ) की खोज की है, यह आम तौर पर इन चरणों लेता है:

  1. संग्रह संसाधन प्रबंधन टिप्पणियों की खोज करें:

    curl -X GET http://localhost:8080
    
    200 OK
    { _links : {
        comments : { href : "…" },
        posts :  { href : "…" }
      }
    }
  2. संसाधन के लिए commentsलिंक और POSTअपने डेटा का पालन करें :

    curl -X POST -H "Content-Type: application/json" $url 
    {  // your payload // … }
    
    201 Created
    Location: $comment_url
  3. PUTएसोसिएशन URI को एक जारी करके पोस्ट पर टिप्पणी को असाइन करें ।

    curl -X PUT -H "Content-Type: text/uri-list" $association_url
    $comment_url
    
    204 No Content

ध्यान दें, कि अंतिम चरण में, के विनिर्देश के अनुसार text/uri-list, आप एक से अधिक टिप्पणियों को असाइन करने के लिए लाइन ब्रेक द्वारा अलग किए गए टिप्पणियों की पहचान करने वाले कई यूआरआई प्रस्तुत कर सकते हैं।

सामान्य डिजाइन निर्णयों पर कुछ और नोट्स। एक पोस्ट / टिप्पणियों उदाहरण आमतौर पर एक समग्र, जो साधन रहा से वापस-संदर्भ से बचने के हैं, उसके लिए बहुत अच्छा उदाहरण है Commentकरने के लिए Postहै और यह भी से बचने के CommentRepositoryलिए पूरी तरह से। यदि टिप्पणियों में अपने आप में एक जीवनचक्र नहीं है (जो वे आमतौर पर एक रचना-शैली संबंध में नहीं हैं) तो आप टिप्पणियों को सीधे इनलाइन प्रदान करते हैं और टिप्पणियों को जोड़ने और हटाने की पूरी प्रक्रिया का उपयोग करके इससे निपटा जा सकता है JSON पैच । स्प्रिंग डेटा रीस्ट ने आगामी संस्करण 2.2 के लिए नवीनतम रिलीज़ उम्मीदवार में इसके लिए समर्थन जोड़ा है ।


4
नीचे के मतदाताओं से यहां पूछा गया, वोटों का कारण क्या था;)।
ओलिवर ड्रोट्बोहम

3
मैं नीचे मतदाताओं के बारे में निश्चित नहीं हूँ ... मेरे पास ऐसा करने के लिए प्रतिष्ठा भी नहीं है! कारण यह है कि मैं जरूरी नहीं है कि पोस्ट के साथ टिप्पणी इनलाइन डालना पसंद करता हूं, क्योंकि जब मैं किसी एक पोस्ट के लिए हजारों टिप्पणियां करता हूं, तो (अप्रभावित) परिदृश्य पर विचार करें। मैं हर बार जब मैं पोस्ट की सामग्री का उपयोग करना चाहता हूं, तो उनके पूरे समूह को प्राप्त करने के बजाय टिप्पणियों के संग्रह को शांत करने में सक्षम होना चाहता हूं।
ccampo

25
मेरे लिए टिप्पणी पोस्ट करने का सबसे सहज तरीका लोकलहोस्ट के लिए एक POST बनाना है : 8080 / पोस्ट / 1 / टिप्पणी । क्या यह करने का सबसे सरल और सबसे सार्थक तरीका नहीं है? और एक ही समय में, आपको अभी भी एक समर्पित टिप्पणी भंडार करने में सक्षम होना चाहिए। क्या यह वसंत या एचएएल मानक है जो इसे अनुमति नहीं देता है?
ऐकानडाल

4
@OliverGierke क्या यह अभी भी ऐसा करने के लिए अनुशंसित / एकमात्र तरीका है? यदि बच्चा अशक्त ( @JoinColumn(nullable=false)) नहीं है तो क्या होगा ? पहले बच्चे को पोस्ट करना संभव नहीं होगा, फिर पेरेंट एसोसिएशन को PUT / PATCH करें।
JW Lim

2
क्या स्प्रिंग डेटा रेस्ट के साथ बनाई गई एपी का उपयोग करने के लिए कोई गाइड है? मैं इसे 2 घंटे के लिए googled और कुछ नहीं मिला है। धन्यवाद!
Skeeve

2

मानचित्रण संघ और संरचना के 2 प्रकार हैं। एसोसिएशन के मामले में हमने टेबल कांसेप्ट जैसे इस्तेमाल किया

कर्मचारी - 1 से n-> विभाग

तो एसोसिएशन कर्मचारी, विभाग, Employee_Depbox के मामले में 3 तालिकाओं का निर्माण किया जाएगा

आपको केवल कोड में EmployeeRepository बनाना होगा। इसके अलावा मैपिंग इस तरह होनी चाहिए:

class EmployeeEntity{

@OnetoMany(CascadeType.ALL)
   private List<Department> depts {

   }

}

डिपॉज़िट एंटिटी में forign key के लिए कोई मैपिंग नहीं होगी ... इसलिए अब जब आप डिप्लॉयमेंट को डिपार्टमेंट में एम्प्लॉयी के साथ जोड़ने के लिए POST रिक्वेस्ट को सिंगल जोंस रिक्वेस्ट में ट्राय करेंगे तो वह जुड़ जाएगा ...।


1

मुझे उसी परिदृश्य का सामना करना पड़ा और मुझे उप-इकाई के लिए रिपॉजिटरी वर्ग को हटाना पड़ा क्योंकि मैंने एक से कई मैपिंग का उपयोग किया है और मुख्य इकाई के माध्यम से डेटा को खींचता हूं। अब मुझे डेटा के साथ पूरी प्रतिक्रिया मिल रही है।


1
यह बात जो आप बात करते हैं, वह अनुमानों के साथ आसानी से हो सकती है
kboom

0

OneToMany मैपिंग के लिए, बस उस वर्ग के लिए एक POJO बनाएं जिसे आप मैप करना चाहते हैं, और @OneToMany एनोटेशन को इसके लिए, और आंतरिक रूप से यह उस टेबल आईडी पर मैप कर देगा।

इसके अलावा, आपको उस वर्ग के लिए सीरियल इंटरफ़ेस को लागू करने की आवश्यकता है जिसे आप डेटा पुनर्प्राप्त कर रहे हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.