【问题标题】:many-to-many mapping with limited options on one side一侧选项有限的多对多映射
【发布时间】:2012-10-28 21:12:06
【问题描述】:

我正在实现一个模拟电影院举行的 Java 应用程序。其中一个实体是Film,这个实体可以有很多Genres,但显然只有有限数量的Genres。我不确定我应该如何在 Hibernate 中实现它。

首先我创建了一个枚举类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;
    }
}

一个非常基础的课程。但是现在说我想在Film 上加一个Genre,我做不到:

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

看到这将为每部类型剧的电影创建一个新的Genre 对象。然后我是否必须先去数据库获取具有“戏剧”价值的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);
}

我不会将事务代码放入模型中,但我只是为了简化而将其放在那里。我也意识到使用串联是不安全的。

这是一个不错的解决方案还是我错过了一些更简单的方法来实现这一点?

【问题讨论】:

    标签: hibernate orm mapping


    【解决方案1】:

    要么将流派作为一个整体作为主键

    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()));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-08
      • 2014-08-20
      • 1970-01-01
      • 1970-01-01
      • 2013-08-25
      • 1970-01-01
      相关资源
      最近更新 更多