2014-12-01 40 views
2

我的查询看起来是这样的:数据春“左连接抓取”查询返回null

@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查询,我会很高兴。提前致谢。

+1

什么是你的表格结构 – HaveNoDisplayName 2014-12-01 22:21:17

+0

playerShips表包含布尔型的'active'列和引用Pilot.ID的外键列'pilot_id',这是重要的东西。 – Sikor 2014-12-01 22:24:17

+0

选择性地检索〜ToMany关系的一部分并不是一个好主意。你将面临很多问题。代之以代码进行过滤。除非你想完全忽略整个应用程序中的所有不活动的船舶(这是你的答案正在做什么)。 – 2014-12-09 01:32:24

回答

1

定义了大量的研究后,我决定实现一个自定义存储库,以便我可以使用休眠筛选器,现在它工作。

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; 

PlayerShip实体:

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

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

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

试过了。抛出以下错误:在提取的关联上不允许使用-clause;使用过滤器。我现在在寻找过滤器,但我认为不可能将它们用于Spring Data JPA。 – Sikor 2014-12-08 21:05:08

+1

试试这个或本地查询:'选择P档试点p LEFT JOIN FETCH p.playerShips S其中p.nickname =(:昵称)和(S为空或s.active = FALSE)' – itpr 2014-12-08 21:18:38

+1

试过一个了。试点仍然是空的。 – Sikor 2014-12-08 21:20:03