2012-06-01 13 views
20

मेरे पास दो इकाइयां हैं जिन्हें मैं एकाधिक कॉलम के माध्यम से शामिल करना चाहता हूं। इन कॉलम को @Embeddable ऑब्जेक्ट द्वारा साझा किया जाता है जो दोनों इकाइयों द्वारा साझा किया जाता है। नीचे दिए गए उदाहरण में, Foo में केवल एक Bar हो सकता है लेकिन Bar में कई Foo एस हो सकते हैं (जहां AnEmbeddableObjectBar के लिए एक अनूठी कुंजी है)।मल्टी-कॉलम हाइबरनेट/जेपीए एनोटेशन में शामिल हों

@Entity 
@Table(name = "foo") 
public class Foo { 
    @Id 
    @Column(name = "id") 
    @GeneratedValue(generator = "seqGen") 
    @SequenceGenerator(name = "seqGen", sequenceName = "FOO_ID_SEQ", allocationSize = 1) 
    private Long id; 
    @Embedded 
    private AnEmbeddableObject anEmbeddableObject; 
    @ManyToOne(targetEntity = Bar.class, fetch = FetchType.LAZY) 
    @JoinColumns({ 
     @JoinColumn(name = "column_1", referencedColumnName = "column_1"), 
     @JoinColumn(name = "column_2", referencedColumnName = "column_2"), 
     @JoinColumn(name = "column_3", referencedColumnName = "column_3"), 
     @JoinColumn(name = "column_4", referencedColumnName = "column_4") 
    }) 
    private Bar bar; 

    // ... rest of class 
} 

और बार वर्ग:

@Entity 
@Table(name = "bar") 
public class Bar { 
    @Id 
    @Column(name = "id") 
    @GeneratedValue(generator = "seqGen") 
    @SequenceGenerator(name = "seqGen", sequenceName = "BAR_ID_SEQ", allocationSize = 1) 
    private Long id; 
    @Embedded 
    private AnEmbeddableObject anEmbeddableObject; 

    // ... rest of class 
} 

अंत में AnEmbeddedObject वर्ग: यहाँ एक उदाहरण है

@Embeddable 
public class AnEmbeddedObject { 
    @Column(name = "column_1") 
    private Long column1; 
    @Column(name = "column_2") 
    private Long column2; 
    @Column(name = "column_3") 
    private Long column3; 
    @Column(name = "column_4") 
    private Long column4; 

    // ... rest of class 
} 

जाहिर स्कीमा है खराब सामान्यीकृत, यह एक प्रतिबंध है कि AnEmbeddedObject ' प्रत्येक टेबल में फ़ील्ड दोहराए जाते हैं।

org.hibernate.AnnotationException: referencedColumnNames(column_1, column_2, column_3, column_4) of Foo.bar referencing Bar not mapped to a single property 

मैं JoinColumns अंकन की कोशिश की है insertable और updatable नहीं हैं, लेकिन कोई भाग्य के साथ:

समस्या मेरे पास है

मैं यह त्रुटि प्राप्त कि जब मैं हाइबरनेट अप प्रारंभ करने का प्रयास है। क्या हाइबरनेट/जेपीए एनोटेशन के साथ इसे व्यक्त करने का कोई तरीका है?

+0

क्या होगा यदि आप 'Foo' से एम्बेड करने योग्य को हटा दें? – siebz0r

उत्तर

9

यदि यह काम नहीं करता है तो मैं विचारों से बाहर हूं। इस तरह आप दोनों टेबलों में 4 कॉलम प्राप्त करते हैं (Bar उनके पास हैं और Foo उन्हें Bar संदर्भित करने के लिए उपयोग करता है) और दोनों इकाइयों में जेनरेट की गई आईडी। 4 कॉलम का सेट Bar में अद्वितीय होना चाहिए, इसलिए कई से एक संबंध कई से ज्यादा नहीं बनता है।

@Embeddable 
public class AnEmbeddedObject 
{ 
    @Column(name = "column_1") 
    private Long column1; 
    @Column(name = "column_2") 
    private Long column2; 
    @Column(name = "column_3") 
    private Long column3; 
    @Column(name = "column_4") 
    private Long column4; 
} 

@Entity 
public class Foo 
{ 
    @Id 
    @Column(name = "id") 
    @GeneratedValue(generator = "seqGen") 
    @SequenceGenerator(name = "seqGen", sequenceName = "FOO_ID_SEQ", allocationSize = 1) 
    private Long id; 
    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumns({ 
     @JoinColumn(name = "column_1", referencedColumnName = "column_1"), 
     @JoinColumn(name = "column_2", referencedColumnName = "column_2"), 
     @JoinColumn(name = "column_3", referencedColumnName = "column_3"), 
     @JoinColumn(name = "column_4", referencedColumnName = "column_4") 
    }) 
    private Bar bar; 
} 

