2010-02-01 12 views
10

मेरे पास निम्न इकाई संबंध समस्या है। एक "गेम" में दो (और केवल दो) "टीम" ऑब्जेक्ट्स होना चाहिए। एक "टीम" में कई "गेम" हो सकते हैंजेपीए/हाइबरनेट में दो से कई रिश्ते मॉडलिंग

यह, जहां तक ​​मैं देख सकता हूं, दो-से-कई संबंध हैं। हालांकि ... मुझे नहीं पता कि जेपीए में इसका मॉडल कैसे करें। उदाहरण के लिए, मैं, इस तरह कुछ करने के लिए जा रहा था ...

@Entity 
public class Team extends BaseObject { 
    private Long id; 
    private Set<Game> games; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    public Long getId() {return id;} 
    public void setId(Long id) {this.id = id;} 

    @OneToMany(mappedBy = "game") 
    public Set<Game> getGames() {return games;} 
    public void setGames(Set<Game> games) {this.games = games;} 
} 

@Entity 
public class Game extends BaseObject { 
    private Long id; 
    private Team team1; 
    private Team team2; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    public Long getId() {return id;} 
    public void setId(Long id) {this.id = id;} 

    @ HERE IS THE PROBLEM - WHAT ANNOTATION DO I USE? 
    public Team getTeam1() {return team1;} 
    public void setTeam1(Team team1) {this.team1 = team1;} 

    @ HERE IS THE PROBLEM - WHAT ANNOTATION DO I USE? 
    public Team getTeam2() {return team2;} 
    public void setTeam2(Team team1) {this.team2 = team2;} 
} 

लेकिन, जैसा कि आप देख सकते हैं मुझे यकीन है कि एक टिप्पणी के तरफ से एक साथ टेबल लिंक करने का तरीका नहीं है। क्या किसी ने कभी ऐसा कुछ किया है? कोई विचार, मदद?

बहुत बहुत धन्यवाद!

+0

अच्छा प्रश्न (+1) –

उत्तर

6

