Cascading ComboBox data binding

I have a problem with the cascading combo box data binding. I want to do something like this: https://support.office.com/en-gb/article/create-a-cascading-list-box-1702993d-d670-4d9b-8063-acabacb76605. This means two combo boxes - one with categories and the other with sub-categories (e.g. 1st combo box with product types and 2nd combo box with specific products, 1st combo box with continents and 2nd combo box with countries on these continents, etc.).

My code:
Backend, entities, Customer.java:

package org.test.backend.entities;
// [...]

@Entity 
@Cacheable(true)
@Table(name = "customers")
public class Customer implements Serializable {
	private long id;
	private String shortName;
	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "continent_id", referencedColumnName = "id")
	private Continent continent;
	
	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "country_id", referencedColumnName = "id")
	private Country country;
	
	@Id
	@Column(name = "id", unique = true, nullable = false, columnDefinition = "bigserial")
	public long getId() {
		return id;
	}
	
	public void setId(long id) {
		this.id = id;
	}

	@Column(name = "short_name", nullable = false, columnDefinition = "varchar", length = 30)
	public String getShortName() {
		return shortName;
	}
	
	public void setShortName(final String shortName) {
		this.shortName = shortName;
	}
	
	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "country_id", nullable = false, columnDefinition = "int4")
	public Country getCountry() {
		return country;
	}

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

	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "continent_id", nullable = false, columnDefinition = "int4")
	public Continent getContinent() {
		return continent;
	}

	public void setContinent(final Continent continent) {
		this.continent = continent;
	}

Backend, entities, Continent.java:

package org.test.backend.entities;
// [...]

@Entity
@Cacheable(true)
@Table(name = "continents")
public class Continent implements Serializable {

	private int id;
	private String continentName;
	private Set<Country> countries = new HashSet<Country>(0);
	private Set<Customer> customers  = new HashSet<Customer>(0);
	
	@Id
	@Column(name = "id", unique = true, nullable = false, columnDefinition = "serial")
	public int getId() {
		return id;
	}
	
	public void setId(int id) {
		this.id = id;
	}
	
	@Column(name = "continent", nullable = false, columnDefinition = "varchar")
	public String getContinentName() {
		return continentName;
	}
	
	public void setContinentName(String continentName)
	{
		this.continentName = continentName;
	}
	
	@OneToMany(fetch = FetchType.LAZY, mappedBy = "continent")
	public Set<Country> getCountries() {
		return countries;
	}
	
	public void setCountries(Set<Country> countries) {
		this.countries = countries;
	}
	
	@OneToMany(fetch = FetchType.LAZY, mappedBy = "continent")
	public Set<Customer> getCustomers() {
		return customers;
	}
	
	public void setCustomers(Set<Customer> customers) {
		this.customers = customers;
	}
	
	@Override
	public String toString() {
		return continentName;
	}
}

Backend, entities, Country.java:

package org.test.backend.entities;
// [...]

@Entity
@Cacheable(true)
@Table(name = "countries")
public class Country implements java.io.Serializable {
	private int id;
	private Continent continent;
	private String countryName;
	private Set<Customer> customers = new HashSet<Customer>(0);
	
	public Country() {
	}
	
	@Id
	@Column(name = "id", unique = true, nullable = false, columnDefinition = "serial")
	public int getId() {
		return id;
	}
	
	public void setId(int id) {
		this.id = id;
	}
	
	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "continent_id", nullable = false, columnDefinition = "int4")
	public Continent getContinent() {
		return continent;
	}
	
	public void setContinent(Continent continent) {
		this.continent = continent;
	}
	
	@Column(name = "country", nullable = false, columnDefinition = "varchar")
	public String getCountryName() {
		return countryName;
	}
	
	public void setCountryName(String countryName) {
		this.countryName = countryName;
	}
	
	@OneToMany(fetch = FetchType.LAZY, mappedBy = "country")
	public Set<Customer> getCustomers() {
		return customers;
	}
	
	public void setCustomers(Set<Customer> customers) {
		this.customers = customers;
	}
	
	@Override
	public String toString() {
		return countryName;
	}
}

Backend, DAO, CustomerDAO.java:

package org.test.backend.dao;
// [...]

@Repository
public interface CustomerDAO extends JpaRepository<Customer, Long> {
	Optional<Customer> findById(Long Id);
	List<Customer> findByShortName(String shortName);
	List<Customer> findByShortNameStartsWithIgnoreCase(String shortName);
}

Backend, DAO, ContinentDAO.java:

package org.test.backend.dao;
// [...]

@Repository
public interface ContinentDAO extends JpaRepository<Continent, Integer> {
	Optional<Continent> findById(Integer Id);
	List<Continent> findByContinentName(String continentName);
}

