2010-06-30 15 views
17

में एनम्स का स्थायी सेट मैं अपने दृढ़ता मैपिंग निर्दिष्ट करने के लिए एनोटर्नेट 3.5.2-फाइनल का उपयोग कर रहा हूं। मैं एक आवेदन और प्लेटफार्मों के एक सेट के बीच संबंध बनाने के साथ संघर्ष कर रहा हूं। प्रत्येक एप्लिकेशन प्लेटफॉर्म के सेट के लिए उपलब्ध है।कई से कई यूनिडायरेक्शनल मैपिंग

मेरे द्वारा किए गए सभी पढ़ने और खोज से, मुझे लगता है कि मुझे प्लेटफॉर्म एनम क्लास को एक इकाई के रूप में जारी रखने की आवश्यकता है, और कई से अधिक रिश्ते का प्रतिनिधित्व करने के लिए तालिका में शामिल होना आवश्यक है। मैं चाहता हूं कि रिश्ते ऑब्जेक्ट स्तर पर एकजुट हो जाएं, यानी, मैं किसी दिए गए एप्लिकेशन के लिए प्लेटफ़ॉर्म की सूची प्राप्त करने में सक्षम होना चाहता हूं, लेकिन मुझे किसी दिए गए प्लेटफ़ॉर्म के लिए एप्लिकेशन की सूची जानने की आवश्यकता नहीं है।

यहाँ मेरी सरलीकृत मॉडल वर्ग हैं:

@Entity 
@Table(name = "TBL_PLATFORM") 
public enum Platform { 
    Windows, 
    Mac, 
    Linux, 
    Other; 

    @Id 
    @GeneratedValue 
    @Column(name = "ID") 
    private Long id = null; 

    @Column(name = "NAME") 
    private String name; 

    private DevicePlatform() { 
     this.name = toString(); 
    } 

    // Setters and getters for id and name... 
} 

@Entity 
@Table(name = "TBL_APP") 
public class Application extends AbstractEntity implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Column(name = "NAME") 
    protected String _name; 

    @ManyToMany(cascade = javax.persistence.CascadeType.ALL) 
    @Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE}) 
    @JoinTable(name = "TBL_APP_PLATFORM", 
       joinColumns = @JoinColumn(name = "APP_ID"), 
       inverseJoinColumns = @JoinColumn(name = "PLATFORM_ID")) 
    @ElementCollection(targetClass=Platform.class) 
    protected Set<Platform> _platforms; 

    // Setters and getters... 
} 

जब मैं हाइबरनेट hbm2ddl उपकरण चलाने के लिए, मैं निम्नलिखित (मैं उपयोग कर रहा हूँ MySQL) देखें:

create table TBL_APP_PLATFORM (
    APP_ID bigint not null, 
    PLATFORM_ID bigint not null, 
    primary key (APP_ID, PLATFORM_ID) 
); 

उचित विदेशी चाबियाँ हैं इस तालिका से एप्लिकेशन टेबल और प्लेटफ़ॉर्म तालिका में भी बनाया गया है। अब तक सब ठीक है।

एक समस्या यह है कि मैं में चल रहा हूँ है जब मैं एक आवेदन वस्तु लागू करने के लिए प्रयास करें:

Application newApp = new Application(); 
newApp.setName("The Test Application"); 
Set<DevicePlatform> platforms = EnumSet.of(Platform.Windows, Platform.Linux); 
newApp.setPlatforms(platforms); 
applicationDao.addApplication(newApp); 

क्या मैं ऐसा करना चाहते हैं के लिए बनाया मंच तालिका में उचित पंक्तियों के लिए है, यानी एक पंक्ति बनाने के विंडोज और लिनक्स के लिए, यदि वे पहले से मौजूद नहीं हैं। फिर, नए एप्लिकेशन के लिए एक पंक्ति बनाई जानी चाहिए, और फिर नए एप्लिकेशन और जुड़ने वाली तालिका में दो प्लेटफार्मों के बीच मैपिंग। जब मैं आवेदन लागू करने के लिए कोशिश

2010-06-30 13:18:09,382 6613126-0 ERROR FlushingEventListener Could not synchronize database state with session org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.example.model.Platform 

किसी तरह, मंच सेट कायम नहीं की जा रही है:

एक मुद्दा मैं में चल रहा हूँ निम्नलिखित क्रम अपवाद हो रही है। कैस्केड एनोटेशन का ख्याल रखना चाहिए, लेकिन मुझे नहीं पता कि क्या गलत है।

