2014-06-26 14 views
11

के साथ कई एसोसिएशन लिंक का पता लगाया है, मैं एक साधारण स्प्रिंग ऐप करने की कोशिश कर रहा हूं। इसे आरईएसटी एंडपॉइंट्स का पर्दाफाश करने और इसे एक रिलेशनल डेटाबेस में सहेजने की जरूरत है।स्प्रिंग डेटा आरईएसटी - एक ही रिलेशन प्रकार

मैंने आपकी नमूना परियोजना, http://spring.io/guides/gs/accessing-data-rest/ लिया। मैं आपकी मार्गदर्शिका में उल्लिखित सभी परिचालन (पोस्ट, पैच, पुट, जीईटी) करने में सक्षम हूं।

हालांकि मैंने व्यक्ति इकाई वर्ग में संबंध जोड़ने की कोशिश की और चीजों को अलग करना शुरू हो गया।

@Entity 
public class Person { 

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

    private String firstName; 
    private String lastName; 

    @OneToOne(cascade = {CascadeType.ALL}) 
    private PersonDetails personDetails; 

    @OneToOne(cascade = {CascadeType.ALL}) 
    private PersonChildren personChildren; 

    ///Getter and setters for everything except id. 
} 


@Entity 
public class PersonChildren { 

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

    private String childFirstName; 
    private String childLastName; 

    @OneToOne(mappedBy="personChildren", optional=false) 
    private Person person; 

///Getter and setters for everything except id. 
} 


@Entity 
public class PersonDetails { 

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

    private String email; 
    private String phoneNumber; 

    @OneToOne(mappedBy="personDetails",optional=false) 
    private Person person; 

///Getter and setters for everything except id. 
} 


@RepositoryRestResource(collectionResourceRel = "people", path = "people") 
public interface PersonRepository extends PagingAndSortingRepository<Person, Long> { 

    List<Person> findByLastName(@Param("name") String name); 

} 

build.gradle

buildscript { 
    repositories { 
     maven { url "http://repo.spring.io/libs-release" } 
     mavenLocal() 
     mavenCentral() 
    } 
    dependencies { 
     classpath("org.springframework.boot:spring-boot-gradle-plugin:1.1.1.RELEASE") 
    } 
} 

apply plugin: 'java' 
apply plugin: 'eclipse' 
apply plugin: 'idea' 
apply plugin: 'spring-boot' 

jar { 
    baseName = 'gs-accessing-data-rest' 
    version = '0.1.0' 
} 

repositories { 
    mavenLocal() 
    mavenCentral() 
    maven { url "http://repo.spring.io/libs-release" } 
} 

dependencies { 
    compile("org.springframework.boot:spring-boot-starter-web") 
    compile("org.springframework.boot:spring-boot-starter-data-jpa") 
    compile("com.h2database:h2") 
    compile("org.springframework.data:spring-data-rest-webmvc") 
} 

task wrapper(type: Wrapper) { 
    gradleVersion = '1.11' 
} 

कॉल:

$ curl -i -X POST -H "Content-Type:application/json" -d '{ "firstName":"John", "lastName": "Doe", "personDetails": { "email": "[email protected]", "phoneNumber": "001-002-0003" }, "personChildren": {"childFirstName": "Mary", "childLastName": "Martin" } }' <code> http://localhost:8080/people </code> 

Response: 
HTTP/1.1 201 Created 
Server: Apache-Coyote/1.1 
<code> 
Location: http://localhost:8080/people/1 
</code> 
Content-Length: 0 
Date: Thu, 26 Jun 2014 05:42:45 GMT 

$ curl http://localhost:8080/people 

