Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select object from joined table with JPA Criteria-API

I'm fighting about two days with the following problem and hope you can give me a push into the right direction. The tutorials and examples I found during my research always only showed how to easy joins work in the criteria api. First of all I have two classes:

@Entity
public class Offer {

  private String name;
  @ManyToOne private Location location;
  private String tags;
}

and

@Entity
public class Location {
  private String name;
  private string tags;
}

Because I need to avoid circular references the connection beween these classes is only unidirectional. There are a lot of additional attributes in this classes and I want to build dynamic queries depending on my search filter. The following SQL statement shall explain what I like to do:

SELECT l 
FROM Offer o 
JOIN o.location l
WHERE o.tags LIKE :sometag AND l.tags LIKE :someothertag

After implementing this with the criteria api I got to this code:

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);
}

But if I execute this I get the following error message from my H2 Database:

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 ?

The database expects t1.ID and t1.NAME in the select clause and not LOCATION.ID and LOCATION.NAME. How can I tell JPA to create the "right" request? Am I missing something in my code?

I'm using Glassfish 3.1.1 with Eclipse Link and an H2 Database.

like image 522
Ralph Avatar asked Dec 28 '22 05:12

Ralph


1 Answers

I think you just missed a select in your query:

criteriaQuery.select(location);
like image 194
JB Nizet Avatar answered Dec 29 '22 19:12

JB Nizet