2012-10-28 101 views
0

我正在實現模擬電影院控制的Java應用程序。其中一個實體是Film,該實體可以有許多Genres,但顯然只有有限數量的Genres。我不知道我應該如何在Hibernate中實現這一點。一對多選擇有限選項的多對多映射

首先我做了一個enum類Genre,並給Film實體一個Set<Genre> genres = new HashSet<>();屬性。

這樣做的問題是,Genre被存儲在數據庫中的BLOB,在由Hibernate創建的表稱爲film_genres,我將無法向特定Genre的所有電影。 (至少在我有限的Hibernate經驗)。

然後,我以爲我可以填充在啓動數據庫與所有可能的Genres其中Genre類看起來是這樣的:

public class Genre { 
    private Integer id; 
    private String name; 

    private Genre() {} 

    public Genre(String name) { 
     this.name = name; 
    } 

    public Integer getId() { 
     return id; 
    } 

    private void setId(Integer id) { 
     this.id = id; 
    } 

    public String getName() { 
     return name; 
    } 

    private void setName(String name) { 
     this.name= name; 
    } 
} 

一個非常基本的類。但現在說我要一個Genre添加到Film,我不能這樣做:

Film film = new Film("The Terminal"); 
film.addGenre(new Genre("Drama")); 

看到,因爲這會因爲這是流派劇每部電影創建一個新的Genre對象。然後,我需要首先訪問數據庫以獲取值爲「Drama」的Genre對象,然後添加該對象?

如果這就是應該做的,那麼我還是喜歡用這樣的枚舉:

public enum GenreEnum { 
    DRAMA("Drama"), 
    ADVENTURE("Adventure"), 
    ACTION("Action"), 
    ... 

    private String value; 

    GenreEnum(String value) { 
     this.value = value; 
    } 

    public String getValue() { 
     return value; 
    } 
} 

這樣做的原因是,我有超過初始值的進入的拼寫完全控制數據庫(預填充)和枚舉值,所以我現在可以這樣做:

Film film = new Film("The Terminal"); 
film.addGenre(GenreEnum.DRAMA); 

然後在addGenre方法我可以這樣做:

public void addGenre(GenreEnum ge) { 
    Query query = session.createQuery("from Genre g where g.name = " + ge.getValue()); 
    Genre genre = (Genre)query.list().get(0); 
    this.genres.add(genre); 
} 

我不會把事務代碼放在模型中,但我只是爲了簡化而放在那裏。我也意識到使用串聯是不安全的。

這是一個體面的解決方案還是我錯過了更簡單的實現這一點?

回答

0

要麼使流派作爲一個整體主鍵

public enum Genre { 
    DRAMA("Drama"), 
    ADVENTURE("Adventure"), 
    ACTION("Action"), 
    ... 

    private String value; 

    GenreEnum(String value) { 
     this.value = value; 
    } 

    public int getId() { 
     return id; 
    } 

    public String getValue() { 
     return value; 
    } 
} 

<compositeId> 
    <key-property name="value" /> 
</compositeId> 


Film film = new Film("The Terminal"); 
film.addGenre(session.load<GenreEnum>(Genre.DRAMA)); 

// or 
for(Genre g : GetAllGenre) 
    session.attach(g); 

Film film = new Film("The Terminal"); 
film.addGenre(Genre.DRAMA); 

或在枚舉引入固定ID

public enum Genre { 
    DRAMA(1, "Drama"), 
    ADVENTURE(2, "Adventure"), 
    ACTION(3, "Action"), 
    ... 

    private int id; 
    private String value; 

    GenreEnum(int id, String value) { 
     this.id = id; 
     this.value = value; 
    } 

    public int getId() { 
     return id; 
    } 

    public String getValue() { 
     return value; 
    } 
} 

Film film = new Film("The Terminal"); 
film.addGenre(session.load<GenreEnum>(Genre.DRAMA.getId()));