Spring repository cascade

1.3k Views Asked by At

I'm using Spring Data repository to save my entities, but for some reason the cascade doesn't work for the test saveCountryAndNewCity() : the city doesn't get saved but it works for saveCityAndNewCountry() which is similar. Can someone help me to figure out why? Thx.

public class City {
@Cascade(CascadeType.ALL)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "countryid", nullable = false, insertable = true, updatable = true)
private Country country;

public void setCountry(Country country) {
    this.country = country;
    country.getCities().add(this);
}

}


public class Country {
@Cascade(CascadeType.ALL)
@OneToMany(fetch = FetchType.EAGER, mappedBy = "country")
private Set<City> cities = new HashSet<City>(0);

public void addCity(City city){
    this.cities.add(city);
    city.setCountry(this);
}
}


@Test 
@Transactional
public void saveCountryAndCity() throws Exception {
    Country country = countryRepository.findOneByName("Canada");
    City newCity = new City();
    newCity.setName("Quebec");
    country.addCity(newCity);

    countryRepository.save(country);

}

@Test 
public void saveCityAndNewCountry() throws Exception {
    City city = cityRepository.findOneByName("London");

    Country country = new Country();
    country.setName("myCountry");
    city.setCountry(country);

    cityRepository.save(city);
}
1

There are 1 best solutions below

0
On

Your method that doesn't "work" is marked as @Transactional. By default, Spring will rollback any transactional behavior at the end of the test method. The method that you say it "works" is not transactional and Spring testing framework doesn't know it needs to roll it back.

So, from unit tests perspective what you are doing in there with methods that are not @Transactional is wrong. You would want to just test the behavior and then bring back the database to the state it was before the test so that the same database (in the same state) can be used for other tests without being polluted with testing data from other tests.

So, if you want your other method to insert data, remove the @Transactional annotation. But, as I said, this isn't quite how tests should be done.