JPA映射2实体表,它们之间有关系表

时间:2016-10-25 20:04:12

标签: java hibernate jpa

我试图将这两个权利表映射到一个模型类,游戏和平台。游戏可以有多个平台。所以在我的数据库中我有以下表格:

CREATE TABLE IF NOT EXISTS games (
id                          SERIAL  NOT NULL PRIMARY KEY,
name                        VARCHAR,
summary                     TEXT,
avg_score                   REAL,
);

CREATE TABLE IF NOT EXISTS platforms (
id   SERIAL NOT NULL PRIMARY KEY,
name VARCHAR
);

一个名为Game_Platforms的关系表

CREATE TABLE IF NOT EXISTS game_platforms (
id          serial not null primary key,
game_id      INTEGER NOT NULL,
platform_id  INTEGER NOT NULL,
release_date date not null,

FOREIGN KEY (game_id) REFERENCES games (id) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (platform_id) REFERENCES platforms (id) ON DELETE CASCADE ON UPDATE CASCADE,
UNIQUE(game_id,platform_id, release_date)   --The same game can be released for the same platform multiple times (i.e. remaster)
);

请注意,这些表格包含更多列,但我只是展示与此问题相关的列。

所以在我的模型上,我有以下类,我想使用JPA

映射到数据库
@Entity
@Table(name = "games")
public class Game {

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "games_gameid_seq")
private long id;

@Column(length = 100, nullable = false, unique = true)
private String name;

//Map with platforms
private Map<String, LocalDate> platforms;

没有课程的平台,因为我没有发现它是必要的。我不认为@OneToMany注释足以映射这个。 添加课程&#34;平台&#34;我的模型将是最后的手段,因为我必须更改我的大部分界面 ,需要更改整个应用程序。关于如何接受这个的任何想法?提前谢谢!

2 个答案:

答案 0 :(得分:1)

当使用对象关系映射工具(如Hibernate / JPA API)时,您应该考虑对象关系模型 - 关键字:对象。因此,不希望将表格映射为实体对您的需求非常适得其反,因为您无法按预期使用该技术;你不得不求助于使用原生查询。

相反,请映射所有涉及的表(在本例中为GamPlatform),并通过添加关系映射实际上使JPA工作。

@Entity
public class Game {

  ...

  @OneToMany(mappedBy="game")
  private Set<GamePlatform> gamePlatforms;

  ...
}

要解决的真正问题是,存在大量现有代码,这些代码将因此变化而中断。要暂时处理它,您可以维护现有的平台属性getter,并在水下构建从新定义的模型返回的HashMap。假设getter名为getPlatforms()

@Deprecated
public Map<String, LocalDate> getPlatforms(){
  Map<String,LocalDate> ret = new HashMap<>();

  gamePlatforms.stream().forEach(gamePlatform -> {
    ret.put(gamePlatform.getPlatform().getName(), gamePlatform.getReleaseDate());
  });

  return ret;
}

您可以将该方法标记为已弃用,并且随着时间的推移迁移代码以使用正确的实体类。

脚注:我确定使用Collectors.toMap进行上述操作的方法比较紧凑,只剩下exercise to the reader

答案 1 :(得分:0)

如果我理解你的意思你有一个游戏,每个游戏有几个平台! 你需要onToMany关系,需要创建平台模型。 看看这个例子 Game.java

@Entity
@Table(name = "games")
public class Game {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "games_gameid_seq")
    private long id;

    @Column(name = "name", nullable = false)
    private String name;

    @OneToMany(mappedBy="game_name")
    @Column(name = "PlatFormId", nullable = false)
    private Set<PlatForm>   PlatFormId= new HashSet<PlatForm>(0);

}

PlatForm.java

@Entity
@Table(name = "platForm")
public class PlatForm {

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "games_gameid_seq")
private long id;

@Column(name = "name", nullable = false)
private String name;

    @Column(name = "game_name", nullable = false)
    private Game  game;