Resolving Criteria on Polymorphic child class attribute jpa hibernate query
Using hibernate 3.6.10 with hibernate jpa 2.0.
My problem boils down to needing to set some criteria on a column of a child object during a somewhat complex joining query.
I have a set of objects similar to:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Ball
{
private String name;
//...getter and setter crud...
}
@Entity
public class BeachBall extend ball
{
private boolean atTheBeach;
//...getter and setter crud...
}
@Entity
public class SoccerBall extend ball
{
private int numberOfKicks;
//...getter and setter crud...
}
@Entity
public class Trunk
{
private Set<Ball> balls;
@OneToMany(mappedBy = "trunk", cascade = CascadeType.ALL, orphanRemoval = true)
public Set<Ball> getBalls()
{
return balls;
}
}
@Entity
public class Car
{
private Trunk trunk;
private String carModel;
//...getter and setter crud...
}
Now i need to query how many soccer balls have 20 kicks in a car with a specific model.
Using JPA I tried to do something like:
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Car> criteriaQuery = criteriaBuilder.createQuery(Car.class);
Root<Car> car= criteriaQuery.from(Car.class);
Join<Car, Trunk> trunkJoin = car.join(Car_.trunk);
Join<Trunk, Ball> ballJoin = trunkJoin.join(Trunk_.Balls);
criteriaQuery.select(trunk);
Predicate [] restrictions = new Predicate[]{ criteriaBuiler.equal(car.get(carModel), "Civic"), criteriaBuilder.equal(ballJoin.get("numberOfKicks"), 20)};
criteriaQuery.where(restrictions);
TypedQuery<Car> typedQuery = entityManager.createQuery(criteriaQuery);
Car carWithSoccerBalls = typedQuery.getSingleResult();
At runtime the above code dies because numberOfKicks is only on soccerballs and due to how its typed in Trunk it only knows about ball. If i manually create a from on the soccerballs and setup criteria to join it i can query numberOfKicks, however i feel like there must be a way to inform the query that the set is in fact a set.
Please note i cannot post any of the actual code so all above examples are just examples.
Using JPA and hibernate like above is there a way to force hibernate to know that the set< ball > is actually set< soccerball >?
Due to time restrictions i'm taking the easy way out :(. If anyone can answer better then what i have i'll gladly choose their answer over mine.
To make the criteria api recognize that i'm looking for the inherited table i changed my query code to be:
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Car> criteriaQuery = criteriaBuilder.createQuery(Car.class);
Root<Car> car= criteriaQuery.from(Car.class);
Root<Soccerball> soccerballs = criteriaQuery.from(SoccerBall.class);
Join<Car, Trunk> trunkJoin = car.join(Car_.trunk);
Join<Trunk, Ball> ballJoin = trunkJoin.join(Trunk_.Balls);
criteriaQuery.select(trunk);
Predicate [] restrictions = new Predicate[]{ criteriaBuiler.equal(car.get(carModel), "Civic"), criteriaBuilder.equal(soccerball.get("numberOfKicks"),20), criteriaBuilder.equal(soccerball.get(SoccerBall_.id),car.get(Car_.id))};
criteriaQuery.where(restrictions);
TypedQuery<Car> typedQuery = entityManager.createQuery(criteriaQuery);
Car carWithSoccerBalls = typedQuery.getSingleResult();
链接地址: http://www.djcxy.com/p/37082.html