2011-01-16 15 views
12

que estoy usando Hibernate como proveedor de persistencia y el modelado de entidades con mis APP 2.APP 2: uso de columna múltiple en las claves externas

Ahora surgió una pregunta y espero que me puedan ayudar.

En mi aplicación puedes abrir un juego, crear grupos de jugadores y caminar en el mapa (fichas (2d)).

Primeros mis definiciones de entidades: juego:

@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; 

Teja (un azulejo se crea a partir de una plantilla y pertenece a un solo juego):

@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; 
} 

Carácter:

@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; 

Como puedes ver, tuve que cambiar el nombre de la columna de gameid a groupgameid y tilegam eid. Esto no es muy bonito porque necesitaría gameid en personaje solo una vez. Para marcar las columnas fk en carácter de mosaico y grupo con insertable = falso, actualizable = falso permitirá la generación de sql, pero no puedo cambiar/establecer estos valores.

Claro que podría introducir un pk artificial en grupo y en mosaico, pero necesitaría más combinaciones.

¿Está JPA limitado a que tenga que permitir la columna de gameid más de una vez con otros nombres? ¿O mi diseño no es óptimo?

Esperamos sus comentarios y agradecimientos por adelantado. saludos Markus

PS (editar): Al momento en que dejo que el Shema generan por hibernación en el arranque hasta que mi modelo es completa. Pero aquí está el Shema generada (poco simplificado y cutted algunos campos sin importancia):

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: Ya jugado un poco con , insertable = false, updatable = false. Por ejemplo cuando cambio la JoinColumns grupo a:

@ManyToOne 
@JoinColumns({ 
    @JoinColumn(name="gameid", referencedColumnName = "gameid", insertable = false, updatable = false), 
    @JoinColumn(name="groupTag", referencedColumnName = "grouptag") 
}) 
private Group group; 

me sale un error que la mezcla no está permitido: Causado por: org.hibernate.AnnotationException: no está permitido Mezcla columnas insertables insertables y no en una propiedad : net.hq.model.Charactergroup

Cuando hago tanto insertable = false, ya no puedo configurar la etiqueta de grupo. It groupTag se mantiene vacío después de la inserción y se establece gameid. : -/

La forma en que añadir un carácter a un grupo:

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

Método en la clase Grupo:

public void addCharacter(Character character){ 
    if(this.characters == null) 
     this.characters = new ArrayList<Character>(); 

    this.characters.add(character); 
    character.setGroup(this); 
} 
+0

que sería mucho más fácil ayudar si usted podría proporcionar esquema de base de datos relacionada y especificar @Table de sus clases. – Osw

+0

Publicada al final de mi pregunta. Saludos. – mkuff

Respuesta

3

¿Seguro que no se puede utilizar para estos insertable = false, updateable = false@JoinColumn s?

Por lo que yo entiendo, puede inicializar gameid vez mediante el establecimiento de game propiedad, y después de eso que no es necesario cambiarlo desde Tile s y s Group pertenecen a la misma Game.

+0

Sí, eso es cierto. Pero parece que no tengo permiso para mezclar los atributos de JoinColums. Explicación en PS 2. Saludos – mkuff

7

lo que necesita hacer esto:

@ManyToOne 
@JoinColumns({ 
    @JoinColumn(name="gameid", referencedColumnName = "gameid", insertable = false, updatable = false), 
    @JoinColumn(name="groupTag", referencedColumnName = "grouptag", insertable = false, updatable = false) 
}) 
private Group group; 
+0

Gracias Sanama Na que me acercó mucho. Tengo que cambiar para usar corchetes ya que JoinColumns esperaba una matriz. – bigMC28

Cuestiones relacionadas