2011-10-26 12 views
9

दुर्भाग्य से नीचे दिया गया कोड काम नहीं करता है। छवि हमेशा प्राप्त की जाती है!जेपीए आलसी सरल बाइट [] क्षेत्र स्तर

@Entity 
public Car implements Serializable { 
    ... 
    @Basic(fetch = FetchType.LAZY) //Neither with @Lob 
    private byte[] image; 
    ... 
} 

सेटअप: जेपीए 2.0/हाइबरनेट 3.5/MySQL 5,5

उत्तर

0

मुझे याद है इस एक सवाल किया जा रहा है एक समय पहले (लगभग 2007): अर्थात् क्यों बाइट सरणियों बेसब्री से भी यद्यपि दिलवाया जाता है उन्हें आलसी घोषित किया जाता है। स्पष्ट रूप से हाइबरनेट लोगों ने अभी भी इस मुद्दे को ठीक नहीं किया है।

यहाँ कुछ व्यवहार्य विकल्प है:

फिस्ट, साथ ही @Lob के साथ अपने क्षेत्र व्याख्या कोशिश करते हैं और देखते हैं कि अगर काम करता है के रूप में उम्मीद। तो यह एक बड़ा रिफैक्टरिंग नहीं होगा

दूसरा, स्थापित करने और वास्तविक बाइट सरणी प्राप्त करने के लिए अपने byte[]java.sql.Blob के साथ, यह है सुविधा तरीकों की जगह है, और यह वास्तव में आलसी लोड हो रहा है इस मुद्दे को हल करना चाहिए:

http://download.oracle.com/javase/1.4.2/docs/api/java/sql/Blob.html

+0

धन्यवाद आंद्रेई, लेकिन वे दृष्टिकोण मेरे लिए काम नहीं करते हैं। बड़ी समस्याएं! '@ लॉब @ बासिक (fetch = FetchType.LAZY) ब्लॉब निजी बाइट [] छवि; 'EntityManager इस संपत्ति को जारी नहीं रख सकता है ... सभी फ़ील्ड जारी रखें और' छवि 'शून्य रहता है। मैं कंक्रीट क्लास 'सीरियलब्लोब' – CelinHC

3

याद रखें कि जब आप इसे निर्दिष्ट करते हैं तो जेपीए प्रदाता को डेटा को आलसी लाने की आवश्यकता नहीं होती है। यह संकेत है और आवश्यकता नहीं है।

जेपीए विशिष्टता 2,0 11.1.6

उत्सुक रणनीति हठ प्रदाता क्रम कि डेटा बेसब्री से प्राप्त किए गए होना चाहिए पर एक आवश्यकता है। LAZY रणनीति संकेत दृढ़ता प्रदाता रनटाइम के लिए है कि डेटा को पहली बार एक्सेस किया जाने पर लाया जाना चाहिए। कार्यान्वयन उत्सुकता से प्राप्त करने की अनुमति है जिसके लिए LAZY रणनीति संकेत निर्दिष्ट किया गया है। विशेष में, आलसी fetching केवल मूल मैपिंग के लिए उपलब्ध हो सकता है जिसके लिए संपत्ति-आधारित पहुंच उपयोग की जाती है।

+0

का उपयोग कर रहा हूं धन्यवाद पेड्रो! तो क्या मैं खो गया हूँ? – CelinHC

+0

पेड्रो, मुझे सच में लगता है कि यह एक हाइबरनेट बग है (यह उनके जेपीए कार्यान्वयन पर पहला नहीं होगा)। इस प्रश्न को देखें: http://stackoverflow.com/questions/2605477/spring-hibernate-blob-lazy-loading। लड़के की मूलभूत स्थिति में आपके जैसा ही सुझाव है, समाधान का सुझाव दिया गया है: अपनी इकाई के बीच एक मैपिंग (छवि को संसाधित करें) और केवल एक बाइट [] युक्त एक इकाई बनाएं और उस संगठन को आलसी बनाएं –

+0

@AndreiBodnarescu निश्चित रूप से यह हो सकता है हाइबरनेट बग, लेकिन फिर भी आप यह नहीं मान सकते कि जेपीए प्रदाता आपके डेटा को आलसी लोड करेगा। मेरी राय में यदि आपका तर्क ऐसी सुविधा पर निर्भर करता है तो इसे अच्छी तरह से प्रलेखित किया जाना चाहिए क्योंकि आप जेपीए प्रदाता को बदलते समय आश्चर्यचकित हो सकते हैं। –

1

मेरे ज्ञान के लिए आलसी लोडिंग केवल तभी संभव है जब आपके पास @OneToMany संबंध है (जब तक आप कक्षा बुनाई का उपयोग नहीं करते)। यह कम से कम यह है कि EclipseLink इसे http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Mapping/Basic_Mappings/Lazy_Basics बताता है, और यह जावा भाषा परिप्रेक्ष्य से समझ में आता है। तो जेपीए आसानी से अपने स्वयं के संग्रह कार्यान्वयन का उपयोग कर सकते हैं कि भार डेटा lazily जब आप इसे माध्यम से पुनरावृत्ति शुरू जब आप

@OneToMany (fetch = FetchType.LAZY) 
Collection<Employee> employees; 

है संग्रह एक अंतरफलक है। यदि आपके पास byte[] प्रकार के क्षेत्र के साथ कोई ऑब्जेक्ट है तो यह मान शून्य है या इसमें सभी डेटा शामिल हैं, इस प्रकार जावा काम करता है। इसे छेड़छाड़ करने का एकमात्र तरीका वर्ग बुनाई का उपयोग करना और बाइट-कोड बनाना है जो बाइट सरणी जैसा दिखता है, लेकिन इसमें तब तक कोई डेटा नहीं है जब तक आप इसे एक्सेस नहीं करते।

2

चाल इस इस विषय में बताया कि कैसे हासिल करने के लिए: http://justonjava.blogspot.it/2010/09/lazy-one-to-one-and-one-to-many.html

मैं हाइबरनेट v.4.3.5 और जेपीए v.1.5.0, PostgreSQL 9.3 पर यह cheched गए हैं। एक जादू की तरह काम किया। उदाहरण:

public class Attachment implements FieldHandled{ 
    @Transient 
    private FieldHandler fieldHandler; 
... 
... 
    @Lob 
    @Column(name=CONTENT, nullable=false) 
    @Basic(fetch = FetchType.LAZY, optional = false) 
    private byte[] content; 

... 
... 
    public byte[] getContent() { 
    if(fieldHandler!=null){ 
     return (byte[])fieldHandler.readObject(this, "content", content); 
    } 
    return content; 
    } 

    public void setContent(byte[] content) { 
    if(fieldHandler!=null){ 
     fieldHandler.writeObject(this, "content", this.content, content); 
     return; 
    } 
    this.content = content; 
    } 

} 

नोट: यदि आप CGLib का उपयोग कर रहे हैं, तो FieldHandled के बजाय net.sf.cglib.transform.impl.InterceptFieldEnabled लागू, एक ही दृष्टिकोण के साथ।