2014-02-24 115 views
0

我知道它已经在这里提到的前几次,但我真的不能让它为我工作,JPQL加入对一对多数据库

我有两个实体:配方,配料:

@Entity 
@Table(name = "Recipe") 
public class Recipe { 

    @Id 
    @GeneratedValue 
    @Column(name = "Recipe_id") 
    private Long id; 

    private String name; 

    private String description; 
    @Lob 
    @Basic(fetch = FetchType.LAZY) 
    @Column(length = 100000) 
    private byte[] image; 

    @OneToMany(mappedBy = "recipe", fetch = FetchType.EAGER) 
    @Cascade({CascadeType.ALL}) 
    private List<Ingredient> ingredientsList; 
.... 
} 

和配料:

@Entity 
@Table 
public class Ingredient { 

    @Id 
    @GeneratedValue 
    private Long id; 

    private String name; 

    private int cpt; 

    private String cptyType; 

    @ManyToOne 
    @JoinColumn(name = "Recipe_id") 
    private Recipe recipe; 

.... 
} 

我还建立了JPA Reposiotries,我想创建这将等同于自定义查询:

SELECT * 
FROM `Recipe` 
INNER JOIN `Ingredient` ON Recipe.Recipe_id = Ingredient.Recipe_id 
WHERE Ingredient.name = "fancyName" 
LIMIT 0 , 30 

到现在为止我已经试过这一个:

@Query("Select r from Recipe r join r.id i where i.name = :ingredient") 
List<Recipe> findRecipeByIngredient(@Param("ingredient") String ingredient); 

结束了expcetion:

Caused by: java.lang.NullPointerException 
     at org.hibernate.hql.internal.ast.HqlSqlWalker.createFromJoinElement(HqlSqlWalker.java:395) 
     at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.joinElement(HqlSqlBaseWalker.java:3477) 
     at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3263) 
     at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3141) 
     at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:694) 
     at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:550) 
     at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:287) 
     at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:235) 
     at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:248) 
     at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:183) 
     at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136) 
     at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:101) 
     at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:80) 
     at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:119) 
     at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:214) 
     at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:192) 

我已经尝试过的东西像这样:

@Query("Select r from Recipe r join fetch r.ingredientsList where r.name = :ingredient") 
    List<Recipe> findRecipeByIngredient(@Param("ingredient") String ingredient); 

这不会导致任何错误,但会返回空结果。

这是一个繁琐的问题,但我没有与任何JPQL经验之前=/

编辑:

仍然得到空的结果:

DEBUG (SqlStatementLogger.java:104) - select recipe0_.Recipe_id as Recipe1_1_0_, ingredient1_.id as id0_1_, recipe0_.description as descript2_1_0_, recipe0_.image as image1_0_, recipe0_.name as name1_0_, ingredient1_.cpt as cpt0_1_, ingredient1_.cptyType as cptyType0_1_, ingredient1_.name as name0_1_, ingredient1_.Recipe_id as Recipe5_0_1_, ingredient1_.Recipe_id as Recipe5_1_0__, ingredient1_.id as id0__ from Recipe recipe0_ inner join Ingredient ingredient1_ on recipe0_.Recipe_id=ingredient1_.Recipe_id where ingredient1_.name=? 
DEBUG (CollectionLoadContext.java:224) - No collections were found in result set for role: com.bla.model.Recipe.ingredientsList 

编辑2:

删除从语句提取后:

DEBUG (SqlStatementLogger.java:104) - select recipe0_.Recipe_id as Recipe1_1_, recipe0_.description as descript2_1_, recipe0_.image as image1_, recipe0_.name as name1_ from Recipe recipe0_ inner join Ingredient ingredient1_ on recipe0_.Recipe_id=ingredient1_.Recipe_id where ingredient1_.name=? 
DEBUG (StatefulPersistenceContext.java:899) - Initializing non-lazy collections 

回答

2

您的最后一个查询将搜索名称是作为参数传递的配料名称的所有配方。这不是你想要的。

select r from Recipe r 
join r.ingredientList i 
where i.name = :ingredient 

边注:我为什么不能在使用相同的成分两个配方你要什么有一种成分,其名称是成份名称作为参数传递的所有配方是什么?相当有限。该协会应该是一个ManyToMany。

+0

好吧,我真的找不到我没有做到这一点的原因!感谢这个简单但非常有用的提示。查询将在今天被检查=)。非常快速的答案感谢。 – iie

+0

我已更新说明。我想我们几乎在那里=) – iie

+0

从查询中删除'fetch'。并粘贴你正在使用的新JPQL查询 –