Reputation: 13734
@Test
public void testAddPlayerToGame() {
gameRepository.save(createTestGame());
Game game = gameRepository.findOne(1l);
assertTrue(game.getId() > 0);
Player p = new Player();
p.setName("test 1");
p.setGame(game);
p.setChips(5000);
assertTrue(p.getId() == null);
playerRepository.saveAndFlush(p);
assertTrue(p.getId() != null);
flushAndClear();
Game game2 = gameRepository.findOne(1l);
assertEquals(1, game2.getPlayers().size());
}
The above test fails because game2.getPlayers() returns null
.
Already went through JpaRepository caches newly created object. How to refresh it? but couldn't figure out how to solve.
The method flushAndClear
used in the above code is blank, as follows :
protected void flushAndClear() {
// sessionFactory.getCurrentSession().flush();
// sessionFactory.getCurrentSession().clear();
}
Any help is really appreciated.
Update
Game & Player mapping code :
@Entity
@Table(name="game")
public class Game implements Serializable {
private static final long serialVersionUID = -495064662454346171L;
private long id;
private int playersRemaining;
private Player playerInBTN;
private GameType gameType;
private String name;
private boolean isStarted;
private Set<Player> players;
private HandEntity currentHand;
private GameStructure gameStructure;
@Column(name="game_id")
@Id
@GeneratedValue(strategy=GenerationType.TABLE)
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@Column(name="players_left")
public int getPlayersRemaining() {
return playersRemaining;
}
public void setPlayersRemaining(int playersRemaining) {
this.playersRemaining = playersRemaining;
}
@OneToOne
@JoinColumn(name="btn_player_id")
public Player getPlayerInBTN(){
return playerInBTN;
}
public void setPlayerInBTN(Player playerInBTN){
this.playerInBTN = playerInBTN;
}
@Column(name="game_type")
@Enumerated(EnumType.STRING)
public GameType getGameType() {
return gameType;
}
public void setGameType(GameType gameType) {
this.gameType = gameType;
}
@OneToMany(mappedBy="game", fetch=FetchType.LAZY)
public Set<Player> getPlayers() {
return players;
}
public void setPlayers(Set<Player> players) {
this.players = players;
}
@Column(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(name="is_started")
public boolean isStarted() {
return isStarted;
}
public void setStarted(boolean isStarted) {
this.isStarted = isStarted;
}
@OneToOne(fetch=FetchType.EAGER)
@JoinColumn(name="current_hand_id")
public HandEntity getCurrentHand() {
return currentHand;
}
public void setCurrentHand(HandEntity currentHand) {
this.currentHand = currentHand;
}
@OneToOne(fetch=FetchType.EAGER, cascade={CascadeType.ALL})
@JoinColumn(name="game_structure_id")
public GameStructure getGameStructure() {
return gameStructure;
}
public void setGameStructure(GameStructure gameStructure) {
this.gameStructure = gameStructure;
}
}
@Entity
@Table(name="player")
public class Player implements Comparable<Player>, Serializable{
private static final long serialVersionUID = -1384636077333014255L;
private String id;
private Game game;
private String name;
private int chips;
private int gamePosition;
private int finishPosition;
private boolean sittingOut;
@JsonIgnore
@Column(name="player_id")
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid2")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@JsonIgnore
@ManyToOne
@JoinColumn(name="game_id")
public Game getGame() {
return game;
}
public void setGame(Game game) {
this.game = game;
}
@Column(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(name="chips")
public int getChips() {
return chips;
}
public void setChips(int chips) {
this.chips = chips;
}
@Column(name="game_position")
public int getGamePosition() {
return gamePosition;
}
public void setGamePosition(int gamePosition) {
this.gamePosition = gamePosition;
}
@Column(name="finished_place")
public int getFinishPosition() {
return finishPosition;
}
public void setFinishPosition(int finishPosition) {
this.finishPosition = finishPosition;
}
@Column(name="sitting_out")
public boolean isSittingOut() {
return sittingOut;
}
public void setSittingOut(boolean sittingOut) {
this.sittingOut = sittingOut;
}
@Override
public boolean equals(Object o){
if(o == null || !(o instanceof Player)){
return false;
}
Player p = (Player) o;
if(this.getId() == null){
return this.getName().equals(p.getName());
}
return this.getId().equals(p.getId());
}
@Override
public int hashCode(){
if(id == null){
return name.hashCode();
}
return id.hashCode();
}
@Override
@Transient
public int compareTo(Player p){
return this.getGamePosition() - p.getGamePosition();
}
}
I am using HSQL db in the testing environment. Following is the configuration :
@Configuration
@EnableJpaRepositories(basePackages = "com.nitinsurana.repos")
@EnableTransactionManagement
class TestDataConfig {
@Bean(name = "transactionManager")
@Autowired
public PlatformTransactionManager getTransactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
jpaTransactionManager.setEntityManagerFactory(entityManagerFactory);
return jpaTransactionManager;
}
@Bean
public EntityManagerFactory entityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan("com.nitinsurana.domain");
em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
em.setJpaProperties(getHibernateProperties());
em.afterPropertiesSet();
return em.getObject();
}
// @Bean
// public EntityManager entityManager(HibernateEntityManagerFactory entityManagerFactory) {
// HibernateEntityManager entityManager = (HibernateEntityManager) entityManagerFactory.createEntityManager();
// entityManager.setFlushMode(FlushModeType.AUTO FlushMode.ALWAYS);
// return entityManager;
// }
private Properties getHibernateProperties() {
Properties prop = new Properties();
prop.put("hibernate.show_sql", "false");
prop.put("hibernate.hbm2ddl.auto", "create");
prop.put("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
return prop;
}
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
// .addScript("classpath:com/bank/config/sql/schema.sql")
// .addScript("classpath:com/bank/config/sql/test-data.sql")
.build();
}
}
Upvotes: 4
Views: 2989
Reputation: 120851
You need to write a FlushAndClear method that works. If not game2
gets not loaded for the database but from the internal cache. And if it is not loaded then the releationship become not updated.
class TestXXX {
@PersistenceContext
private EntityManager em.
private flushAndClear() {
em.flush();
em.clear();
}
}
Upvotes: 7