2010-07-13 14 views
8

के साथ विरासत मानचित्रण यह काफी लंबा (अत्यधिक जटिल नहीं) डिजाइन प्रश्न है इसलिए कृपया मेरे साथ भालू। मैं पीओजेओ और जेपीए के साथ एक व्यक्ति/भूमिका प्रबंधन प्रणाली को लागू करने की कोशिश कर रहा हूं। मैं ओआरएम के लिए बिल्कुल नया हूं और यह ज्यादातर मैपिंग समस्या है।जेपीए/हाइबरनेट

मैं POJOs के रूप में इस काम के लिए मिला है और फोन करने वाले स्तर के एपीआई के साथ आराम कर रहा हूँ, लेकिन अब जेपीए का उपयोग कर एक डेटाबेस से मैप या एक सीवन वातावरण में हाइबरनेट करना चाहते हैं।

मेरा कार्यान्वयन सजावटी (गोफ) और व्यक्ति भूमिका वस्तु पैटर्न (बाउमर/रिहेले एट अल) पर आधारित है। सभी भूमिकाएं हार्ड-कोडेड हैं और नई भूमिकाओं के रन-टाइम जोड़ समर्थित नहीं हैं क्योंकि इसे व्यवहार बढ़ाने के लिए कोड परिवर्तनों की आवश्यकता होगी। मैं सुरक्षा और अनुमतियों को लागू करने के लिए उपयोगकर्ता समूहों का उपयोग करता हूं।

अन्य प्रबंधन के साथ addRole(), removeRole(), हैरोल(), getRole(), getRoles() जैसे भूमिका प्रबंधन विधियों के साथ एक व्यक्ति इंटरफ़ेस है। कंक्रीट कार्यान्वयन एक व्यक्ति Ipl वर्ग द्वारा प्रदान किया जाता है।

एक अमूर्त वर्ग भूमिका है जो व्यक्ति इंटरफ़ेस (सजावटी प्रतिस्थापन समकक्षता के लिए) को लागू करती है, और एक रोलआईएमएल कक्षा जो इसे विस्तारित करती है। रोल क्लास व्यक्ति इंटरफ़ेस पर किसी भी विधि/संपत्ति कॉल की सेवा के लिए इसका उपयोग करते हुए किसी व्यक्ति के उदाहरण का संदर्भ रखता है, जिसका अर्थ है कि भूमिका के सभी उप-वर्ग व्यक्ति इंटरफ़ेस को संभाल सकते हैं। रोल कन्स्ट्रक्टर व्यक्ति ऑब्जेक्ट को पैरामीटर के रूप में ले जाता है।

(आप चित्र इनलाइन नहीं देख सकते हैं, उसे यहां देख via yUML):

public interface Person { 
    public String getFirstName(); 

    public void setFirstName(String firstName); 
    . 
    . 
    . 
    public boolean isEnabled(); 
    public void setEnabled(boolean enabled); 
    public Set<Role> getRoles(); 
    public Role addRole(Class<? extends Role> roleType); 
    public void removeRole(Class<? extends Role> roleType); 
    public boolean hasRole(Class<? extends Role> roleType); 
    public Role getRole(Class<? extends Role> roleType); 

    public enum Gender {MALE, FEMALE, UNKNOWN}; 
} 

public class PersonImpl implements Person { 
    . 
    . 
    . 
} 

public abstract class Role implements Person { 
protected PersonImpl person; 

    @Transient 
    protected abstract String getRoleName(); 
    protected Role() {} 
    public Role(PersonImpl person) { 
     this.person = person; 
    } 
    public String getFirstName() { 
     return person.getFirstName(); 
    } 
    public void setFirstName(String firstName) { 
     person.setFirstName(firstName); 
    } 
    public Set<Role> getRoles() { 
     return person.getRoles(); 
    } 
    public Role addRole(Class<? extends Role> roleType) { 
     return person.addRole(roleType); 
    } 
    . 
    . 
    . 
} 

