Spring Data'Left Join Fetch'查询返回null

时间:2014-12-01 22:15:13

标签: java sql spring spring-data spring-data-jpa

我的查询如下:

@Query("SELECT p FROM Pilot p LEFT JOIN FETCH p.playerShips WHERE p.nickname = (:nickname)")

到目前为止一切顺利。即使playerShips为空,我也会获得Pilot实例 现在,我想只获取不活动的船只,所以我修改了我的查询,如下所示:

@Query("SELECT p FROM Pilot p LEFT JOIN FETCH p.playerShips s WHERE p.nickname = (:nickname) AND s.active = false")

我作为飞行员得到了空,所以它显然不起作用。
如果有人能解释如何使用适用于子元素的WHERE子句创建JOIN FETCH查询,我会很高兴。提前谢谢。

2 个答案:

答案 0 :(得分:2)

将其移至连接条件:

@Query("SELECT p FROM Pilot p LEFT JOIN FETCH p.playerShips s ON s.active = false WHERE p.nickname = (:nickname)")

ON子句在JPA 2.1

中定义

答案 1 :(得分:2)

经过大量的研究,我决定实现一个自定义存储库,以便我可以使用Hibernate Filters,现在它可以工作。

<强> PilotRepository:

@Repository
public interface PilotRepository extends JpaRepository<Pilot, Long>, PilotRepositoryCustom{
/*spring data methods here*/
}

<强> PilotRepositoryCustom:

public interface PilotRepositoryCustom {
    public Pilot findByNicknameFetchInactiveShips(String nickname);
}

<强> PilotRepositoryImpl:

public class PilotRepositoryImpl implements PilotRepositoryCustom{

    @PersistenceContext
    EntityManager entityManager;

    @Override
    public Pilot findByNicknameFetchInactiveShips(String nickname) {
        Session session = entityManager.unwrap(Session.class);
        session.enableFilter("active").setParameter("active", false);
        Query query = entityManager.createQuery(
                "SELECT p FROM Pilot p " +
                "LEFT JOIN FETCH p.playerShips ps " +
                "LEFT JOIN FETCH ps.ship s " +
                "WHERE p.nickname = (:nickname)");
        query.setParameter("nickname", nickname);
        return (Pilot)query.getSingleResult();
    }
}

关于弹簧数据的说法。现在过滤器配置:

试点实体:

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "pilot")
    @Filter(name="active", condition = "active = :active")
    private List<PlayerShip> playerShips;

玩家船队实体:

@Entity
@Table(name="player_ship")
@FilterDef(name="active", parameters=@ParamDef(name="active",type="java.lang.Boolean"))
public class PlayerShip {
    /*...*/
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "pilot_id")
    private Pilot pilot;
    /*...*/
}

重要提示:
如果在@ParamDef中使用布尔值,请确保键入 java.lang.Boolean 而不是布尔值。我花了一个多小时想知道为什么我一直得到参数未找到/未定义错误