I've been searching the web with success for the following case but didn't manage to make it work for me (maybe because the example I've seen use TopLink...). So here is the case:
Both Game and Player has oneToMany with GamePlayer.
I can retreive properly any previously saved relationship (enter directly in the DB) but I can't create one using the following code. My Id column get added twice in the SQL generated which cause to failed:
Exception:
Caused by: java.sql.SQLSyntaxErrorException: Column name 'GAME_ID' appears more than once times in the column list of an INSERT statement.
SQL from log:
Code:
Hibernate: insert into pascal.GAME_PLAYER (comment, game_id, play, player_id, GAME_ID, PLAYER_ID) values (?, ?, ?, ?, ?, ?)
Game Entity
Code:
@Entity
public class Game implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
@Column(name="GAME_ID")
@GeneratedValue(strategy=TABLE, generator = "GamePKGen")
@TableGenerator(name="GamePKGen", table = "pk_gen", pkColumnName = "pk_name", valueColumnName = "pk_nextval", pkColumnValue = "Game", allocationSize=1, initialValue = 100)
private Long id;
private String name;
@Column(name="GAME_START")
private Timestamp gameStart;
@Column(name="GAME_END")
private Timestamp gameEnd;
private String comment;
@OneToMany(cascade = ALL, mappedBy = "game")
private List<GamePlayer> players;
public Game()
{
players = new ArrayList<GamePlayer>();
}
public static Game findByPK(EntityManager em, Long id)
{
Game result = em.find(Game.class, id);
return result;
}
public static List<Game> findAll(EntityManager em)
{
List<Game> result = (List<Game>) em.createQuery("select g from Game g")
.getResultList();
return result;
}
public static List<Game> findGameForDate(EntityManager em, Date date)
{
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(date);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
java.sql.Timestamp start = new Timestamp(cal.getTimeInMillis());
cal.add(Calendar.DATE, 1);
java.sql.Timestamp end = new Timestamp(cal.getTimeInMillis());
List<Game> result =
(List<Game>) em.createQuery("select g from Game g where g.gameStart>=?1 and g.gameEnd<?2")
.setParameter(1, start)
.setParameter(2, end)
.getResultList();
return result;
}
public int getNumberPlaying()
{
int totalPlaying = 0;
for (GamePlayer gp : getPlayers())
{
if (gp.isPlaying())
totalPlaying++;
}
return totalPlaying;
}
public Long getId() { return this.id; }
public void setId(Long id) { this.id = id; }
public String getName() { return this.name; }
public void setName(String name) { this.name = name; }
public Timestamp getGameStart() { return this.gameStart; }
public void setGameStart(Timestamp gameStart) { this.gameStart = gameStart; }
public Timestamp getGameEnd() { return this.gameEnd; }
public void setGameEnd(Timestamp gameEnd) { this.gameEnd = gameEnd; }
public String getComment() { return this.comment; }
public void setComment(String comment) { this.comment = comment; }
public List<GamePlayer> getPlayers() { return players; }
public void setPlayers(List<GamePlayer> players) { this.players = players; }
public void addPlayer(Player player, PlayStatus willPlay, String comment)
{
GamePlayer gp = new GamePlayer();
gp.setGame(this);
gp.setPlayer(player);
gp.setPlayStatus(willPlay);
gp.setComment(comment);
getPlayers().add(gp);
}
}
Player Entity
Code:
@Entity
public class Player implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
@Column(name="PLAYER_ID")
@GeneratedValue(strategy=TABLE, generator = "PlayerPKGen")
@TableGenerator(name="PlayerPKGen", table = "pk_gen", pkColumnName = "pk_name", valueColumnName = "pk_nextval", pkColumnValue = "Player", allocationSize=1, initialValue = 100)
Long id;
String name;
String username;
String password;
String email;
@Column(name="EMAIL_IF_GAME_CHANGE")
boolean emailIfGameChange;
String comment;
@OneToMany(mappedBy="player")
List<GamePlayer> games;
public static Player findByPK(EntityManager em, Long id)
{
Player result = em.find(Player.class, id);
return result;
}
public static List<Player> findAll(EntityManager em)
{
List<Player> result = em.createQuery("select p from Player p")
.getResultList();
return result;
}
public static Player findByUserName(EntityManager em, String username)
{
Player result = (Player) em.createQuery("select p from Player p where p.username=:username")
.setParameter("username", username)
.getSingleResult();
return result;
}
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public boolean isEmailIfGameChange() { return emailIfGameChange; }
public void setEmailIfGameChange(boolean emailIfGameChange) { this.emailIfGameChange = emailIfGameChange; }
public String getComment() { return comment; }
public void setComment(String comment) { this.comment = comment; }
}
GamePlayer Entity
Code:
@Entity
@Table(name="GAME_PLAYER")
@IdClass(GamePlayer.PK.class)
public class GamePlayer implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
Long gameId;
@Id
Long playerId;
Integer play;
String comment;
@ManyToOne
@JoinColumn(name="game_id")
Game game;
@ManyToOne
@JoinColumn(name="player_id")
Player player;
public enum PlayStatus
{
No, Yes, Maybe
};
public GamePlayer()
{
setPlayStatus(PlayStatus.No);
}
// public static GamePlayer findByPK(EntityManager em, Long gameId, Long playerId)
// {
// GamePlayer result = (GamePlayer)em.find(GamePlayer.class, new GamePlayer.PK(gameId, playerId));
// return result;
// }
public static List<GamePlayer> findByGameId(EntityManager em, Long gameId)
{
List<GamePlayer> result =
em.createQuery("select o from GamePlayer o where o.gameId=?1")
.setParameter(1, gameId)
.getResultList();
return result;
}
public boolean isPlaying() { return getPlayStatus()==PlayStatus.Yes; }
public PlayStatus getPlayStatus()
{
int status = getPlay()!=null ? getPlay() : 1;
switch (status) {
case 0:
return PlayStatus.No;
case 2:
return PlayStatus.Maybe;
case 1:
default:
return PlayStatus.Yes;
}
}
public void setPlayStatus(PlayStatus playStatus)
{
setPlay(playStatus.ordinal());
}
public Integer getPlay() { return play; }
public void setPlay(Integer play) { this.play = play; }
public String getComment() { return comment; }
public void setComment(String comment) { this.comment = comment; }
public Game getGame() { return game; }
public void setGame(Game game) { this.game = game; }
public Player getPlayer() { return player; }
public void setPlayer(Player player) { this.player = player; }
public Long getGameId() { return gameId; }
public void setGameId(Long gameId) { this.gameId = gameId; }
public Long getPlayerId() { return playerId; }
public void setPlayerId(Long playerId) { this.playerId = playerId; }
public static class PK implements Serializable
{
@Column(name="GAME_ID")
private Long gameId;
@Column(name="PLAYER_ID")
private Long playerId;
}
}