Я борюсь около двух дней со следующей проблемой и надеюсь, что вы можете дать мне толчок в правильном направлении. Обучающие материалы и примеры, которые я нашел во время своего исследования, всегда показывали, как легко работать в критериях API. Прежде всего, у меня есть два класса:
@Entity
public class Offer {
private String name;
@ManyToOne private Location location;
private String tags;
}
и
@Entity
public class Location {
private String name;
private string tags;
}
Поскольку мне нужно избегать циклических ссылок, связь между этими классами является только однонаправленной. В этих классах много дополнительных атрибутов, и я хочу создавать динамические запросы в зависимости от моего поискового фильтра. Следующий оператор SQL должен объяснить, что мне нравится делать:
SELECT l
FROM Offer o
JOIN o.location l
WHERE o.tags LIKE :sometag AND l.tags LIKE :someothertag
После реализации с критериями API я получил этот код:
CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<Location> criteriaQuery = criteriaBuilder.createQuery(Location.class);
criteriaQuery = criteriaQuery.distinct(true);
Join location;
ArrayList<Predicate> whereList = new ArrayList<Predicate>();
// if filter by offer, use offer as main table and join location table
if (filter.getOfferTags() != null) {
Root<Offer> offer = criteriaQuery.from(Offer.class);
location = offer.join("location");
// limit to offering tags
Path<String> tagPath = offer.get("tags");
for (String tag : filter.getOfferTags()) {
Predicate whereTag = criteriaBuilder.like(tagPath, "%" + tag + "%");
whereList.add(whereTag);
}
} else {
// else use location table as base
location = (Join<Location, Location>) criteriaQuery.from(Location.class);
}
Но если я выполню это, я получу следующее сообщение об ошибке из моей базы данных H2:
Column "LOCATION.ID" not found; SQL statement:
SELECT DISTINCT LOCATION.ID, LOCATION.NAME
FROM OFFER t0, LOCATION t1
WHERE t0.TAGS LIKE ? AND t1.TAGS LIKE ?
База данных ожидает t1.ID
и t1.NAME
в предложении select, а не LOCATION.ID
и LOCATION.NAME
. Как я могу сказать JPA создать «правильный» запрос? Я что-то упустил в своем коде?
Я использую Glassfish 3.1.1 с Eclipse Link и базой данных H2.