Sto usando Hibernate come provider di persistenza e modellazione miei entità con JPA 2.JPA 2: utilizzo multiplo colonna chiavi esterne
Ora una domanda si avvicinò e spero che tu mi possa aiutare.
Nella mia applicazione è possibile aprire una partita, creare gruppi di giocatori e spostarsi sulla mappa (tessere (2d)).
La mia definizioni di entità: Gioco:
@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;
Tile (una tessera verrà creato da un modello e appartiene ad una sola partita):
@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;
}
Carattere:
@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;
Come puoi vedere ho dovuto rinominare la colonna Gameid in groupgameid e tilegam eid. Questo non è molto carino perché avrei bisogno del gameid nel personaggio solo una volta. Per contrassegnare le colonne fk nel carattere da tile e group con insertable = false, updateable = false consentirà la generazione sql, ma non posso modificare/impostare questi valori.
Certo, potrei introdurre un pk artificiale in gruppo e piastrella, ma avrei bisogno di più join.
JPA ha appena limitato che devo consentire alla colonna Gameid più di una volta con altri nomi? O il mio design non è ottimale?
In attesa di feedback e grazie in anticipo. saluti Markus
PS (edit): Al momento ho lasciato che lo Shema generare da Hibernate in fase di avvio fino al mio modello è completo. Ma qui è lo Shema generato (bit semplificato e tagliato fuori alcuni campi non importanti):
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: Ho già giocato con , insertable = false, updatable = false
. Ad esempio quando cambio i JoinColumns gruppo di:
@ManyToOne
@JoinColumns({
@JoinColumn(name="gameid", referencedColumnName = "gameid", insertable = false, updatable = false),
@JoinColumn(name="groupTag", referencedColumnName = "grouptag")
})
private Group group;
ottengo un errore che la miscelazione non è consentito: causato da: org.hibernate.AnnotationException: Miscelazione colonne inseribili inseribili e non in una struttura non è consentito : net.hq.model.Charactergroup
Quando eseguo sia insertable = false, non sono più in grado di impostare il tag di gruppo. GroupTag rimane vuoto dopo l'inserimento e viene impostato gameid. : -/
il mio modo di aggiungere un carattere a un gruppo:
// 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);
Metodo della classe Gruppo:
public void addCharacter(Character character){
if(this.characters == null)
this.characters = new ArrayList<Character>();
this.characters.add(character);
character.setGroup(this);
}
Sarei molto più facile per aiutare se si potesse fornire schema DB correlate e specificare l'annotazione @Table delle classi. – Osw
pubblicato alla fine della mia domanda. Saluti. – mkuff