Backend, DAO, CountryDAO.java:

package org.test.backend.dao;
// [...]

@Repository
public interface CountryDAO extends JpaRepository<Country, Integer> {
	Optional<Country> findById(Integer Id);
	List<Country> findByCountryName(String countryName);
	List<Country> findByContinent(Continent continent);
	List<Country> findAllByContinent(Continent continent);
}

UI, CustomerEditor.java:

package org.test.ui;
// [...]

public class CustomerEditorForm extends FormLayout {
	private final CustomerDAO customerRepository;
	private CountryDAO countryDataProvider;

	private Customer customer;

	/* Fields to edit properties in Customer entity */
	@PropertyId("shortName")
	TextField shortNameField = new TextField("Name:");

	@PropertyId("continent")
	ComboBox<Continent> continentField = new ComboBox<Continent>("Continent:");

	@PropertyId("country")
	ComboBox<Country> countryField = new ComboBox<Country>("Country:");

	private MainView mainView;

	/* Action buttons */
	Button saveButton = new Button("Save", new Icon(VaadinIcon.CHECK));
	Button cancelButton = new Button("Cancel");
	Button deleteButton = new Button("Delete", new Icon(VaadinIcon.TRASH));

	Binder<Customer> customerBinder = new Binder<>(Customer.class);
	Binder<Continent> continentBinder = new Binder<>(Continent.class);

	@Autowired
	public CustomerEditorForm(MainView mainView, CustomerDAO customerRepository, ContinentDAO continentDataProvider,
			CountryDAO countryDataProvider) {
		this.mainView = mainView;

		this.customerRepository = customerRepository;
		this.countryDataProvider = countryDataProvider;

		HorizontalLayout buttonsLayout = new HorizontalLayout(saveButton, deleteButton);
		add(shortNameField, continentField, countryField, buttonsLayout);
		
		// bind using naming convention
		customerhBinder.bindInstanceFields(this);

		continentField.setItemLabelGenerator(createItemLabelGenerator(Continent::getContinentName));
		continentField.setDataProvider(
				DataProvider.ofCollection(continentDataProvider.findAll(Sort.by("continentName").descending())));
		customerBinder.forField(continentField).bind(
				customer -> customer.getContinent(),
				(customer, continent) -> customer.setContinent(continent));
		
		countryField.setDataProvider(new ListDataProvider<Country>(new HashSet<>())); // No items initially because countryField combo box has no value yet
		customerBinder.forField(countryField).bind(
				customer -> customer.getContinent() == null ? null : customer.getCountry(),
				(customer, country) -> {
					if (customer.getContinent() != null) {
						customer.setCountry(country);
					}
				});
		countryField.setEnabled(false); // Disable because no items initially  
		
		customerBinder.addValueChangeListener(event -> {
			customerBinder.setBean(customerBinder.getBean()); // Forces bound components to get the value again (refresh)
			refillCountryFieldData();
		});

		// to make sure that the save and delete buttons are disabled by default
		setCustomer(null);

		saveButton.addClickListener(e -> this.save());
		deleteButton.addClickListener(e -> this.delete());
		cancelButton.addClickListener(e -> setCustomer(customer));
	}

	/**
	 * Gets called when binder value has changed. This way I circumvent the fact
	 * that a normal valueChangeListener of a component is fired before the
	 * binder-bean is updated
	 */
	private void refillCountryFieldData() {
		Continent selectedContinent = customerBinder.getBean().getContinent();
		if (selectedContinent != null) {
			countryField.setDataProvider(DataProvider.ofCollection(countryDataProvider.findAllByContinent(selectedContinent)));
	        countryField.setEnabled(true);
	    } else {
	        // There is no continent selected, therefore no countries should be allowed to be selected
	    	countryField.setDataProvider(new ListDataProvider<Country>(new HashSet<>()));
	    	countryField.setEnabled(false);
	    }
		customerBinder.setBean(customerBinder.getBean());
	}

	public void setCustomer(customer customer) {
		this.customer = customer;
		customerBinder.setBean(customer);

		boolean enabled = (customer != null);
		saveButton.setEnabled(enabled);
		deleteButton.setEnabled(enabled);
		if (enabled) {
			shortNameField.focus();
		}
	}

	private void delete() {
		customerRepository.delete(customer);
		mainView.updateList();
		setCustomer(null);
	}

	private void save() {
		customerRepository.save(customer);
		mainView.updateList();
		setCustomer(null);
	}
}

And this code don’t work correctly.
A correct list of countries from the continent selected in continentField ComboBox is displayed in countryField ComboBox. But selection in countryField ComboBox is always empty. I can’t select anything from countryField ComboBox (after selection and clicking the field is still empty) and selection is not saved in database.