2014-09-18 5 views
6

को क्रमानुसार नहीं है मैं एक इकाई है:जैक्सन - आलसी वस्तुओं

@Entity 
public class Book { 

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

    @Column 
    private String title; 

    @OneToMany(fetch = FetchType.LAZY, mappedBy = ("movie"),cascade = CascadeType.ALL) 
    private List<Genre> genre; 

} 

तो मैं एक नियंत्रक जिसका उद्देश्य पुस्तकों को पुनः प्राप्त करने के लिए है, मेरी समस्या यह है कि, शैली क्षेत्र के json प्रतिक्रिया में शामिल किया जा रहा है मेरा नियंत्रक जैकसन ऑब्जेक्ट को क्रमबद्ध करता है जब किसी भी तरह से मैं आलसी लोड कर रहे हैं कि उन क्षेत्रों को बाहर कर सकते हैं?

Hibernate4Module hm = new Hibernate4Module(); 
hm.configure(Hibernate4Module.Feature.FORCE_LAZY_LOADING, false); 
registerModule(hm); 
configure(SerializationFeature.INDENT_OUTPUT, true); 

धन्यवाद:

यह मेरा ObjectMapper के विन्यास है!

मैं इसे जेसन इग्नोर के रूप में चिह्नित नहीं कर सकता, क्योंकि यह हमेशा क्रमबद्धता बॉक्स से बाहर होगा। ऐसे समय होंगे जहां मुझे पुस्तक के साथ शैलियों को पुनः प्राप्त करने की आवश्यकता होगी, और तब तक मैं अपनी क्वेरी पर "शामिल होने" का उपयोग करूंगा, इसलिए यह शून्य नहीं होगा।

+0

[क्षणिक] [1] [1]: http://stackoverflow.com/ प्रश्न/20700530/क्यों-उपयोग-क्षणिक-कीवर्ड-इन-जावा अपना उत्तर प्राप्त करने के लिए इस विषय का उपयोग करने का प्रयास करें;) – Fincio

+0

हाय @ फ़िनसिओ, मैं शैली के क्षेत्र को क्षणिक के रूप में नहीं बना सकता, क्योंकि मुझे इसकी आवश्यकता है डेटाबेस। – lorraine

+0

हम्म, कैसे @JsonIgnoreProperties ({"genre"}) या @JsonIgnore – Fincio

उत्तर

7

आप जैक्सन @JsonInclude एनोटेशन के साथ ऐसा कर सकते हैं।

latest version's javadoc (2.4 right now) के मुताबिक यदि आप फ़ील्ड मान शून्य या खाली हैं तो एनोटेटेड प्रॉपर्टी को शामिल करना या नहीं, तो आप एक साधारण एनोटेशन के साथ निर्दिष्ट कर सकते हैं।

डिफ़ॉल्ट रूप से, यह JsonInclude.Include.ALWAYS है, और इसका मतलब है कि भले ही आपके आलसी लोड किए गए मान शून्य न हों, जैक्सन में संपत्ति शामिल है।

खाली या शून्य मान शामिल नहीं करने के लिए काफी .. सभी लाभ शामिल साथ, JSON उत्तर के आकार को कम कर सकते हैं

आप इस व्यवहार को बदलना चाहते हैं, तो आप वर्ग में एनोटेशन जोड़ सकते हैं निर्दिष्ट करना -लेवल या एकल संपत्ति/गेटर मोड स्तर।क्षेत्रों के लिए निम्न टिप्पणियां जोड़ने के लिए

कोशिश आप शामिल नहीं करना चाहती खाली हो तो:

@JsonInclude(JsonInclude.Include.NON_EMPTY) 
@OneToMany(fetch = FetchType.LAZY, mappedBy = ("movie"),cascade = CascadeType.ALL) 
private List<Genre> genre; 
+2

यह मेरे लिए स्प्रिंग जेपीए + स्प्रिंग रीस्ट कंट्रोलर समाधान पर काम नहीं कर रहा है। आलसी fetching अभी भी तब होता है जब JSON Serialization होता है ... –

+0

