2010-08-02 20 views
5

मेरे पास डेटा दृढ़ता के लिए हाइबरनेट का उपयोग करके एक अनुप्रयोग है, जिसमें वसंत शीर्ष पर है (अच्छे उपाय के लिए)।हाइबरनेट डेटाबेस के माइग्रेशन के लिए DiscriminatorFormula का उपयोग करना बुरा व्यवहार है?

@Entity 
public class A { 
    @Id 
    @Column(unique = true, nullable = false, updatable = false) 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private long id; 
    public String name; 
} 

मैं के बाद से एक के एक उपवर्ग, कहा जाता बी जोड़ लिया है:

@Entity 
public class B extends A { 
    public String description; 
} 

बी जोड़ने के बाद, मैं अब एक के लोड नहीं कर सका अभी हाल तक, वहाँ एक आवेदन में एक लगातार वर्ग था, । निम्नलिखित अपवाद उत्पन्न हुआ था:

class org.springframework.orm.hibernate3.HibernateObjectRetrievalFailureException :: Object with id: 1 was not of the specified subclass: A (Discriminator: null); nested exception is org.hibernate.WrongClassException: Object with id: 1 was not of the specified subclass: A (Discriminator: null) 

मैं बी के लिए निम्न एनोटेशन और संपत्ति जोड़ा, और यह समस्या हल हो गया लगता है। क्या इस मुद्दे को हल करने का यह सही तरीका है?

... 
@DiscriminatorFormula("(CASE WHEN dtype IS NULL THEN 'A' ELSE dtype END)") 
public class A { 
    private String dtype = this.getClass().getSimpleName(); 
    ... 

उत्तर

2

(...) अभी हाल तक, वहाँ, आवेदन में एक लगातार वर्ग था एक:

ID NAME 
-- ---- 
1 foo 
2 bar 

मैं:

निम्नलिखित डेटाबेस प्रतिनिधित्व के साथ

तब से ए के उप-वर्ग को जोड़ा गया है, जिसे बी कहा जाता है (...)

और आपने Inheritance एनोटेशन निर्दिष्ट नहीं किया है इसलिए SINGLE_TABLE मानचित्रण रणनीति का उपयोग किया जाता है। और इस रणनीति में, पदानुक्रम में सभी वर्गों को एक ही तालिका में मैप किया जाता है। तालिका में एक स्तंभ होता है जो "भेदभावकर्ता कॉलम" के रूप में कार्य करता है, यानी, एक स्तंभ जिसका मूल्य विशिष्ट उप-वर्ग को पहचानता है जिस पर पंक्ति द्वारा प्रतिनिधित्व किया गया उदाहरण संबंधित है।

तालिका तो बन गया:

ID NAME DTYPE 
-- ---- ----- 
1 foo NULL 
2 bar NULL 

कहाँ DTYPE स्तंभ के डिफ़ॉल्ट नाम है discriminator के लिए प्रयोग की जाने वाली।

बी जोड़ने के बाद, अब मैं ए लोड नहीं कर सका। निम्नलिखित अपवाद फेंक दिया गया था (...)

दरअसल, क्योंकि मौजूदा मूल्यों में भेदभावकर्ता कॉलम में शून्य मूल्य होता है, प्रदाता को पता नहीं है कि उप-वर्ग किस प्रकार तत्काल है।

मैंने निम्नलिखित एनोटेशन और संपत्ति को बी में जोड़ा, और ऐसा लगता है कि समस्या हल हो गई है। क्या इस मुद्दे को हल करने का यह सही तरीका है?

यह एक तरीका है लेकिन यह घुसपैठ कर रहा है (आपकी संस्थाओं को dtype कॉलम से अवगत नहीं होना चाहिए) और हाइबरनेट विशिष्ट। दूसरे शब्दों में, यह एक हैक है।

UPDATE A SET DTYPE='A' WHERE DTYPE=NULL 
:

मेरे लिए, "सही" इस हल करने के लिए जिस तरह से मौजूदा एक रिकॉर्ड (हाइबरनेट, इकाई नाम के लिए मूल्य चूक के साथ) 'A' को मान सेट करने के DTYPE स्तंभ अद्यतन करने के लिए किया जाएगा

इस तरह, हाइबरनेट उन्हें ठीक से लोड करने में सक्षम होगा।

+0

विस्तृत उत्तर के लिए धन्यवाद। दुर्भाग्य से मुझे एप्लिकेशन के सभी इंस्टॉलेशन तक सीधे पहुंच नहीं होगी, इसलिए मैं इस स्कीमा को उपयोगकर्ताओं के लिए पारदर्शी रूप से बदलना चाहता हूं। मैंने डिस्प्ले क्षेत्र को स्पष्ट रूप से परिभाषित किए बिना डिस्कमिनेटरफॉर्मूला जोड़ने की कोशिश की, लेकिन यह काम नहीं किया। जब मैं ऐसा कर रहा था तो यह एक हैक की तरह महसूस किया - यही कारण है कि मैंने पूछा। – Armand

+1

@ एलिसन आपका स्वागत है। मैंने आपको "आदर्श" समाधान आईएमओ दिया है। यदि यह आपके संदर्भ में उपयुक्त नहीं है, यदि आप अपने उपयोगकर्ताओं को माइग्रेशन स्क्रिप्ट प्रदान नहीं कर सकते हैं (जो विभिन्न 'ALTER' के बाद' अद्यतन 'निष्पादित करेगा) - या स्वचालित स्वचालित माइग्रेशन टूल भी बेहतर होगा - तो आपका समाधान स्वीकार्य है। कम से कम यह काम करता है। और अब आप जानते हैं कि यह एक हैक है :) –

+0

-) मुझे दुर्भाग्यवश, हाइबरनेट/वसंत में माइग्रेशन पर जानकारी मिली है। – Armand

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

  • कोई संबंधित समस्या नहीं^_^