即使保存子项,Spring Data Jpa Test也会返回空列表

时间:2015-11-07 20:08:14

标签: spring hibernate jpa spring-data spring-data-jpa

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

上述测试失败,因为game2.getPlayers() returns null

已经完成了JpaRepository caches newly created object. How to refresh it?,但无法弄清楚如何解决。

上述代码中使用的方法flushAndClear为空白,如下所示:

protected void flushAndClear() {
//        sessionFactory.getCurrentSession().flush();
//        sessionFactory.getCurrentSession().clear();
    }

非常感谢任何帮助。

更新

游戏&播放器映射代码:

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

我在测试环境中使用HSQL db。以下是配置:

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

1 个答案:

答案 0 :(得分:4)

您需要编写一个有效的FlushAndClear方法。如果没有为game2加载数据库,而是从内部缓存加载class TestXXX { @PersistenceContext private EntityManager em. private flushAndClear() { em.flush(); em.clear(); } } 。如果没有加载,则关联不会更新。

throw new RuntimeException("Help!  Somebody debug me!  I'm crashing!");