public abstract class RoleImpl extends Role { 
    private String roleName; 

    protected RoleImpl() {} 

    public RoleImpl(PersonImpl person) { 
     super(person); 
    } 
    . 
    . 
    . 
} 

public class Employee extends RoleImpl { 
    private Date joiningDate; 
    private Date leavingDate; 
    private double salary; 

    public Employee(PersonImpl person) { 
     super(person); 
    } 
    . 
    . 
    . 
} 

यह चित्र वर्ग संबंध दिखाता है:

इन इंटरफेस/वर्ग हैं

मैं इन वर्गों का उपयोग इस प्रकार करता हूं:

Person p = new Person("Doe", "John", Person.MALE, ...); 
// assuming Employee extends Role 
Employee e = (Employee)p.addRole(Employee.class); 

के बाद से भूमिका वर्ग भी व्यक्ति इंटरफ़ेस लागू करता है, मैं भी कर सकते हैं:

// assuming Parent extends Role 
Parent parent = new Parent((PersonImpl)p); 

e.addRole(Parent.class); 
e.getDateOfBirth(); // handled by the decorated person class 

// assuming Manager extends Employee extends Role 
Manager m = (Manager)p.getRole(Manager); 

if (m.hasRole(Employee.class) { 
    // true since Manager derives from Employee 
} 

सवाल मेरे पास है कर रहे हैं:

(क) इस कार्यान्वयन बेकार में जटिल है और यदि ऐसा है तो क्या होगा एक आसान दृष्टिकोण हो? ध्यान दें कि यह एक गैर तुच्छ व्यापार आवेदन और नहीं एक शिशु परियोजना में चला जाता है, और मुझे लगता है कि भूमिका उपवर्गीकरण का लाभ उठाने के इस तरह के कर्मचारी, प्रबंधक, आदि के रूप में मामलों में व्यवहार करने के लिए महत्वपूर्ण है

(ख) मैं इस मैप करते कैसे जेपीए/हाइबरनेट में?

(सी) क्या इसे मैप किया जा सकता है ताकि मैं सीम पहचान प्रबंधन का लाभ उठा सकूं? (भूमिका की मेरी परिभाषा स्पष्ट रूप से सीम के समान नहीं है)

(डी) यदि मैं टेबल-प्रति-सबक्लास (इनहेरिटेंस टाइप। जॉइनेड) मैपिंग रणनीति के साथ जाता हूं, तो मैं व्यक्तिगत रूप से व्यक्तियों और भूमिकाओं के रूप में भूमिकाओं को मानचित्र तालिका के रूप में मानचित्रित करता हूं, और मानचित्र RoleImpl के प्रत्येक उप-वर्ग (जैसे कर्मचारी और अभिभावक) कर्मचारियों और माता-पिता के रूप में अपनी स्वयं की सारणी में।

मेरे पास बाद में तालिका PERSON_ROLES के साथ व्यक्तियों और ROLES (PersonImpl में भूमिका संग्रह पर) के बीच @ManyToMany रिश्ते होगा।

अब समस्या यह है कि कर्मचारियों और माता-पिता टेबल, आदि केवल ROLE_ID संदर्भ, के बाद से विरासत मानचित्रण रणनीति स्पष्ट रूप से उन्हें मानता है, जबकि मैं उन्हें PERSON_ROLES के परिशिष्ट के रूप में की जरूरत है भूमिकाओं (भूमिकाओं) करने के लिए एक्सटेंशन होना है, और की आवश्यकता है USER_ID + ROLE_ID कुंजी को ठीक से हल किया जा सकता है, या कम से कम USER_ID।

मैं एक सामान्य डेटाबेस को पसंद करता हूं जो एक असामान्य डेटाबेस से अतिरिक्त जुड़ने पर निर्भरता निर्भर करता है जिसे बनाए रखना मुश्किल हो सकता है और अप्रयुक्त और अप्रासंगिक क्षेत्रों का एक टन गुच्छा हो सकता है, यही कारण है कि मुझे लगता है कि टेबल-प्रति-सबक्लास जाने का रास्ता।

या इस परिदृश्य में एक भेदभावकर्ता कॉलम ओके (डेटाबेस रखरखाव परिप्रेक्ष्य से) के साथ एक टेबल-प्रति-श्रेणी-पदानुक्रम (विरासत प्रकार .INGLE_TABLE) है? ध्यान दें कि कुछ भूमिकाओं में दर्जनों गुण/फ़ील्ड होने की संभावना है।

(ई) क्या इस डिजाइन के लिए कोई बेहतर विकल्प है?

किसी भी विचार/सुझावों की बहुत सराहना करेंगे।

+0

यदि प्रत्येक भूमिका वस्तु एक व्यक्ति ऑब्जेक्ट पर लागू होती है, जैसा कि आपका कोड इंगित करता है, तो PERSONS और ROLES के बीच @ManyToMany रिश्ते क्यों हैं? क्या यह @OneToMany नहीं है? –

+0

एक व्यक्ति के पास कई भूमिकाएं हो सकती हैं। प्रत्येक भूमिका में कई व्यक्ति हो सकते हैं। मुझे लगता है कि एक तरफ आर्थर का @OneToMany का बिंदु और दूसरे पर @ManyToOne कुछ योग्यता हो सकती है। जांचना है ... –

उत्तर

6

के रूप में कहा

तो मेरे साथ सहन कृपया

तो मेरा उत्तर है कि तुम क्या कहा

सभी भूमिकाओं हार्ड-कोडेड हैं पर आधारित होगा ... नहीं है एक अमूर्त वर्ग भूमिका ...

यदि कोई सारणी है वर्ग, तो मैं मान लीजिए कुछ गुण AbstractRole वर्ग में परिभाषित उपवर्गों के सभी से प्राप्त होती हैं

@Entity 
/** 
    * Which strategy should we use ??? keep reading 
    */ 
@Inheritance 
public abstract class AbstractRole implements Serializable { 

    private Integer id; 

    private String commonProperty; 
    private String otherCommonProperty; 
    private String anotherCommonProperty; 

    @Id 
    @GeneratedValue 
    public Integer getId() { 
     return this.id; 
    } 

    // getter's and setter's 

} 

अब कर्मचारी (एक ही अभिभावक और छात्र द्वारा इस्तेमाल किया दृष्टिकोण)

@Entity 
public class Employee extends AbstractRole { 

    private String specificEmployeeProperty; 

    // getter's and setter's 

} 

लेकिन जो विरासत रणनीति का उपयोग करने ???

InheritanceType.JOINED

  • उपवर्गों एक जटिल मानचित्रण है: कई गुण, @OneToMany, @OneToOne, @ManyToMany के रूप में अन्य संबंधों और इतने
  • आप जेपीए प्रदाता के रूप में हाइबरनेट का उपयोग करते हैं पर, रखना ध्यान में यह भेदभाव कॉलम का समर्थन नहीं करता है। here
  • एक सरल क्वेरी प्रत्येक सबक्लास के लिए परिभाषित सभी तालिका यूनियन करेगा। हो सकता है कि आप सिर्फ एक उप-वर्ग प्राप्त करना चाहते हैं और आप प्रदर्शन के मुद्दों को देखेंगे। Here एक कामकाज चला जाता है।

InheritanceType.SINGLE_TABLE

  • उपवर्गों एक सरल मानचित्रण है।इतने सारे गुण और अन्य संबंधों के कम से कम राशि
  • ठोस वर्ग के संकल्प रनटाइम पर
  • यह एक बार नल स्तंभों का एक बहुत के साथ संबंधित उपवर्गों के सभी साझा एक ही टेबल
  • तेज़ प्रदर्शन

अब चलो

) को देखने के इस तरह के addRole(), removeRole(), hasRole(), getRole (के रूप में भूमिका प्रबंधन के तरीके के साथ एक व्यक्ति नहीं है, getRoles(), अन्य बातों के

01,235,164 के बीच

ठीक है, अगर मैं की तरह addRole विधि कुछ देखते हैं, मैं लगता है व्यक्ति या तो @OneToMany या AbstractRole वर्ग के साथ @ManyToMany संबंध नहीं है। मुझे पता है, मुझे पता है ... आपके पास @ManyToMany रिश्ते हैं लेकिन मैं वास्तव में सलाह देता हूं कि आप अपने @ManyToMany को @OneToMany - @ManyToOne रिलेशनशिप में विभाजित करते हैं। देखें here कैसे

@Entity 
public class Person implements Serializable { 

    private Integer id; 

    private List<AbstractRole> roleList; 

    @Id 
    @GeneratedValue 
    public Integer getId() { 
     return this.id; 
    } 

    @OneToMany 
    public List<AbstractRole> getRoleList() { 
     return this.roleList; 
    } 

    // getter's and setter's 

} 

और करने के लिए अंत में

यह इतना मैप किया जा सकता मैं भी

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

@Name("authenticationManager") 
public class AuthenticationManager { 

    /** 
    * Starting with Seam 2.1+, you should use Credentials instead of Identity 
    * To collect your username and password 
    * 
    * Your JSF Form should looks like 
    * 
    * <h:inputText value="#{credentials.username}"/> 
    * <h:inputSecret value="#{credentials.password}"/> 
    */ 
    private @In org.jboss.seam.security.Credentials credentials; 

    /** 
     * Login method 
     *  must take no arguments 
     *  must return a boolean indicating whether the credentials could be verified 
     * 
     * method name does not mind 
     */ 
    public boolean authenticate() { 
     /** 
      * Logic To verify whether credentials is valid goes here 
      */ 
    } 

} 

और परिभाषित अपने प्रमाणित-विधि /WEB-INF/components.xml

<security:identity authenticate-method="#{authenticationManager.authenticate}"/> 

अपने मानचित्रण के बारे में यह इतने पर व्यापार आवश्यकता, ग्राहकों की जरूरतों पर निर्भर करता है और ... लेकिन मैं लगता है कि

से ऊपर दिखाया गया यह आसान हो सकता है!

+0

मैंने अपने इंटरफ़ेस/कक्षा परिभाषाओं को दिखाते हुए कोड स्निपेट जोड़े हैं। आप यह मानने में सही हैं कि व्यक्ति में भूमिकाओं के लिए एक संग्रह है। वापस लौटने से पहले विस्तार से आपकी प्रतिक्रिया के माध्यम से जाना होगा। धन्यवाद। –

+0

@ एलन-पी देखें http://stackoverflow.com/questions/2443790/2468185#2468185 हम एक समान परिदृश्य को कैसे कार्यान्वित करते हैं। कुछ नोट्स: मैं एस्ट्रस्ट्रोल द्वारा एक कार्यान्वित इंटरफेस के रूप में व्यक्ति का उपयोग नहीं करता। मुझे लगता है कि आपका मॉडल सरल हो सकता है। इंटरफ़ेस के रूप में इसका उपयोग करने के बजाय व्यक्ति को एक साधारण POJO के रूप में उपयोग क्यों नहीं करना ??? मैं समझता हूं कि आपके पास जटिल व्यक्ति/भूमिका प्रबंधन प्रणाली हो सकती है, लेकिन कोड को सरल रखें। यदि संभव हो, तो डोमेन-संचालित-डिज़ाइन दृष्टिकोण का उपयोग करें http://stackoverflow.com/questions/2597219/2598168#2598168 –

+0

मुझे यह पूरी तरह से करने के लिए गोल नहीं मिला है, लेकिन मुझे लगता है कि आपके द्वारा उठाए गए बहुत से अंक वैध हैं और सहायक रहे हैं इसलिए मैं इस जवाब को स्वीकार कर रहा हूं। धन्यवाद। –

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

  • कोई संबंधित समस्या नहीं^_^