Java 多态子类属性jpa hibernate查询的解析条件

Java 多态子类属性jpa hibernate查询的解析条件,java,hibernate,jpa,criteria-api,Java,Hibernate,Jpa,Criteria Api,将Hibernate3.6.10与HibernateJPA2.0结合使用 我的问题归结为在一个有点复杂的连接查询期间需要在子对象的列上设置一些条件 我有一组类似的对象: @Entity @Inheritance(strategy = InheritanceType.JOINED) public class Ball { private String name; //...getter and setter crud... } @Entity public class B

将Hibernate3.6.10与HibernateJPA2.0结合使用

我的问题归结为在一个有点复杂的连接查询期间需要在子对象的列上设置一些条件

我有一组类似的对象:

@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...
}
@实体
@继承(策略=InheritanceType.JOINED)
公共班级舞会
{
私有字符串名称;
//…接二连三的积垢。。。
}
@实体
公共级沙滩球延伸球
{
私人海滩;
//…接二连三的积垢。。。
}
@实体
公开课足球扩展球
{
私人int-numberOfKicks;
//…接二连三的积垢。。。
}
@实体
公共级干线
{
私人定位球;
@OneToMany(mappedBy=“trunk”,cascade=CascadeType.ALL,orphan=true)
公共集getBalls()
{
回球;
}
}
@实体
公车
{
私人干线;
私人字符串卡莫德尔;
//…接二连三的积垢。。。
}
现在我需要查询一辆特定型号的汽车中有多少个足球有20个脚踢

使用JPA,我试着做如下事情:

    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();
CriteriaBuilder-CriteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaQuery-CriteriaQuery=criteriaBuilder.createQuery(Car.class);
根car=criteriaQuery.from(car.class);
Join trunkJoin=car.Join(car\uu.trunk);
Join-ballJoin=trunkJoin.Join(中继球);
criteriaQuery.select(trunk);
谓词[]限制=新谓词[]{criteriaBuiler.equal(car.get(carModel),“Civic”),criteriaBuilder.equal(ballJoin.get(“numberOfKicks”),20)};
criteriaQuery.where(限制);
TypedQuery TypedQuery=entityManager.createQuery(criteriaQuery);
Car carWithSoccerBalls=typedQuery.getSingleResult();
在运行时,上面的代码会消失,因为numberOfKicks仅在足球上,并且由于它在主干中的键入方式,它只知道足球。如果我在足球上手动创建一个from,并设置加入它的条件,我可以查询numberOfKicks,但是我觉得必须有一种方法来通知查询集合实际上是一个集合

请注意,我不能发布任何实际的代码,所以上面所有的例子都只是例子


像上面那样使用JPA和hibernate,有没有办法强迫hibernate知道集合实际上是集合

由于时间限制,我选择了简单的方法:(。如果有人能回答得更好,那么我很乐意选择他们的答案而不是我的答案

为了使criteria api能够识别我正在查找的继承表,我将查询代码更改为:

   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();
CriteriaBuilder-CriteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaQuery-CriteriaQuery=criteriaBuilder.createQuery(Car.class);
根car=criteriaQuery.from(car.class);
根soccerballs=criteriaQuery.from(SoccerBall.class);
Join trunkJoin=car.Join(car\uu.trunk);
Join-ballJoin=trunkJoin.Join(中继球);
criteriaQuery.select(trunk);
谓词[]限制=新谓词[]{criteriaBuiler.equal(car.get(carModel),“Civic”),criteriaBuilder.equal(soccerball.get(“numberOfKicks”),20),criteriaBuilder.equal(soccerball.get(soccerball.id),car.get(car.id));
criteriaQuery.where(限制);
TypedQuery TypedQuery=entityManager.createQuery(criteriaQuery);
Car carWithSoccerBalls=typedQuery.getSingleResult();

以下内容检索具有嵌套列表属性的所有车辆,这些属性满足集合中子类类型的相等条件和根元素上的相等条件。 我已经修改了查询以使用原始问题中的数据模型

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Car> carQuery = criteriaBuilder.createQuery(Car.class);
Root<Car> carRoot = carQuery.from(Car.class);

Subquery<SoccerBall> ballQuery = carQuery.subquery(SoccerBall.class);
Root<SoccerBall> soccerBall = ballQuery.from(SoccerBall.class);

ballQuery.select(soccerBall);
ballQuery.where(criteriaBuilder.equal(soccerBall.get(SoccerBall_.numberOfKicks), 25));

Join<Car, Trunk> carTrunkJoin = carRoot.join(Car_.trunk);
SetJoin<Trunk, Ball> trunkBallJoin = carTrunkJoin.join(Trunk_.balls);

carQuery.select(carRoot);
carQuery.where(criteriaBuilder.and(
    trunkBallJoin.in(ballQuery),
    criteriaBuilder.equal(carRoot.get(Car_.carModel), "Civic")));


TypedQuery<?> typedQuery = entityManager.createQuery(carQuery);
List<?> result = typedQuery.getResultList();
CriteriaBuilder-CriteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaQuery carQuery=criteriaBuilder.createQuery(Car.class);
根carRoot=carQuery.from(Car.class);
Subquery ballQuery=carQuery.Subquery(SoccerBall.class);
根soccerBall=ballQuery.from(soccerBall.class);
ballQuery.select(足球);
where(criteriaBuilder.equal(soccerBall.get(soccerBall_uu.numberOfKicks),25));
Join carTrunkJoin=carRoot.Join(汽车后备箱);
SetJoin-trunkBallJoin=carTrunkJoin.join(Trunk.balls);
carQuery.select(carRoot);
carQuery.where(criteriaBuilder.and(
trunkBallJoin.in(ballQuery),
标准生成器.equal(carRoot.get(Car_.carModel),“Civic”);
TypedQuery TypedQuery=entityManager.createQuery(carQuery);
List result=typedQuery.getResultList();
等效的SQL是:

SELECT*FROM car JOIN trunk JOIN ball WHERE ball.id IN(SELECT soccerball.id FROM soccerball WHERE soccerball.numberOfKicks=25)