Как создать JoinTable, который включает в себя как примитив, так и составной первичный ключ в качестве составного ключа таблиц (Spring JPA)? - PullRequest
1 голос
/ 11 января 2020

У меня есть таблицы Users, Players, CoopGames и CoopGamesPlayers. Концептуально я пытаюсь воссоздать отношения типа Order / OrderProducts. В моем случае каждая запись CoopGamesPlayers имеет в качестве ключа идентификатор CoopGame и идентификатор игрока. Однако я застрял, потому что в моем случае мой класс Player имеет сам составной первичный ключ: сгенерированный идентификатор игрока, а также внешний ключ идентификатора пользователя. Я немного потерян. Я настроил это в соответствии с руководством для Order.OrderProducts, но я не эксперт JPA и никогда не использовал составные ключи в JoinTable. Код:

public class PlayerPK implements Serializable {

    @ManyToOne(optional = false, fetch = FetchType.EAGER)
    @JoinColumn(name = "id")
    private Player player;

    @ManyToOne(optional = false, fetch = FetchType.EAGER)
    @JoinColumn(name = "userid")
    private User user;
}

@Entity
@Table(name = "players")
public class Player implements Serializable {

    @EmbeddedId
    private PlayerPK pk;

    @Column(name = "image")
    private String image;
}

@Entity
@Table(name = "coop_games")
public class CoopGame {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @OneToMany(mappedBy = "pk", fetch = FetchType.EAGER)
    private List<CoopGamesPlayers> players;
}

public class CoopGamesPlayersPK implements Serializable {

    @JsonBackReference
    @ManyToOne(optional = false, fetch = FetchType.EAGER)
    @JoinColumn(name = "coop_game_id")
    private CoopGame game;

    @ManyToOne(optional = false, fetch = FetchType.EAGER)
    @JoinColumns({
        @JoinColumn(name="playerid", referencedColumnName="id"),
        @JoinColumn(name="userid", referencedColumnName="userid")
    })
    @MapsId("pk")
    private Player player;
}

@Entity
@Table(name = "coop_games_players")
public class CoopGamesPlayers {

    @EmbeddedId
    private CoopGamesPlayersPK pk;

    public CoopGamesPlayers(CoopGame game, Player player) {
        pk = new CoopGamesPlayersPK();
        pk.setGame(game);
        pk.setPlayer(player);
    }
}

@Entity
@Table(name = "coop_games")

public class CoopGame {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @OneToMany(mappedBy = "pk", fetch = FetchType.EAGER)
    private List<CoopGamesPlayers> players;
}

1 Ответ

1 голос
/ 13 января 2020

Я думаю, вам лучше переосмыслить свою модель данных со всеми взаимосвязями (какую проблему следует решить? ..).

Что касается таблицы CoopGamesPlayers: если вы просто хотите использовать CoopGamesPlayers в качестве объединяемой таблицы, вам не нужен CoopGamesPlayersPK.

CoopGame и CoopGamesPlayers должны выглядеть примерно так:

@Entity
@Table(name = "coop_games")
public class CoopGame {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @OneToMany(mappedBy = "game", fetch = FetchType.EAGER)
    private List<CoopGamesPlayers> players;
}

@Entity
@Table(name = "coop_games_players")
public class CoopGamesPlayers {

    @EmbeddedId
    private PlayerPK pk;

    @JsonBackReference
    @ManyToOne(optional = false, fetch = FetchType.EAGER)
    @JoinColumn(name = "coop_game_id")
    private CoopGame game;

    @ManyToOne(optional = false, fetch = FetchType.EAGER)
    @JoinColumns({
            @JoinColumn(name = "playerid", referencedColumnName = "id"),
            @JoinColumn(name = "userid", referencedColumnName = "userid")
    })
    @MapsId("id") 
    private Player player;
}

@MapsId("id") - идентификатор, потому что вы хотите, чтобы идентификатор игрока был fk или?

...