2016-06-27 9 views
0

フィルタリングを実行しようとしていますが、ManyToOneによるフィルタリングに問題があり、結果セットを取得するたびに、リンクされているプロジェクトに関係なくすべてのTaskオブジェクトが取得されます。私は次のエンティティがあります。それによって、プロジェクトにリンクされているJPA仕様CriteriaBuilder for @ManyToOne

@Entity 
public class Project implements Serializable { 

@Id 
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "project_seq_gen") 
@SequenceGenerator(name = "project_seq_gen", sequenceName = "project_id_seq", allocationSize = 1) 
private Long id; 

@Column(unique = true) 
private String projectId; 

//more things 
} 

とタスククラスは、それは私が検索するjparepository持ってこの

|id  |project_tasks | 
|--------|--------------| 
| TASK1 |   1 | 
| TASK2 |   2 | 
|--------|--------------| 

のように見えるタスクのID

テーブルで
@Entity 
public class Task implements Serializable { 

@Id 
private String id; 

@Column 
private String name; 

@ManyToOne(fetch = FetchType.EAGER) 
@JoinColumn(name = "project_tasks") 
private Project project; 

@Column 
private Enum<TaskType> type; 

//more things.... 
} 

ですタスク:

@Repository 
public interface TaskRepository extends JpaRepository<Task, Integer> , JpaSpecificationExecutor { 

そしてorg.hibernate.jpamodelgen.JPAMetaModelEntityProcessor

public class TaskSpecification implements Specification<Task> { 
    private final TaskFilter taskFilter; 

    public TaskSpecification(TaskFilter task) { 
     this.taskFilter = task; 
    } 

    @Override 
    public Predicate toPredicate(Root<Task> task, CriteriaQuery<?> cq, CriteriaBuilder cb) { 
     Predicate predicate = cb.conjunction(); 
     //project 
     //approach 1 
     cb.and(predicate, task.join(Task_.project).get(Project_.id).in(taskFilter.getProject().getId())); 
     //approach 2 
     cb.and(predicate, cb.equal(task.get(Task_.project).get(Project_.id), taskFilter.getProject().getId())); 
     //some other filters to follow 
     if (StringUtils.isNotBlank(taskFilter.getByState())) { 
      if (TaskFilter.OPEN.equals(taskFilter.getByState())) { 
       predicate = cb.and(predicate, task.get(Task_.state).in(TaskState.TO_DO, TaskState.ONGOING, TaskState.COMPLETE, TaskState.BLOCKED)); 
      } else { 
       predicate = cb.and(predicate, task.get(Task_.state).in(TaskState.valueOf(taskFilter.getByState()))); 
      } 
     } 
     return predicate; 
    } 
} 

サービスコールによって生成されたメタモデル使用しています仕様:

public List<Task> findBySpecification(TaskFilter filter) { 
    return taskRepo.findAll(new TaskSpecification(filter)); 
} 

両方のアプローチ1とアプローチ2と残念ながらすべてのクエリを、関係なく、どのようなプロジェクト、すべてのタスクを返します。イドです 私はまた、hibernate.show_sqlを有効にし、次は助けのための完全な非常に素晴らしいことだコンソール

アプローチ1

Hibernate: select task0_.id as id1_12_, task0_.active as active2_12_, task0_.task_assignee as task_as21_12_, task0_.create_date as create_d3_12_, task0_.description as descript4_12_, task0_.due_date as due_date5_12_, task0_.estimate as estimate6_12_, task0_.estimated as estimate7_12_, task0_.finishDate as finishDa8_12_, task0_.inSprint as inSprint9_12_, task0_.lastUpdate as lastUpd10_12_, task0_.loggedWork as loggedW11_12_, task0_.name as name12_12_, task0_.task_owner as task_ow22_12_, task0_.parent as parent13_12_, task0_.priority as priorit14_12_, task0_.project_tasks as project23_12_, task0_.release_id as release24_12_, task0_.remaining as remaini15_12_, task0_.state as state16_12_, task0_.story_points as story_p17_12_, task0_.subtasks as subtask18_12_, task0_.task_order as task_or19_12_, task0_.type as type20_12_ from Task task0_ inner join Project project1_ on task0_.project_tasks=project1_.id where 1=1 and (task0_.state in (? , ? , ? , ?)) 

アプローチ2

Hibernate: select task0_.id as id1_12_, task0_.active as active2_12_, task0_.task_assignee as task_as21_12_, task0_.create_date as create_d3_12_, task0_.description as descript4_12_, task0_.due_date as due_date5_12_, task0_.estimate as estimate6_12_, task0_.estimated as estimate7_12_, task0_.finishDate as finishDa8_12_, task0_.inSprint as inSprint9_12_, task0_.lastUpdate as lastUpd10_12_, task0_.loggedWork as loggedW11_12_, task0_.name as name12_12_, task0_.task_owner as task_ow22_12_, task0_.parent as parent13_12_, task0_.priority as priorit14_12_, task0_.project_tasks as project23_12_, task0_.release_id as release24_12_, task0_.remaining as remaini15_12_, task0_.state as state16_12_, task0_.story_points as story_p17_12_, task0_.subtasks as subtask18_12_, task0_.task_order as task_or19_12_, task0_.type as type20_12_ from Task task0_ where 1=1 and (task0_.state in (? , ? , ? , ?)) 

に示されました。 よろしくお願いします。

答えて

1

cb.and()関数を適切に使用することはできません。この関数は現在のものを変更するのではなく、新しい結合された述語を返します。
ので、代わりの
cb.and(predicate, task.join(Task_.project).get(Project_.id).in(taskFilter.getProject().getId()));
あなたは
predicate = cb.and(predicate, task.join(Task_.project).get(Project_.id).in(taskFilter.getProject().getId()));

+0

なんてこった、愚かな私を持っている必要があります。あなたは正しいです。私は述語= cb.and(....)を忘れました 私はそれを後で他のフィルタで正しい方法で使用していました。大いに感謝する :) – Khobar