1
@RunWith(SpringJUnit4ClassRunner.class)
@Transactional
@ContextConfiguration(classes = SimpleConfiguration.class)
public class CustomerSyncRepositoryTest {

    @Autowired
    CustomerSyncRepository customerSyncRepository;


    @Autowired
    CustomerRepository customerRepository;

    @Autowired
    MemberShipRepository memberShipRepository;

    @Test
    public void collectDataTest() {
        CustomerSync customerSyncOne = new CustomerSync();
        customerSyncOne.setMembershipNumber("1");
        customerSyncRepository.save(customerSyncOne);

        Membership membership = new Membership();
        membership.setName("钻石");
        membership = memberShipRepository.save(membership);

        Customer customerOne = new Customer();
        customerOne.setMembershipNumber("1");
        customerOne.setMembership(membership);
        customerRepository.save(customerOne);

        Customer customerTwo = new Customer();
        customerTwo.setMembershipNumber("2");
        customerTwo.setMembership(membership);
        customerRepository.save(customerTwo);

        customerSyncRepository.collectMissingSyncData();
        assertEquals(2, customerSyncRepository.findAll().size());
    }
}

there should be 2 records in db, but it seems that the new record it is never inserted into DB. And when I test it by starting up the application, there are 2 records in db. Is there any configruation I miss in unit test? here is what customerSyncRepository.collectMissingSyncData() do.

public interface CustomerSyncRepository  extends JpaRepository<CustomerSync, String> {
    @Modifying
    @Query(nativeQuery = true, value = "insert into customer_sync(membershipNumber,membership, cnName, enName, phoneNum, password, email, firstname, lastname, active, otherType, otherNum ) SELECT " +
            "a.membershipNumber, " +
            "b.name, " +
            "a.cnName, " +
            "a.enName, " +
            "a.phoneNum ," +
            "a.password, " +
            "a.email, " +
            "a.firstname, " +
            "a.lastname, " +
            "a.active, " +
            "a.otherType, " +
            "a.otherNum " +
            "FROM " +
            "customer a " +
            "JOIN membership b ON (a.membership_id = b.id) " +
            "WHERE " +
            "a.membershipNumber NOT IN (select membershipNumber from customer_sync) ")
    void collectMissingSyncData();

    List<CustomerSync> findBySync(boolean isSync);
}
Cherry Zhang
  • 101
  • 1
  • 11

1 Answers1

2

The issue is that your saved entities are being stored in the 1st level cache. In other words, they are not yet in the database.

To solve this, just flush the state of the 1st level cache into the database.

One way is to inject the EntityManager into your test class like this...

@PersistenceContext
EntityManager entityManager;

... and then invoke entityManager.flush() after each call to customerRepository.save(..) (or at least once before the call to customerSyncRepository.findAll()).

The other option is simply to invoke the flush() method on the repository itself -- for example, if you're using Spring Data JPA repositories.

Sam Brannen
  • 29,611
  • 5
  • 104
  • 136
  • That's true. I've already figured it out. But without the need to add the persistenceContext, just enough with customerRepository.flush() Still, thanks. – Cherry Zhang Jul 09 '15 at 13:58
  • Sure. That'll also work. I wasn't thinking about the fact that Spring Data JPA automatically adds a `flush()` method to repositories. – Sam Brannen Jul 09 '15 at 14:01