Spring JPA 规范一对多联接 3 个表

Spring JPA Specification One to Many Join 3 tables

我有 3 个具有以下关系的实体。

@Table(name = "a")
@Entity
public class A{
   @Id 
   @GeneratedValue
   @Column(name = "a_uuid")
   @OneToMany(mappedBy = "a", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
   private List<B> bList;

   @OneToMany(mappedBy = "a", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
   private List<C> cList;

}

@Table(name = "b")
@Entity
public class B{
   @ManyToOne(fetch = FetchType.LAZY)
   @JoinColumn(fetch = "a_uuid")
   private A a;
}

@Table(name = "c")
@Entity
class C{
   @ManyToOne(fetch = FetchType.LAZY)
   @JoinColumn(fetch = "a_uuid")
   private A a;
}

我需要加入以上三个 table 并且我正在为每个 table

使用单独的规范
@Component
public class SpecificationTableAUtil {
    public Specification<A> tableACriteriaMatches(final SomeCriteria criteria) {
return (root, query, criteriaBuilder) -> {
            List<Predicate> predicateList = new ArrayList<>();
            predicateList .add(
                    criteriaBuilder.isNull(
                            root.get("some_column_in_table_a")));
            Predicate[] predicates = new Predicate[predicateList.size()];
            return criteriaBuilder.and(predicateList.toArray(predicates ));
        };
     }
   }
}

@Component
public class SpecificationTableBUtil {
    public Specification<A> tableBCriteriaMatches(final SomeCriteria criteria) {
return (root, query, criteriaBuilder) -> {
            ListJoin<A, B> b =
                root.joinList("bList", JoinType.LEFT);
            List<Predicate> predicateList = new ArrayList<>();
            predicateList .add(
                    criteriaBuilder.isNull(
                            b.get("some_column_in_table_b")));
            Predicate[] predicates = new Predicate[predicateList.size()];
            return criteriaBuilder.and(predicateList.toArray(predicates ));
        };
     }
   }
}

来自我的服务 Class,

@Service
public class ServiceClass{
    //Autowire the utilities
    public Specification<A> getSpecification(final SomeCriteria criteria) {
            return bUtil.tableBCriteriaMatches(criteria)
                   .and(aUtil.tableACriteriaMatches(criteria));
     }
   }
}

现在我也需要加入 Table C。如何以更好的方式实现这一点?我需要让每个方法的代码行尽可能少

我自己想出来的。这是我想出来的。

@Component
public class SpecificationTableAUtil {

    @Autowired 
    private SpecificationTableBUtil bSpecificationUtil;

    public Specification<A> tableACriteriaMatches(final SomeCriteria criteria) {
return (root, query, criteriaBuilder) -> {
            List<Predicate> predicateList = new ArrayList<>();
            predicateList .add(
                    criteriaBuilder.isNull(
                            root.get("some_column_in_table_a")));
            predicateList.add(bSpecificationUtil.criteriaMatches(criteria).toPredicate(root, query, criteriaBuilder));
            Predicate[] predicates = new Predicate[predicateList.size()];
            return criteriaBuilder.and(predicateList.toArray(predicates ));
        };
     }
   }
}

对于table B规格,

@Component
public class SpecificationTableBUtil {
    public Specification<A> tableBCriteriaMatches(final SomeCriteria criteria) {
return (root, query, criteriaBuilder) -> {
            ListJoin<A, B> b =
                root.joinList("bList", JoinType.LEFT);
            List<Predicate> predicateList = new ArrayList<>();
            predicateList .add(
                    criteriaBuilder.isNull(
                            b.get("some_column_in_table_b")));
            Predicate[] predicates = new Predicate[predicateList.size()];
            return criteriaBuilder.and(predicateList.toArray(predicates));
        };
     }
   }
}

来自服务 class、

@Service
public class ServiceClass {
   
    @Autowired
    private SpecificationTableAUtil aSpecificationUtil;
   
    public Specification<A> getSpecification(final SomeCriteria criteria) {
            return aSpecificationUtil.tableACriteriaMatches(criteria);
     }
   }
}