【发布时间】:2011-06-09 22:59:17
【问题描述】:
我使用 Hibernate 作为持久性提供程序并使用 JPA 2 对我的实体进行建模。
现在出现了一个问题,我希望你能帮助我。
在我的应用程序中,您可以打开一个游戏,在其中创建玩家组并在地图上四处走动(图块 (2d))。
首先我的实体定义: 游戏:
@Entity
public class Game implements Serializable {
@Id
@SequenceGenerator(name = "gen_gameid", sequenceName = "seq_gameid")
@GeneratedValue(generator="gen_gameid")
private long gameid;
/**
* Playing Characters.
*/
@OneToMany(mappedBy = "game")
private List<Character> characters;
private int round = 0;
@OneToMany(mappedBy="game")
private List<Tile> tiles;
@OneToMany(mappedBy="game")
private List<Group> group;
图块(图块将从模板创建,并且只属于一个游戏):
@Entity @IdClass(TileId.class)
public class Tile implements Serializable{
private static final long serialVersionUID = 2039974286110729270L;
@Id
private int x;
@Id
private int y;
@Id @ManyToOne @JoinColumn(name="gameid")
private Game game;
@OneToOne(mappedBy="tile")
private Character character;
}
人物:
@ManyToOne
@JoinColumn(name="gameid", referencedColumnName = "gameid")
private Game game;
@ManyToOne
@JoinColumns({
@JoinColumn(name="groupgameid", referencedColumnName = "gameid"),
@JoinColumn(name="groupTag", referencedColumnName = "grouptag")
})
private Group group;
@OneToOne
@JoinColumns({
@JoinColumn(name = "x", referencedColumnName = "x"),
@JoinColumn(name = "y", referencedColumnName = "y"),
@JoinColumn(name = "tilegameid", referencedColumnName = "gameid")
})
private Tile tile;
如您所见,我不得不将 gameid 列重命名为 groupgameid 和 tilegameid。这不是很漂亮,因为我只需要一次角色中的游戏ID。 要使用 insertable=false 标记来自 tile 和 group 的字符中的 fk 列,updateable=false 将允许生成 sql,但我无法更改/设置此值。
当然,我可以在组和拼贴中引入人工 pk,但我需要更多的连接。
JPA 是否仅限于我必须多次允许使用其他名称的 gameid 列?或者我的设计不是最优的?
期待您的反馈,并在此先感谢您。 你好 马库斯
PS(编辑): 此刻我让shema在启动时由hibernate生成,直到我的模型完成。但这里是生成的 shema(有点简化并删去了一些不重要的字段):
CREATE TABLE Character
(
charid bigint NOT NULL,
gameid bigint,
grouptag character varying(255),
x integer,
y integer,
CONSTRAINT hero_pkey PRIMARY KEY (charid),
CONSTRAINT fkd4addb09308bc3b822441a FOREIGN KEY (gameid)
REFERENCES game (gameid) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fkd4addb093091cb6522441a FOREIGN KEY (gameid, x, y)
REFERENCES tile (gameid, x, y) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fkd4addb09c018f3ae22441a FOREIGN KEY (gameid, grouptag)
REFERENCES gamegroup (gameid, grouptag) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
CREATE TABLE tile (
x integer NOT NULL,
y integer NOT NULL,
gameid bigint NOT NULL,
CONSTRAINT tile_pkey PRIMARY KEY (gameid, x, y),
CONSTRAINT fk27c6ce308bc3b8 FOREIGN KEY (gameid)
REFERENCES game (gameid) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION)
CREATE TABLE gamegroup
(
grouptag character varying(255) NOT NULL,
gameid bigint NOT NULL,
CONSTRAINT gamegroup_pkey PRIMARY KEY (gameid, grouptag),
CONSTRAINT fk3c1c51cd308bc3b8 FOREIGN KEY (gameid)
REFERENCES game (gameid) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
PS 2:我已经玩过, insertable = false, updatable = false。
例如,当我将组 JoinColumns 更改为:
@ManyToOne
@JoinColumns({
@JoinColumn(name="gameid", referencedColumnName = "gameid", insertable = false, updatable = false ),
@JoinColumn(name="groupTag", referencedColumnName = "grouptag")
})
private Group group;
我收到不允许混合的错误: 原因:org.hibernate.AnnotationException:不允许在属性中混合可插入和不可插入的列:net.hq.model.Charactergroup
当我同时设置 insertable=false 时,我无法再设置组标签。插入后 groupTag 保持为空并设置了 gameid。 :-/
我将角色添加到组的方式:
// Create game
Game game = new Game();
game.addCharacter(max);
em.persist(game);
// Group
Group heroGroup = new Group(game, "HEROES");
heroGroup.addCharacter(max);
em.persist(game);
组类中的方法:
public void addCharacter(Character character){
if(this.characters == null)
this.characters = new ArrayList<Character>();
this.characters.add(character);
character.setGroup(this);
}
【问题讨论】:
-
如果您能提供相关的数据库架构并指定您的类的@Table 注释,我会更容易提供帮助。
-
在我的问题末尾发布。问候。
标签: java hibernate postgresql jpa-2.0