यह ग्रहण लिंक के साथ जेपीए 2.1 के लिए सही जवाब नहीं है! समस्या स्पष्ट रूप से है कि जैक्सन गेटर्स को कॉल करके "NON_EMPTY" के गुणों की जांच करता है और जो आलसी लोडिंग को ट्रिगर करता है! दुर्भाग्य से, कोई AccesType "फ़ील्ड" जेसन एनोटेशन या तो नहीं है, इससे मदद मिलेगी। यह मोक्सी द्वारा समर्थित तरीके से मुझे लगता है (मुझे लगता है कि यह इसके लिए जेएक्सबी एनोटेशन का उपयोग करता है)। – Nabi

+0

@RonyeVernaes यह 'Hibernate5 मॉड्यूल' बीन जोड़ने के बाद मेरे लिए काम करता है। कृपया http://stackoverflow.com/questions/21708339/avoid-jackson-serialization-on-non-fetched-lazy-objects में chrismarx का उत्तर देखें। – Zeemee

1

शायद यह a known issue about lazy loading से संबंधित है।

मैं जैक्सन-डेटाटाइप-हाइबरनेट का उपयोग नहीं करता हूं, लेकिन एक ही समस्या को हल करने के लिए मैंने जो किया है, वह एक हाइबरनेट ऑब्जेक्ट को सीधे क्रमबद्ध करने के बजाय डीटीओ का उपयोग करके तस्वीर से लगातार संग्रह प्राप्त करना है। डोजर जैसे टूल्स आपको इससे मदद कर सकते हैं। वैकल्पिक रूप से, small utility है, मैंने इस तरह के मैपिंग करने के लिए लिखा था।

यदि आप बस डीटीओ की तरह दिखने के साथ प्रयोग करना चाहते हैं, तो आप नियमित रूप से खाली संग्रह के साथ अनलोड किए गए लगातार संग्रह को प्रतिस्थापित कर सकते हैं, जैसे books.setGenre (नया ArrayList <>()); दुर्भाग्य से मुझे यह बताने का कोई तरीका नहीं है कि आलसी लोड ऑब्जेक्ट लोड हो गया है या नहीं, इसलिए आप स्वचालित रूप से यह पुन: असाइनमेंट नहीं कर सकते हैं। जिन स्थानों पर आप लगातार संग्रह को प्रतिस्थापित करते हैं, उन्हें मामले के आधार पर आपके द्वारा निर्धारित किया जाना चाहिए। तब नियंत्रक में

@Entity 
@JsonFilter("Book") 
public class Book { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private long id; 

    @Column 
    private String title; 

    @OneToMany(fetch = FetchType.LAZY, mappedBy = ("movie"),cascade = CascadeType.ALL) 
    private List<Genre> genre; 
} 

@Entity 
@JsonFilter("Genre") 
public class Genre { 
    ... 
} 

आप फ़िल्टर करना क्या निर्दिष्ट करें::

2

आप Jackson's JSON Filter Feature उपयोग कर सकते हैं जब आप रन टाइम पर आलसी संबंध फ़िल्टर करना चाहते हैं

@Controller 
public class BookController { 
     @Autowired 
     private ObjectMapper objectMapper; 

     @Autowird 
     private BookRepository bookRepository; 

     @RequestMapping(value = "/book", method = RequestMethod.GET, produces = "application/json") 
     @ResponseBody 
     public ResponseEntity<String> getBooks() { 

      final List<Book> books = booksRepository.findAll(); 
      final SimpleFilterProvider filter = new SimpleFilterProvider(); 
      filter.addFilter("Book", SimpleFilterProvider.serializeAllExcept("Genre"); 
      return new ResponseEntity<>(objectMapper.writer(filter).writeValueAsString(books), HttpStatus.OK) 
     } 

} 

इस तरह, आप नियंत्रित कर सकते हैं

+0

जैसा कि संपादित कतार पूर्ण है, मुझे एक पंक्ति को सही करना चाहिए; addFilter() का दूसरा तर्क ** SimpleBeanPropertyFilter ** होना चाहिए। serializeAll ... नहीं ** SimpleFilterProvider **। serializeAll ... वर्ग –