2

ABの2つのエンティティがあります。それらの間には多対多の関係があり、AのリストはBです。 具体的な名前のBが含まれているすべてのAのエントリを取得するための仕様の作成方法?例:セットのスプリングデータ仕様には、操作が含まれています

@Service 
public class YourService { 

    @Resource 
    private ARepository repository; 

    // I know how to do this type of queries with specifications 
    public List<A> getByB(B b) { 
     return repository.findAll(Specifications.containsB(b)); 
    } 

    //Question: how to write Specification for this type of query? 
    public List<A> getByNameOfB(String name) { 
     return repository.findAll(Specifications.containsBWithName(name)); 
    } 
} 

エンティティ:

@Entity 
public class B { 

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

     @Column(unique = true, updatable = false) 
     private String name; 
} 

@Entity 
public class A { 

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

    @ManyToMany(fetch = FetchType.EAGER) 
    @JoinTable(name = "A_B", 
      joinColumns = {@JoinColumn(name = "A_ID", nullable = false, updatable = false)}, 
      inverseJoinColumns = {@JoinColumn(name = "B_ID", nullable = false, updatable = false)}) 
    @Fetch(value = FetchMode.SUBSELECT) 
    private List<B> bList; 
} 

メタモデル:

@Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor") 
@StaticMetamodel(A.class) 
public class A_ { 
    public static volatile ListAttribute<A, B> bList; 
} 


@Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor") 
@StaticMetamodel(B.class) 
public class B_ { 
    public static volatile SingularAttribute<B, String> name; 
} 

検索:

public interface ARepository extends JpaRepository<A, Long>, JpaSpecificationExecutor<A> { 
} 

public class Specifications { 

    public static Specification<A> containsB(B b) { 
     return (root, query, cb) -> { 
      Expression<List<B>> bList = root.get(A_.bList); 
      return cb.isMember(b, bList); 
     }; 
    } 

    // HERE IS A QUESTION: 

    public static Specification<A> containsBWithName(String name) { 
     return (root, query, cb) -> { 
      ListJoin<List<B>> bList = root.join(A_.bList); 
      Expression<String> exp = bList.get(B_.name) 
      //TODO how to check that name is one of the retrieved names? 
      //PROBLEM, method below expects Expression<List<String>> instead of Expression<String> 
      cb.isMember(name, exp); 
     }; 
    } 
} 

答えて

3

は次に何をするようにしてください:

public static Specification<A> containsBWithName(String name) { 
    return (root, query, cb) -> { 
     root.join("bList", JoinType.INNER); 
     return cb.equal(root.get("bList").get("name"), name); 
    }; 
} 

希望はトリックです。

1.11.4

0

春データバージョンそれは私に受け入れ答えは私のために動作しなかった理由を把握するのに時間がかかりました。 私はそれをこのようにしなければならなかった:

public static Specification<A> containsBWithName(String name) { 
    return (root, query, cb) -> { 
     Join<Object, Object> bListJoin = root.join("bList", JoinType.INNER); 
     return cb.equal(bListJoin.get("name"), name); 
    }; 
} 

春データ1.11.9

関連する問題