当前位置: 首页 > 知识库问答 >
问题:

@ManyToOne的JPA规范标准生成器

傅涵忍
2023-03-14

我正在尝试执行一些过滤,但ManyToOne的过滤有一些问题,每次我得到结果集时,我都会得到所有Task对象,而不管它们所链接的项目如何。我有以下实体:

@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
}

和任务类,它通过它的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....
}

在任务表中,它看起来像这样

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

我有jparepository来搜索任务:

@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的每个查询都返回所有任务,无论项目Id是什么。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个答案

姬振濂
2023-03-14

您可能无法正确使用cb.and()函数。这个函数将返回一个新的组合谓词,而不是改变当前的谓词。< br >所以不用< br> cb.and(谓词,task.join(Task_。项目)。get(Project_。id)。在(taskFilter.getProject()中。getId()));
应该有< br> 谓词= cb.and(谓词,task.join(Task_。项目)。get(Project_。id)。在(taskFilter.getProject()中。getId()));

 类似资料:
  • PSR 是 PHP Standard Recommendations 的简写,由 PHP FIG 组织制定的 PHP 规范,是 PHP 开发的实践标准。

  • 我有一个父表,它与一个子表有许多关联。 我试图用CriteriaBuilder编写一个查询,以限制从子表返回的结果。 我添加了一个谓词,类似于 如果父节点有一个子节点或子节点和子节点,则返回父节点,同时也返回所有子节点。 Hibernate使用我的谓词启动了第一个查询,但是第二个获取孩子的查询只使用了where子句中的JoinColumn,而没有包含它 思想? 我正在使用SetJoin 澄清:

  • There are only two hard problems in computer science: cache invalidation, naming things, and off-by-one errors. — Phil Karlton 当你维护代码时会发现,选择适当而有意义的信息为你的模块或类命名是有很大帮助的。 尤其是当其他人需要阅读或基于你编写的配置清单工作时,这种命名方法是

  • 对于来说,肯定有某种方法可以产生这个输出,不是吗?我发现有一些将映射到,所以似乎有一种方法可以让它产生类型,但我没有找到

  • 为什么它更高效,因为像'your_name'这样的c.name扫描只在第一个查询中发生一次。

  • > 我使用的是Project Lombok,这是一个(虚假的)JSR269实现,提供了一些有用的特性,比如在编译时生成getter和setter,同时保持源代码的清洁: 有没有一种方法可以按照需要的方式管道两个注释处理器?