Hibernate как ORM очень гибкий и универсальный инструмент. При разработке на его основе испытываешь удовольствие, но как в каждом продукте есть свои неудобные моменты. Один из тех моментов, которые периодически раздражают, - это отсутствие удобного механизма по добавлению критериев по связанным объектам через Criteria API.
Рассмотрим подобную ситуацию на примере. Имеются классы Company, Address, Product, Customer связанный между собой. Данная модель может вам не нравиться, но она лишь написана для того, чтобы продемонстрировать проблему.
public class Product {
public Long id;
public String name;
public String description;
public Company company;
public Set<Customer> customers = new HashSet<Customer>();
}
public class Company {
public Long id;
public String name;
public Address address;
public Set<Product> products = new HashSet<Product>();
}
public class Address {
public Long id;
public String name;
public Set<Company> companies = new HashSet<Company>();
}
public class Customer {
public Long id;
public Set<Product> products = new HashSet<Product>();
}
Выберем пользователей, которые совершали покупки продуктов компаний, зарегистрированных на территории Москвы.
Criteria cr = session.CreateCriteria(Customer.class);
cr.createCriteria("products").createCriteria("company").createCriteria("address").add(Restrictions.like("name", "%Москва%"));
При этом существуют некоторые ограничения. Например, если вы в переменную cr попытаетесь еще добавить критерий по описанию продукта вот таким вот образом:
cr.createCriteria("products").add(Restrictions.like("description", "вафли%"))
В результате возникнет исключение "duplicate association path" :(. А что делать, если такой критерий собирается динамически?
Так как же можно упростить добавление критерия, вызвав добавление связки только один раз "products.company.address" и при этом еще избежать дублирования при добавлении критерия "products"?