2015-08-25 9 views
5

मुझे एच 2 डेटाबेस में इंडेक्स नामों की विशिष्टता के साथ एक छोटी सी समस्या है। Mysql/mariadb के साथ तालिका ए और तालिका बी के लिए "X" नामक इंडेक्स को एक ही समय में परिभाषित करना संभव है। एच 2 डेटाबेस के साथ यह संभव नहीं है, क्योंकि सूचकांक का नाम प्रति डेटाबेस अद्वितीय होना चाहिए।एच 2 इंडेक्स नाम विशिष्टता

यह मेरे लिए एक समस्या है, के बाद से मैं निम्नलिखित संपत्ति के साथ एक आधार जेपीए इकाई वर्ग परिभाषित किया गया है:

@org.hibernate.annotations.Index(name = "X") 
protected String x; 

यह वर्ग एक से विरासत में मिला है और बी और सूचकांक निर्माण निम्नलिखित के साथ वर्ग बी के लिए विफल रहता है त्रुटि:

ERROR [main] o.h.tool.hbm2ddl.SchemaUpdate - HHH000388: Unsuccessful: create index X on B(x) 
ERROR [main] o.h.tool.hbm2ddl.SchemaUpdate - Index "X" already exists 

यह स्वचालित रूप से सूचकांक नाम बना सकते हैं या किसी भी तरह एच 2 उस तालिका नाम के साथ इस तरह के सूचकांक नाम उपसर्ग के लिए एक एडाप्टर बनाने के लिए हाइबरनेट बताने के लिए संभव है?

+2

ऐसा लगता है कि आप भाग्य से बाहर हैं। मैं इंडेक्स को एनोटेशन के रूप में परिभाषित करने के बारे में भी सावधान रहूंगा। वे अलग से संभालना आसान है। – Kayaman

उत्तर

2

हालांकि आपके पास हमेशा database drive the schema evolution होना चाहिए और स्कीमा संस्करणों को माइग्रेट करने के लिए FlywayDB का उपयोग करना चाहिए, तो आप @ इंडेक्स को जितना चाहें ओवरराइड कर सकते हैं।

मैंने इसे साबित करने के लिए test on GitHub जोड़ा।

कक्षाएं

इस तरह दिखेगा:

@Entity(name = "Base") 
@Table(name="Base") 
@Inheritance(strategy = InheritanceType.JOINED) 
public static abstract class Base { 

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

    @Transient 
    protected String x; 

    public Long getId() { 
     return id; 
    } 

    public String getX() { 
     return x; 
    } 

    public void setX(String x) { 
     this.x = x; 
    } 
} 

@Entity(name = "ChildY") 
@Table(name="ChildY") 
@DiscriminatorValue("Y") 
public static class ChildY extends Base { 

    private String y; 

    @Override 
    @org.hibernate.annotations.Index(name = "xy") 
    @Access(AccessType.PROPERTY) 
    public String getX() { 
     return x; 
    } 
} 

@Entity(name = "ChildZ") 
@Table(name="ChildZ") 
@Inheritance(strategy = InheritanceType.JOINED) 
@DiscriminatorValue("Z") 
public static class ChildZ extends Base { 

    private String z; 

    @Override 
    @org.hibernate.annotations.Index(name = "xz") 
    @Access(AccessType.PROPERTY) 
    public String getX() { 
     return x; 
    } 
} 

स्कीमा इस तरह उत्पन्न होता है:

create table Base (id bigint generated by default as identity (start with 1), primary key (id)) 
create table ChildY (x varchar(255), y varchar(255), id bigint not null, primary key (id)) 
create table ChildZ (x varchar(255), z varchar(255), id bigint not null, primary key (id)) 
create index xy on ChildY (x) 
create index xz on ChildZ (x) 

इस तरह:

  1. आप डोमेन मॉडल में आधार वर्ग संपत्ति के प्रतिधारण (फ़ील्ड, गेटर और सेटर)
  2. प्रत्येक तालिका को अपनामिलता हैएक संबंधित इंडेक्स

समस्या यह है कि आपके पास बेस क्लास में फ़ील्ड नहीं हो सकता है, क्योंकि हाइबरनेट इसे दो बार बनाने का प्रयास करेगा। आप हाइबरनेट पर एक जिरा मुद्दा दर्ज कर सकते हैं और उल्लेख कर सकते हैं कि एचबीएम स्कीमा पीढ़ी को इंडेक्स को छोड़ना चाहिए यदि यह पहले से ही बनाया गया है।

सबसे सुरुचिपूर्ण समाधान बस एक उचित डेटाबेस स्कीमा का उपयोग करना और एचबीएम-डीडीएल स्कीमा पीढ़ी को हटा देना है।

+1

यही वह है जो मैंने अपेक्षित था। आपका बहुत बहुत धन्यवाद! – Konrad