1

I am trying to write a test for custom spring data repository. I'm also using QueryDSL. I am new to spring-data. I use spring support for HSQL DB in testing. MySQL for dev.

Problem: I do not see updated data in tests if I use custom repository.

public interface AuctionRepository extends AuctionRepositoryCustom, CrudRepository<Auction, Long>, QueryDslPredicateExecutor<Auction> {
// needed for spring data crud
}

.

public interface AuctionRepositoryCustom {
    long renameToBestName();
}

.

public class AuctionRepositoryImpl extends QueryDslRepositorySupport implements AuctionRepositoryCustom {
    private static final QAuction auction = QAuction.auction;

public AuctionRepositoryImpl() {
    super(Auction.class);
}

@Override
public long renameToBestName() {
    return update(auction)
        .set(auction.name, "BestName")
        .execute();
}
}

My test
Somehow fails at last line

public class CustomAuctionRepositoryImplTest extends AbstractIntegrationTest {
@Inject
AuctionRepository auctionRepository;

@Test
public void testDoSomething() {
    Auction auction = auctionRepository.findOne(26L);
    assertEquals("EmptyName", auction.getName());

    // test save
    auction.setName("TestingSave");
    auctionRepository.save(auction);
    Auction saveResult = auctionRepository.findOne(26L);
    assertEquals("TestingSave", saveResult.getName());

    // test custom repository
    long updatedRows = auctionRepository.renameToBestName();
    assertTrue(updatedRows > 0);
    Auction resultAuction = auctionRepository.findOne(26L);
    assertEquals("BestName", resultAuction.getName()); // FAILS expected:<[BestNam]e> but was:<[TestingSav]e>
}
}

I can't figure out why data doesn't update when using custom repository. If I start application in dev mode, and call renameToBestName() through controller, everything works as expected, name changes.

Below is Test Configuration if needed

@RunWith(SpringJUnit4ClassRunner.class)
@Transactional
@ActiveProfiles("test")
@ContextConfiguration(classes = {TestBeans.class, JpaConfig.class, EmbeddedDataSourceConfig.class})
@ComponentScan(basePackageClasses = IntegrationTest.class, excludeFilters = @Filter({Configuration.class}))
public abstract class AbstractIntegrationTest {
}

.

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackageClasses = Application.class)
class JpaConfig {

    @Value("${hibernate.dialect}")
    private String dialect;
    @Value("${hibernate.hbm2ddl.auto}")
    private String hbm2ddlAuto;
    @Value("${hibernate.isShowSQLOn}")
    private String isShowSQLOn;

    @Autowired
    private DataSource dataSource;

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactory.setDataSource(dataSource);
        entityManagerFactory.setPackagesToScan("auction");
        entityManagerFactory.setJpaVendorAdapter(new HibernateJpaVendorAdapter());

        Properties jpaProperties = new Properties();
        jpaProperties.put(org.hibernate.cfg.Environment.DIALECT, dialect);
        if ( !hbm2ddlAuto.isEmpty()) {
            jpaProperties.put(org.hibernate.cfg.Environment.HBM2DDL_AUTO, hbm2ddlAuto);
        }
        jpaProperties.put(org.hibernate.cfg.Environment.SHOW_SQL, isShowSQLOn);
        jpaProperties.put(org.hibernate.cfg.Environment.HBM2DDL_IMPORT_FILES_SQL_EXTRACTOR, "org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor");
        entityManagerFactory.setJpaProperties(jpaProperties);

        return entityManagerFactory;
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        return new JpaTransactionManager();
    }
}
Etruskas
  • 194
  • 10
  • What does `AbstractIntegrationTest` look like? – geoand May 07 '14 at 10:56
  • edited and added some configuration. I will add more if needed. Thanks for trying to help. – Etruskas May 07 '14 at 11:05
  • Does the renaming work if you try plain old JPQL or entityManager.update? – geoand May 07 '14 at 11:52
  • I've tried `entityManager.refresh(resultAuction);` - test passed. That's good :-) Thanks. But still, why this line is needed? Maybe I'm missing some configuration? – Etruskas May 07 '14 at 12:26
  • I don't really know since I have not worked with QueryDSL that much – geoand May 07 '14 at 12:27
  • This case has effectively been covered [here][1]. [1]: http://stackoverflow.com/questions/22533399/why-do-i-not-see-changes-issued-through-an-update-query-with-spring-data-jpa/22551997#22551997 – Oliver Drotbohm May 08 '14 at 07:20

1 Answers1

2

This is due to the update query issued through your code is defined to not evict the object potentially touched by the query from the EntityManager. Read more on that in this answer.

Community
  • 1
  • 1
Oliver Drotbohm
  • 80,157
  • 18
  • 225
  • 211