2010-07-14 10 views
9

मेरे पास हाइबरनेट इकाई पदानुक्रम के लिए निम्न प्रकार के वर्ग हैं। मैं दो ठोस उप वर्ग Sub1Class और Sub2Class रखने की कोशिश कर रहा हूं। वे एक भेदभावकर्ता कॉलम (field) से अलग होते हैं जिन्हें MappedSuperClass में परिभाषित किया गया है। एक अमूर्त इकाई वर्ग EntitySuperClass है जिसे अन्य संस्थाओं द्वारा संदर्भित किया जाता है। अन्य संस्थाओं को परवाह नहीं करना चाहिए यदि वे वास्तव में Sub1Class या Sub2Class का संदर्भ दे रहे हैं।हाइबरनेट, सिंगल टेबल विरासत और सुपरक्लास से फील्ड का उपयोग भेदभावकर्ता कॉलम

यह वास्तव में संभव है? वर्तमान में मैं इस त्रुटि मिलती है (क्योंकि स्तंभ परिभाषा Sub1Class में और EntitySuperClass में दो बार विरासत में मिलती है):

Repeated column in mapping for entity: my.package.Sub1Class column: field (should be mapped with insert="false" update="false") 

अगर मैं hiberante से @MappedSuperClassEntitySuperClass है, तो मैं दावे त्रुटि जोड़ें: अगर एक वर्ग दोनों है यह पसंद नहीं करता इकाई और एक मैप किए गए सुपर क्लास। अगर मैं EntitySuperClass से @Entity निकालने के लिए, वर्ग अब इकाई है और अन्य संस्थाओं से संदर्भित नहीं किया जा सकता:

MappedSuperClass बाहरी पैकेज का एक हिस्सा है, इसलिए यदि संभव हो तो इसे बदला नहीं जाना चाहिए।

मेरे कक्षाएं:

@MappedSuperclass 
public class MappedSuperClass { 
    private static final String ID_SEQ = "dummy_id_seq"; 
    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = ID_SEQ) 
    @GenericGenerator(name=ID_SEQ, strategy="sequence") 

    @Column(name = "id", unique = true, nullable = false, insertable = true, updatable = false) 
    private Integer id; 

    @Column(name="field", nullable=false, length=8) 
    private String field; 

    public Integer getId() { 
     return id; 
    } 
    public void setId(Integer id) { 
     this.id = id; 
    } 
    public String getField() { 
     return field; 
    } 
    public void setField(String field) { 
     this.field = field; 
    } 
} 


@Entity 
@Table(name = "ACTOR") 
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) 
@DiscriminatorColumn(name="field", discriminatorType=DiscriminatorType.STRING) 
abstract public class EntitySuperClass extends MappedSuperClass { 


    @Column(name="description", nullable=false, length=8) 
    private String description; 

    public String getDescription() { 
     return description; 
    } 

    public void setDescription(String description) { 
     this.description = description; 
    } 
} 

@Entity 
@DiscriminatorValue("sub1") 
public class Sub1Class extends EntitySuperClass { 

} 


@Entity 
@DiscriminatorValue("sub2") 
public class Sub2Class extends EntitySuperClass { 

} 


@Entity 
public class ReferencingEntity { 
    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE) 
    private Integer id; 

    @Column 
    private Integer value; 

    @ManyToOne 
    private EntitySuperClass entitySuperClass; 


    public Integer getId() { 
     return id; 
    } 

    public void setId(Integer id) { 
     this.id = id; 
    } 

    public Integer getValue() { 
     return value; 
    } 

    public void setValue(Integer value) { 
     this.value = value; 
    } 

    public EntitySuperClass getEntitySuperClass() { 
     return entitySuperClass; 
    } 

    public void setEntitySuperClass(EntitySuperClass entitySuperClass) { 
     this.entitySuperClass = entitySuperClass; 
    } 

} 
+0

लेकिन तुम क्यों discriminator बेनकाब करना चाहते हैं स्तंभ? यह कॉलम आम तौर पर एक "छुपा" कार्यान्वयन विवरण है जिसे आप बेनकाब नहीं करना चाहते हैं। –

+0

