2012-10-28 49 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()));