तो मेरी प्रश्न हैं:

  1. वहाँ मॉडल करने के लिए मुझे क्या करना है, उदा चाहते एक बेहतर तरीका है एक Enum उपयुक्त उपयोग कर रहा है?
  2. यदि मेरा मॉडल ठीक है, तो मैं सभी वस्तुओं को सही ढंग से कैसे जारी रखूं?

मैं इसके साथ घंटों तक संघर्ष कर रहा हूं, और मैंने ऊपर दिए गए सभी कोड को फिर से बनाने की कोशिश की है, लेकिन यह पूर्ण और/या सटीक नहीं हो सकता है। मुझे आशा है कि कोई कुछ स्पष्ट बताएगा!

उत्तर

32

आपको यह तय करना चाहिए कि आपका Platformइकाई है या नहीं।

यदि यह एक इकाई है, तो यह enum नहीं हो सकता है, क्योंकि संभव प्लेटफ़ॉर्म की सूची डेटाबेस में संग्रहीत है, एप्लिकेशन में नहीं। यह @Entity एनोटेशन के साथ एक नियमित कक्षा होना चाहिए और आपके पास सामान्य से कई संबंध होंगे।

यदि यह एक इकाई नहीं है, तो आपको TBL_PLATFORM तालिका की आवश्यकता नहीं है, और आपके पास कई से अधिक संबंध नहीं हैं।इस मामले में आप Platform एस के सेट को बिट फ्लैग के साथ एक पूर्णांक फ़ील्ड के रूप में या एक साधारण से-से-कई संबंधों के रूप में प्रदर्शित कर सकते हैं।

create table TBL_APP_PLATFORM ( 
    APP_ID bigint not null, 
    PLATFORM_ID bigint not null, -- the ordinal number of enum value 
    primary key (APP_ID, PLATFORM_ID) 
); 

और enum Platform एनोटेशन बिना -

@ElementCollection(targetClass = Platform.class) 
@CollectionTable(name = "TBL_APP_PLATFORM", 
    joinColumns = @JoinColumn(name = "APP_ID")) 
@Column(name = "PLATFORM_ID") 
protected Set<Platform> _platforms; 

: जेपीए 2.0 उत्तरार्द्ध मामले @ElementCollection साथ सरल बनाता है।

+0

मैं स्कीमा पैदा करने के लिए हाइबरनेट के एक पुराने संस्करण का उपयोग कर रहा था। Http://stackoverflow.com/questions/2734971/hibernate3-maven-plugin- निर्भरता-for-newer-version-of-hibernate का पालन करके, मैंने 3.5.3-फाइनल पर निर्भरता निर्धारित की है और "org.hibernate.MappingException: के लिए प्रकार निर्धारित नहीं कर सका: java.util.Set "चला गया। मैंने एक सादे गैर-इकाई एनम का उपयोग करके आपके द्वारा सुझाए गए एलीमेंट कोलेक्शन विधि का पालन किया, और अब सेट तालिका में मैप किया गया है। और, संपत्ति पर @ अनुमानित सेटिंग को सेट करके, मैं यह निर्धारित कर सकता हूं कि enum मान डेटाबेस में पूर्णांक या स्ट्रिंग के रूप में संग्रहीत हैं या नहीं। – gnuf

+0

@axtavt क्या आप कृपया मेरी मदद कर सकते हैं http://stackoverflow.com/questions/7687409/hibernate-criteria-query-for-collection-table/7693793#7693793 मैंने वहां एक उपहार दिया है .. बदसूरत मदद चाहिए .. –

+0

@ एक्स्टावेट क्या आप अपनी पोस्ट में प्रिंसिपल टेबल "टीबीएल_एपीपी" की संरचना को जोड़ सकते हैं? thnx –

2

आपकी इकाई पर मैपिंग के नीचे सरल उपयोग। मान लीजिए कि हम:

public enum TestEnum { A, B } 

फिर अपने इकाई कक्षा में:

@ElementCollection(targetClass = TestEnum.class) 
@CollectionTable(
     name = "yourJoinTable", 
     joinColumns = @JoinColumn(name = "YourEntityId") 
) 
@Column(name = "EnumId") 
private final Set<TestEnum> enumSet= new HashSet<TestEnum >(); 
संबंधित मुद्दे