{ 
    "timestamp" : 1403761371011, 
    "status" : 500, 
    "error" : "Internal Server Error", 
    "exception" : "org.springframework.http.converter.HttpMessageNotWritableException", 
    "message" : "Could not write JSON: Detected multiple association links with same relation type! Disambiguate association @javax.persistence.OneToOne(optional=false, targetEntity=void, cascade=[], fetch=EAGER, orphanRemoval=false, mappedBy=personChildren) private com.ds.dao.rest.Person com.ds.dao.rest.PersonChildren.person using @RestResource! (through reference chain: org.springframework.hateoas.PagedResources[\"_embedded\"]->java.util.UnmodifiableMap[\"people\"]->java.util.ArrayList[0]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Detected multiple association links with same relation type! Disambiguate association @javax.persistence.OneToOne(optional=false, targetEntity=void, cascade=[], fetch=EAGER, orphanRemoval=false, mappedBy=personChildren) private com.ds.dao.rest.Person com.ds.dao.rest.PersonChildren.person using @RestResource! (through reference chain: org.springframework.hateoas.PagedResources[\"_embedded\"]->java.util.UnmodifiableMap[\"people\"]->java.util.ArrayList[0])", 
    "path" : "/people" 
} 

प्रश्न 1: मैं एक पोस्ट करने के लिए कर रहा हूँ, लेकिन मेरे प्राप्त नाकाम रहने रखता है।

प्रश्न 2: पोस्ट सफल होने पर मुझे यह त्रुटि क्यों मिल रही है?

प्रश्न 3: क्या कोई अच्छी वसंत मार्गदर्शिका है जो आरईएसटी और जेपीए के साथ मदद करेगी? यदि आप अभी भी इन मॉड्यूल पर काम कर रहे हैं तो मैं किस उदाहरण को देख सकता हूं?

प्रश्न 4: क्या @RepositoryRest समस्या का संसाधन है? यह तब तक पहचाना नहीं जाता जब तक कि मैं वसंत-डेटा-आराम-वेबएमवीसी निर्भरता के रूप में नहीं जोड़ता।

यह अनुत्तरित प्रश्न Spring Data Rest Ambiguous Association Exception

अद्यतन के समान है:

यह Person वर्ग में केवल एक ही OneToOne मानचित्रण के साथ काम कर रहा है। यदि मैं मैपिंग के साथ Person में दोनों कक्षाएं, personDetails और personChildren जोड़ता हूं। यह काम नहीं कर रहा है।

मैंने @JointColumn(name="person_details") और @JointColumn(name="person_children")personDetails और personChildren जोड़ने का भी प्रयास किया। यह या तो काम नहीं किया।

उत्तर

14

इसका कारण बहुत आसान है: संबंधित इकाइयों के संबंध संबंध शामिल वर्ग के संपत्ति नामों से प्राप्त किए गए हैं। तो PersonDetails और PersonChildren नामक person नामक आउटबाउंड लिंक बनाना चाहते हैं। अगर हमने इसे प्रस्तुत किया है, तो यह

{ _links : { 
    person : { href : … }, <- the one from PersonDetails 
    person : { href : … } <- the one from PersonChildren 
} 

जैसा कुछ निश्चित रूप से अमान्य होगा। इसके अलावा, एक सरणी में दो लिंक अस्तर आप अब दो लिंक के बीच अंतर करना (जिनमें PersonDetails से आ रहा है और जो एक PersonChildren से आ रही है की अनुमति नहीं होगी

तो उसके लिए कुछ विकल्प यहां हैं:।

  1. मैन्युअल उन प्रकार के संबंधों को नाम दें। आप @RestResource साथ Person गुण व्याख्या और कुछ person से अलग करने के लिए एनोटेशन के rel विशेषता कॉन्फ़िगर कर सकते हैं।
  2. आप दोनों को पर निर्यात नहीं किया जाना चाहिए। लिंक को बिल्कुल भी प्रस्तुत करने से रोकने के लिए एक ही एनोटेशन का उपयोग किया जा सकता है। बस exported@RestResource पर false पर ध्वज सेट करें और लिंक प्रदान नहीं किया जाएगा। सूचक हो सकता है तो यह उपयोगी हो सकता है PersonDetails से कोड के भीतर बस प्रासंगिक है, लेकिन वास्तव में एक JSON प्रतिनिधित्व में नहीं है।
+0

ओलिवर, यह एक आकर्षण की तरह काम करता था। मैंने विकल्प 1 का उपयोग किया। आपकी सभी मदद के लिए धन्यवाद। – user827096

+3

मैंने दोनों विकल्पों की कोशिश की, उनमें से कोई भी मुझसे काम नहीं कर रहा है। –

संबंधित मुद्दे