मैं करूंगा किसी के लिए एक भयानक समाधान के साथ आने के लिए प्यार है, लेकिन यह एक मुश्किल स्थिति है जिसे मैं कभी भी बहुत अच्छी तरह से मानचित्र बनाने का तरीका नहीं ढूंढ पाया। आपके विकल्पों में शामिल हैं:

  1. रिश्ते को मॉडल करने के तरीके को बदलें। उदाहरण के लिए, आप की तरह कुछ हो सकता था:

    @Entity 
    public class GameMembership { 
        Team team; 
        Game game; 
        int gamePosition; // If tracking Team 1 vs Team 2 matters to you 
    } 
    

    और फिर Game एक Collection<GameMembership> है, यानि कि आप मॉडल यह रूप में कई-से-अनेक। Game में टीम 1 और टीम 2, आदि को स्थापित करने के लिए अभी भी सुविधाजनक तरीके हो सकते हैं, (यह लागू करने के लिए व्यवसाय तर्क है कि केवल 2 टीम हैं, हालांकि यह किया गया है) लेकिन वे Collection पर वापस हाइबरनेट द्वारा उपयोग किए गए मानचित्र पर मानचित्रण करते हैं।

  2. रिश्ते को द्विपक्षीय होने पर छोड़ दें - एक दिशा चुनें (GameTeam सबसे उपयुक्त लगता है) और केवल उस संबंध को झपकी दें। Games एक Team तो में शामिल है ढूँढना अपने डीएओ आदि के बजाय कुछ से एक ऑपरेशन Team से ही पहुंचा जा सकता है हो जाता है:

    public class GameDAO { 
        .... 
        public Collection<Game> gamesForTeam(Team t) { 
         .... 
         Query q = session.createQuery("FROM Game WHERE team1 = :team OR team2 = :team"); 
         q.setParameter("team", t); 
         return q.list(); 
        } 
    } 
    

    या कुछ इसी तरह की ...

  3. आपके द्वारा उठाए जा रहे मार्ग के साथ जारी रखें, लेकिन Team अंत में 'धोखा' रखें। Game पक्ष के गुणों को सामान्य से-एक संबंधों के रूप में मैप किया जाना चाहिए; फिर Team पर mappedBy का उपयोग किया गया ताकि Game संबंधों को 'नियंत्रण' इंगित किया जा सके।

    public class Team { 
         ... 
         @OneToMany(mappedBy="team1") 
         private Set<Game> team1Games; 
         @OneToMany(mappedBy="team2") 
         private Set<Game> team2Games; 
    

    और फिर (team1Games और team2Games हाइबरनेट के उपयोग के लिए बस कर रहे हैं) अपने एपीआई के लिए एक सुविधा संपत्ति है:

    @Transient 
        public Set<Game> getGames() { 
         Set<Game> allGames = new HashSet<Game>(team1Games); 
         allGames.addAll(team2Games); 
         // Or use google-collections Sets.union() for bonus points 
         return allGames; 
        } 
    
    तो अपने वर्ग के कॉल करने के लिए

    , यह पारदर्शी है 2 गुण देखते हैं कि ।

+0

मैं सहमत हूं ...यह सबसे व्यापक जवाब लगता है। मुझे लगता है कि मैं आपके दूसरे विकल्प के साथ जाने के लिए खत्म होने जा रहा हूँ। धन्यवाद! – Brian

1

मुझे लगता है कि आप दो एक-से-कई रिश्ते, नहीं एक दो-से-अनेक है।

+2

यह गलत है। उनके पास टीमों के दो सेट नहीं हैं, उनके पास दो टीमें हैं। – laura

2

पर विचार करता है, तो अपने खेल के पहले खिलाड़ी के लिए होता है क्या होगा - एक टीम (टीमों की सूची में से चुना) और दूसरे खिलाड़ी - एक कंप्यूटर (कंप्यूटर की एक सूची से चुना):

  • आपका पहला खिलाड़ी टीम टेबल में एक विदेशी कुंजी होगा।
  • आपका दूसरा प्लेयर कंप्यूटर टेबल में एक विदेशी कुंजी होगा।

यदि अब आप "कंप्यूटर" को किसी अन्य खिलाड़ी के रूप में "कंप्यूटर" के रूप में प्रतिस्थापित करते हैं, तो आपको टीम टेबल में दो विदेशी कुंजी मिलेंगी।

मेरे जेपीए थोड़ा जंग लगी है, लेकिन मेरा मानना ​​है कि आप एक @OneToOne टिप्पणी के साथ एक विदेशी कुंजी संबंध मॉडल, इसलिए जैसे:

@OneToOne(cascade = {CascadeType.ALL}, optional = false) 
@JoinColumn(name = "team1") 

और साथ दूसरा एक:

@OneToOne(cascade = {CascadeType.ALL}, optional = false) 
@JoinColumn(name = "team2") 
+0

हाय लौरा, जो मुझे समझ में आता है। हालांकि, मुझे आश्चर्य है कि क्या आप जानते हैं कि रिश्ते के दूसरी तरफ इसका क्या प्रभाव है ... टीम ऑब्जेक्ट से, जब हम सेटगेम्स() विधि ... यानी, जब मैं जाता हूं "team.getGames" पर कॉल करें, यह रिश्ते यह जांचने के लिए पर्याप्त स्मार्ट होगा कि क्या यह टीम सभी खेलों में टीम 1 या टीम 2 है या नहीं? आशा है कि यह मदद के लिए समझ में आता है और धन्यवाद। – Brian

+0

हां यह होगा - डेटाबेस स्तर पर किया गया। ऐसा इसलिए है क्योंकि मानचित्रण पूरी तरह से अलग है। 'गेम' टेबल में आपके पास प्रत्येक पंक्ति में दो कॉलम होंगे जिनमें उनमें 'टीम' तालिका से एक आईडी होगी (ये विदेशी कुंजी हैं) - एक-से-एक सरल। 'टीमों' तालिका में, चूंकि एक टीम कई खेलों का हिस्सा हो सकती है, इसलिए आपके पास 1-से-रिश्ते का रिश्ता होगा। इसका अर्थ यह है कि एक और तालिका बनाई जाएगी जो '(आईडी, game_id, team_id)' के समान दिखाई देगी और 'टीमों' तालिका में आपके पास इस अतिरिक्त तालिका से 'id' होगा, न कि 'गेम' से' id' । ध्यान दें कि आप अतिरिक्त तालिका का प्रबंधन नहीं करते हैं। – laura

+0

हाय लॉरा, यदि आपकी गलती नहीं है तो आपकी अतिरिक्त तालिका कईToMany समाधान में एक लिंक तालिका प्रतीत होती है। जब आप कहते हैं कि गेम के लिए टीम कई रिश्तों के लिए 1 है, तो मैं सहमत हूं, लेकिन मुझे यकीन नहीं है कि अगर किसी को कई लोगों को लिंक टेबल की आवश्यकता होती है। क्या यह कई समाधानों के लिए कई लोगों की तरह नहीं है? साथ ही, जब तक कि मैं गलत नहीं हूं तब तक वह लिंक तालिका स्वचालित रूप से हाइबरनेट द्वारा नहीं बनाई जाएगी। सहायता के लिए धन्यवाद! – Brian

2

आप एक @OneToMany संबंध (मुझे लगता है कि खेल के साथ टीम एक @ManyToOne संबंध नहीं है), मेरी सलाह है: अपने लक्ष्य को प्राप्त करने के लिए

उपयोग कैप्सूलीकरण

@Entity 
public class Team { 

    private Game game1; 
    private Game game2; 

    private List<Game> gameList = new ArrayList<Game>(); 

    public void setGame1(Game game1) { 
     // You can use index 0 to store your game1 
     if(getGameList().size == 0) 
      getGameList().add(game1); 
     else 
      getGameList().set(0, game1); 
    } 

    @Transient 
    public Game getGame1() { 
     if(getGameList().size() == 0) 
      return null; 

     return getGameList().get(0); 
    } 

    public void setGame2(Game game2) { 
     // You can use index 1 to store your game2 
     switch(getGameList().size()) { 
      case 0: 
       getGameList().add(null); 

       getGameList().add(game2); 
      break; 
      case 1: 
       getGameList().add(game2); 
      break; 
      case 2: 
       getGameList().set(1, game2); 
      break; 
     } 
    } 

    @Transient 
    public Game getGame2() { 
     if(getGameList().size() < 2) 
      return null; 

     return getGameList().get(1); 
    } 

    @OneToMany 
    @JoinColumn(name="TEAM_ID") 
    public List<Game> getGameList() { 
     return this.gameList; 
    } 

} 

कभी-कभी जागरूक रहें आपको कभी-कभी अपना काम करना होगा। तो encapsulation आपके प्रश्न की कुंजी हो सकता है।

संबंध है,

0

चाहेंगे इस काम:

@OneToMany 
@JoinFormula(value = "SELECT g.id FROM game g WHERE g.homeTeam = id or g.awayTeam=id") 
private Set<Game> games; 
संबंधित मुद्दे