@Entity 
@Table(uniqueConstraints = @UniqueConstraint(columnNames = { 
    "column_1", 
    "column_2", 
    "column_3", 
    "column_4" 
})) 
public class Bar 
{ 
    @Id 
    @Column(name = "id") 
    @GeneratedValue(generator = "seqGen") 
    @SequenceGenerator(name = "seqGen", sequenceName = "BAR_ID_SEQ", allocationSize = 1) 
    private Long id; 
    @Embedded 
    private AnEmbeddedObject anEmbeddedObject; 
} 
+0

यह रगड़ है, "AnEmbeddedObject" दोनों वस्तुओं में मौजूद होना चाहिए। जेनरेट आईडी प्रदर्शन कारणों के लिए बेहतर है। – bowsie

+0

तो 4 कॉलम प्लस जेनरेट किए गए कुंजी मानचित्र बार में? यह बहुत बुरा है।यदि आपका समाधान 'बार' के लिए सरोगेट कुंजी उत्पन्न करना है और 'Foo' विदेशी कुंजी में कॉलम नहीं बनाते हैं, तो आपको कॉलम को' Foo' में सेट करना होगा। अगर मैं सही हूं तो मैं अपना जवाब समायोजित कर सकता हूं। ;-) – siebz0r

+0

@ बोवेसी मैंने अपना जवाब संशोधित किया ताकि 'फू' और 'बार' दोनों में 4 कॉलम हों और 'बार' को 'आईडी' के संदर्भ में संदर्भित किया गया हो। – siebz0r

4

हाइबरनेट से आप स्वयं तुम क्या करने की कोशिश कर रहे क्या करना है के लिए बनाने के लिए नहीं जा रहा है। Hibernate documentation से:

ध्यान दें कि संदर्भित कॉलमनाम का उपयोग गैर प्राथमिक कुंजी कॉलम में करते समय, संबंधित वर्ग को Serializable होना चाहिए। यह भी ध्यान दें कि एक गैर प्राथमिक कुंजी कॉलम में संदर्भित कॉलमनाम को एक कॉलम वाले किसी संपत्ति में मैप किया जाना चाहिए (अन्य मामले शायद काम नहीं कर सकते हैं)।(जोर जोड़ा)

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

+0

मैं कहूंगा कि यह एक शॉट के लायक है, सिद्धांत रूप में कई विदेशी कुंजी का उपयोग करके जो एक अद्वितीय बाधा का उल्लेख करना संभव होना चाहिए। यदि यह ओपी भाग्य से बाहर नहीं है। इसके लिए +1 संभवतः उत्तर है। – siebz0r

+0

@ siebz0r, ओपी ने शॉट लिया है और लगभग त्रुटि संदेश प्राप्त किया है जो मैं इस त्रुटि की स्थिति के लिए अपेक्षा करता हूं: "संदर्भित कॉलमनाम ... *** एक ही संपत्ति में मैप नहीं किया गया ***"। यह कहना चाहिए कि "एक कॉलम वाले किसी संपत्ति के लिए मैप नहीं किया गया है," लेकिन यह वही बात है। –

+0

मुझे लगता है कि यह तब खत्म हो गया है ;-) – siebz0r

10

यह मेरे लिए काम किया। मेरे मामले 2 टेबल foo में और मेरे मामले में 3 अलग columns.Please टिप्पणी के आधार पर शामिल हो गए होने की जरूरत बू, बू में 3 आम स्तंभ हैं नहीं प्राथमिक कुंजी

यानी, एक मानचित्रण के लिए एक 3 अलग कॉलम

के आधार पर
@Entity 
@Table(name = "foo") 
public class foo implements Serializable 
{ 
    @Column(name="foocol1") 
    private String foocol1; 
    //add getter setter 
    @Column(name="foocol2") 
    private String foocol2; 
    //add getter setter 
    @Column(name="foocol3") 
    private String foocol3; 
    //add getter setter 
    private Boo boo; 
    private int id; 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "brsitem_id", updatable = false) 
    public int getId() 
    { 
     return this.id; 
    } 
    public void setId(int id) 
    { 
     this.id = id; 
    } 
    @OneToOne 
    @JoinColumns(
    { 
     @JoinColumn(updatable=false,insertable=false, name="foocol1", referencedColumnName="boocol1"), 
     @JoinColumn(updatable=false,insertable=false, name="foocol2", referencedColumnName="boocol2"), 
     @JoinColumn(updatable=false,insertable=false, name="foocol3", referencedColumnName="boocol3") 
    } 
    ) 
    public Boo getBoo() 
    { 
     return boo; 
    } 
    public void setBoo(Boo boo) 
    { 
     this.boo = boo; 
    } 
} 





@Entity 
@Table(name = "boo") 
public class Boo implements Serializable 
{ 
    private int id; 
    @Column(name="boocol1") 
    private String boocol1; 
    //add getter setter 
    @Column(name="boocol2") 
    private String boocol2; 
    //add getter setter 
    @Column(name="boocol3") 
    private String boocol3; 
    //add getter setter 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "item_id", updatable = false) 
    public int getId() 
    { 
     return id; 
    } 
    public void setId(int id) 
    { 
     this.id = id; 
    } 
}