2011-01-16 48 views
12

Tôi đang sử dụng Hibernate làm nhà cung cấp kiên trì và lập mô hình thực thể của mình với JPA 2.JPA 2: sử dụng nhiều cột trong khóa ngoài

Bây giờ câu hỏi đã xuất hiện và tôi hy vọng bạn có thể giúp tôi.

Trong ứng dụng của mình, bạn có thể mở một Trò chơi, tạo các nhóm người chơi trong đó và đi bộ xung quanh trên bản đồ (các ô (2ngày)).

Đầu tiên định nghĩa thực thể của tôi: Trò chơi:

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

Ngói (một gạch sẽ được tạo ra từ một mẫu và thuộc về chỉ là một trò chơi):

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

Đặc tính:

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

Như bạn có thể thấy tôi phải đổi tên cột trò chơi thành groupgameid và tilegam eid. Điều này không phải là rất đẹp bởi vì tôi sẽ cần các gameid trong nhân vật chỉ một lần. Để đánh dấu các cột fk trong ký tự từ gạch và nhóm có chèn = false, updateable = false sẽ cho phép tạo sql, nhưng tôi không thể thay đổi/đặt giá trị này.

Chắc chắn tôi có thể giới thiệu một pk nhân tạo trong nhóm và lát gạch, nhưng tôi sẽ cần thêm tham gia.

JPA có bị hạn chế rằng tôi phải cho phép cột trò chơi nhiều hơn một lần với các tên khác không? Hay thiết kế của tôi không tối ưu?

Mong nhận được phản hồi của bạn và cảm ơn trước. lời chào Markus

PS (chỉnh sửa): Lúc này tôi để cho shema tạo bằng ngủ đông lúc khởi động cho đến khi mô hình của tôi hoàn tất. Nhưng đây là shema tạo (bit đơn giản hóa và cutted ra một số lĩnh vực quan trọng):

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: Tôi đã chơi xung quanh với , insertable = false, updatable = false. Ví dụ khi tôi thay đổi JoinColumns nhóm:

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

tôi nhận được một lỗi mà trộn không được phép: Nguyên nhân: org.hibernate.AnnotationException: Trộn cột insertable insertable và phi trong một tài sản không được phép : net.hq.model.Charactergroup

Khi tôi đặt cả hai có thể chèn = false, tôi không thể đặt thẻ nhóm nữa. Nó groupTag vẫn trống sau khi chèn và gameid được thiết lập. : -/

The way i thêm một nhân vật cho một nhóm:

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

Phương pháp trong Nhóm Lớp:

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

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

Tôi muốn được dễ dàng hơn nhiều để giúp đỡ nếu bạn có thể cung cấp schema DB có liên quan và xác định chú thích @Table của lớp học của bạn. – Osw

+0

Được đăng ở cuối câu hỏi của tôi. Lời chào hỏi. – mkuff

Trả lời

3

Bạn có chắc chắn bạn không thể sử dụng insertable = false, updateable = false cho các @JoinColumn s?

Theo như tôi hiểu, bạn có thể khởi tạo gameid một lần bằng cách thiết lập game bất động sản, và sau đó bạn không cần phải thay đổi nó từ Tile s và Group s thuộc cùng Game.

+0

Đúng vậy. Nhưng có vẻ như tôi không được phép trộn các thuộc tính JoinColums. Giải thích trong PS 2. Lời chào – mkuff

7

Bạn cần làm điều này:

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

Cảm ơn bạn Sanama Na, người đã giúp tôi thực sự thân thiết. Tôi phải thay đổi để sử dụng dấu ngoặc vuông vì JoinColumns mong đợi một mảng. – bigMC28

Các vấn đề liên quan