भेदभावकर्ता कॉलम पहले से ही मैप्डसुपर क्लास में उजागर हुआ है जो बाहरी पैकेज का हिस्सा है। यदि संभव हो, तो मैं एक पैकेज को संशोधित करना चाहता हूं। –

उत्तर

14

अपने प्रोजेक्ट में यह इस तरह से किया जाता है:

@Entity 
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) 
@DiscriminatorColumn(name = "field", discriminatorType = DiscriminatorType.STRING) 
@DiscriminatorValue("dummy") 
public class EntitySuperClass { 
    // here definitions go 
    // but don't define discriminator column here 
} 

@Entity 
@DiscriminatorValue(value="sub1") 
public class Sub1Class extends EntitySuperClass { 
    // here definitions go 
} 

और यह काम करता है। मुझे लगता है कि आपकी समस्या यह है कि आप अपने सुपरक्लास परिभाषा में भेदभाव क्षेत्र को अनिवार्य रूप से परिभाषित करते हैं। इसे हटा दें और यह काम करेगा।

12

एक सामान्य संपत्ति के रूप में एक भेदभावकर्ता कॉलम का उपयोग करने के लिए आपको यह संपत्ति केवल insertable = false, updatable = false के साथ पढ़नी चाहिए। जब से तुम MappedSuperClass नहीं बदल सकते हैं, तो आप @AttributeOverride उपयोग करने की आवश्यकता:

@Entity 
@Table(name = "ACTOR") 
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) 
@DiscriminatorColumn(name="field", discriminatorType=DiscriminatorType.STRING) 

@AttributeOverride(name = "field", 
    column = @Column(name="field", nullable=false, length=8, 
     insertable = false, updatable = false)) 

abstract public class EntitySuperClass extends MappedSuperClass { 
    ... 
} 
2

आप पढ़ने-लिखने क्षेत्र (एक क्षेत्र है कि insertable=true और/या updatable=true) और किसी भी संख्या बार के रूप में के रूप में केवल एक बार एक डेटाबेस स्तंभ मैप कर सकते हैं केवल पढ़ने के लिए फ़ील्ड (insertable=falseऔरupdatable=false)। @DiscriminatorColumn के रूप में कॉलम का उपयोग रीड-राइट मैपिंग के रूप में किया जाता है, इसलिए आपके पास अतिरिक्त रीड-राइट मैपिंग नहीं हो सकती हैं।

हाइबरनेट कंक्रीट क्लास इंस्टेंस के आधार पर दृश्यों के पीछे @DiscriminatorColumn में निर्दिष्ट मान निर्धारित करेगा। यदि आप उस क्षेत्र को बदल सकते हैं, तो यह @DiscriminatorColumn फ़ील्ड को संशोधित करने की अनुमति देगा ताकि फ़ील्ड में आपका उप-वर्ग और मान मेल न हो।

0

एक मौलिक: आप प्रभावी रूप से डीबी से अपने discriminator स्तंभ को पुन: प्राप्त करने की आवश्यकता नहीं होनी चाहिए। आपके पास उस कोड के भीतर पहले से ही वह जानकारी होनी चाहिए, जिसमें से आप अपने @DiscriminatorValue टैग में उपयोग करते हैं। यदि आपको डीबी से पढ़ने की जरूरत है, तो भेदभाव करने वाले तरीके से ध्यान से पुनर्विचार करें।

आप अंतिम इकाई वस्तु में यह की जरूरत है, एक अच्छा अभ्यास discriminator मूल्य से एक Enum को लागू करने और वापस जाने के लिए यह दुकान एक @Transient क्षेत्र में करने के लिए किया जा सकता है:

@Entity 
@Table(name="tablename") 
@DiscriminatorValue(Discriminators.SubOne.getDisc()) 
public class SubClassOneEntity extends SuperClassEntity { 

    ... 

    @Transient 
    private Discriminators discriminator; 

    // Setter and Getter 
    ... 
} 

public enum Discriminators { 
    SubOne ("Sub1"), 
    SubOne ("Sub2"); 

    private String disc; 
    private Discriminators(String disc) { this.disc = disc; } 
    public String getDisc() { return this.disc; } 
} 
संबंधित मुद्दे

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