2011-09-17 11 views
6

पर बदलें, मैं इसके सबक्लास में एक कंक्रीट सुपरक्लास बदलना चाहता हूं। मैंने नीचे एक उदाहरण शामिल किया है:हाइबरनेट: बेस क्लास का उदाहरण उदाहरण

@Entity 
@Table(name = "employees") 
@Inheritance(strategy = InheritanceType.JOINED) 
public class Employee { 

    @Id 
    @Column(name = "id") 
    private String id; 

    public Employee(String id) { 
     this.id = id; 
    } 
... 
} 

@Entity 
@Table(name = "managers") 
@PrimaryKeyJoinColumn(name = "id", referencedColumnName = "id") 
public class Manager extends Employee { 

    public Manager(String id) { 
     super(id); 
    } 
... 
} 


@Entity 
@Table(name = "history") 
public class History { 
... 
/** 
* 
*/ 
@ManyToOne 
@JoinColumn(name = "employee_id") 
private Employee employee; 
... 
} 

मैं जिन तीन वर्गों के साथ काम कर रहा हूं वे कर्मचारी, प्रबंधक और इतिहास हैं। सभी प्रबंधक कर्मचारी हैं, लेकिन सभी कर्मचारी प्रबंधक नहीं हैं। सभी कर्मचारियों (और प्रबंधकों) का इतिहास है। कर्मचारियों को प्रबंधन में पदोन्नत किया जा सकता है। जब ऐसा होता है तो कर्मचारी का इतिहास अपने कर्मचारी आईडी को रखकर बनाए रखा जाना चाहिए। इससे रोजगार के माध्यम से आसानी से मिलकर प्रबंधक के इतिहास की अनुमति मिल जाएगी।

पदोन्नति संचालन को कार्यान्वित करना डाटाबेस के साथ बाधाओं से जटिल है: डेटाबेस पुराने कर्मचारी को हटाने और एक ही आईडी के साथ एक नया प्रबंधक बनाने की अनुमति नहीं देगा, बिना किसी इतिहास के सभी इतिहास वस्तुओं को हटाए बिना, जो मानव संसाधन जीता ' टी अनुमति नहीं है, अन्यथा मेरा काम आसान होगा!

यह करना संभव है जोड़ने या कस्टम एसक्यूएल आपरेशन का सहारा के बिना देते प्रबंधक (नए प्रबंधकों) एक मौजूदा कर्मचारी को पंक्ति?

public void promote(Employee employee) { 
    /* copy over the ID of the employee to the manager. Will not work because employee with ID already exists */ 
    Manager manager = new Manager(employee.getId()); 
    this.entityManager.persist(manager); 
} 

... या ...

public void promote(Employee employee) { 
    /* detach the employee then merge. Will not work: fails, again, with a NonUniqueObject Exception */ 
    this.entityManager.detach(employee); 
    Manager manager = new Manager(employee.getId()); 
    this.entityManager.merge(manager); 
} 

मैं कैसे प्राप्त कर सकते हैं यह किया:

मैं सफलता के बिना निम्नलिखित समाधान की कोशिश की है? क्या मैं डिटेच() और विलय() के साथ सही रास्ते पर भी हूं?

क्या यह हाइबरनेट/जेपीए में संभव है?

इस बिंदु पर कोई भी विचार सहायक होगा क्योंकि मैं स्टंप हो गया हूं!

  • हारून

उत्तर

6

आप कोई संदेह नहीं है देखने के लिए शुरू कर रहे हैं के रूप में, आप हवा के खिलाफ यहां नौकायन कर रहे हैं। दुर्भाग्यवश, ऐसा लगता है कि आपके पास using inheritance to represent role का क्लासिक उदाहरण है। दोनों Hibernate - एक ऑब्जेक्ट - तर्कसंगत मैपर - और जावा - एक ऑब्जेक्ट -ऑरिएंटेड भाषा - इस पर आपसे लड़ने जा रहे हैं क्योंकि आपका ऑब्जेक्ट मॉडल गलत है। मैं कहूंगा कि आपकी सबसे अच्छी शर्त अब इसे एक रिफैक्टरिंग और डेटा माइग्रेशन के साथ ठीक करना है। अंतिम परिणाम यह होना चाहिए कि हर कोई एक कर्मचारी है, और कुछ कर्मचारियों के पास एक या अधिक विभागों या अन्य कर्मचारियों के साथ कुछ प्रकार के "प्रबंध" संबंध हैं।

+0

है इस आम OO flub से निपटने का एक में हाइबरनेट तरीका नहीं हाइबरनेट? समस्या को ऑब्जेक्ट-पहचान समस्या के रूप में भी वर्णित किया जा सकता है: मैं केवल एक लेनदेन के लिए हिबेनेट को बताने में सक्षम होना चाहता हूं, .equals() और == semanticists को संरक्षित करने की कोशिश करने के बारे में भूलना चाहता हूं - और मुझे ऑब्जेक्ट्स को बराबर नहीं बनाने दें, !=, तब बराबर() भी हो, इसे सबक्लास के लिए एक INSERT करने के लिए निर्देशित करें। मैं समझता हूँ कि अपनी 'हठ वीएम राज्य को कुछ हद तक असंगत छोड़ने के लिए जा रहा - आवेदन वास्तव में उस के लिए डिज़ाइन किया गया है (कोई कैशिंग, आदि ...)। कोई अन्य विचार? –

+0

@Aaron: यदि आप एक मैप किए गए कर्मचारी> इतिहास संबंध है? यदि हां, तो आप नए प्रबंधक के लिए पुराने कर्मचारी के सभी गुण कॉपी एक प्रबंधक वस्तु बनाने के लिए सक्षम होना चाहिए, और फिर प्रबंधक के इतिहास में इतिहास वस्तु की स्थापना की और अशक्त करने के लिए कर्मचारी का इतिहास निर्धारित करते हैं, इस प्रकार अनिवार्य रूप से के स्वामित्व के हस्तांतरण कर्मचारी उदाहरण से प्रबंधक उदाहरण के लिए इतिहास। –

+0

धन्यवाद! । हाँ, यह है कि तरह लगता है कि मैं क्या (या कुछ इसी तरह :() क्या करने की जरूरत करने जा रहा हूँ है मूल रूप से मुझे लगता है कि निम्न स्तर के हाइबरनेट/जेपीए तरीकों में से एक पहचान में परिवर्तन प्रबंधन में मदद - लेकिन इसके काम करने के लिए नहीं जा रहा । –

1

मैं इसी तरह की स्थिति में भाग गया और मुझे विश्वास नहीं है कि एक दोषपूर्ण डेटा मॉडल दोषी है क्योंकि डेटा मॉडल वास्तविक दुनिया मॉडल से काफी अच्छी तरह मेल खाता है।

वांछित परिणाम प्राप्त करने के लिए आप उप-वर्ग रिकॉर्ड मैन्युअल रूप से सम्मिलित कर सकते हैं। कभी कभी यह हाइबरनेट चारों ओर कुछ किया जाना जाना अपेक्षित है, तो यह है कि क्या मैं एक समाधान के रूप इस मामले में किया है:

sessionFactory.getCurrentSession().createSQLQuery(
      "insert into manager (employee_id, rank) " + 
      "values (:employeeId, :rank) ") 
      .setParameter("employeeId", employeeId) 
      .setParameter("rank", rank) 
      .executeUpdate(); 
संबंधित मुद्दे