ben id yılların listesine dayanarak çocuk varlığın bir koleksiyon filtrelemek için gereken hangi bir varlık hizmeti var. Hizmetim, ana öğenin kimliğini ve bazı çocuk varlıklarının kimlik listesini içeren bir genel yönteme sahiptir.Çocuk varlıkları koleksiyonları yüklemeli olarak nasıl filtrelenir?
Varsayılan olarak, ben JPA ilgili tüm varlıkları ve bu onun gerçek davranışı alıp bunu biliyoruz. Ama hizmetin performansı üzerinde çalışmamız gerek. Bu nedenle, tüm ilişkili varlıkları almak ve onları çok sayıda döngü ile filtrelemek (kimlikleri üzerinde filtre ve tarih özelliği gibi diğer özelliklerde) yerine, yalnızca isteğimle ilgilenen varlıkları almak istiyorum.
Benim Üst varlık
@Entity
@Table(name = "MyParent")
public class MyParentEntity {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,
generator = "SEQ_MyParent")
@SequenceGenerator(allocationSize = 1, name = "SEQ_MyParent",
sequenceName = "SEQ_MyParent")
@Column(name = "ID_PARENT")
private Long id;
@OneToMany(mappedBy = "myParent", cascade = CascadeType.ALL,
fetch = FetchType.EAGER, orphanRemoval = true)
private final List<MyChildEntity> myChild = new ArrayList<MyChildEntity>();
}
My Child Varlık
@Entity
@Table(name = "MyChild")
public class MyChildEntity {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,
generator = "SEQ_MyChild")
@SequenceGenerator(allocationSize = 1, name = "SEQ_MyChild",
sequenceName = "SEQ_MyChild")
@Column(name = "ID_CHILD")
private Long id;
@ManyToOne
@JoinColumn(name = "ID_PARENT")
private MyParentEntity myParent;
}
benim DB'den veri almak için Bahar-veri CrudRepository kullanıyorum ve ayrıca JpaSpecificationExecutor doğrulaması kullanabilir kadar uzanır.
public interface MyParentRepository extends CrudRepository<MyParentEntity, Long>,
JpaSpecificationExecutor<MyParentEntity> {
}
Bu bana CrudRepository findOne() yöntemini ancak bunun yerine düzenli Uzun parametrenin bir Şartname nesne ile kullanalım.
Ayrıca, aşağıdaki çağrıyla katları Edilen Özellik en nesneyi birleştirmek:
this.myParentRepository.findOne(Specifications
.where(firstSpecification(parentId))
.and(secondSpecification(childrenIdsList)));
İki çocuk varlıkları ile bağlantılı bir Ana ile basit junit testi yarattı. İsteğemde, ebeveyn kimliğini sağlanan kimlikle alabiliyorum. Ancak, çocuk kimliğini sağlasa bile, her zaman her iki çocuğu da ebeveynler içindeki listede bulunan varlıkları alırım. toPredicate yöntemi geçersiz kılma olduğu bir yeni Şartname nesnesi, dönmek benim yöntemde
, benim çocuk koleksiyonunda filtre ve sadece ben ilgileniyorum olanlar birini alacak bir doğrulama'yı oluşturamıyorum. Hazırda Kriterleri "Sınırlamalar" ekleme olasılığı vardır ama bu toPredicate yöntemi ile sağlanır CriteriaBuilder mevcut olmadığını biliyoruz. secondSpecification() yönteminde
public static Specification<MyParentEntite> firstSpecification(final Long id) {
return new Specification<MyParentEntite>() {
@Override
public Predicate toPredicate(Root<MyParentEntite> root,
CriteriaQuery<?> query, CriteriaBuilder cb) {
Predicate predicate = cb.equal(root.get(MyParentEntity_.id), id);
return cb.and(predicate);
}
};
}
public static Specification<MyParentEntite> secondSpecification(final List<Long> ids) {
return new Specification<MyParentEntite>() {
@Override
public Predicate toPredicate(Root<MyParentEntite> root,
CriteriaQuery<?> query, CriteriaBuilder cb) {
Root<MyChildEntity> child = query.from(MyChildEntity.class);
Expression<Long> exp = child.get(MyChildEntity_.id);
Predicate p = exp.in(ids);
return cb.and(p);
}
};
}
, ayrıca biriminin doğrudan ListJoin yerine kökü kullanmayı denemişlerdir. Burada diğer sorular arandı ancak bu endişe hazırda Kriterleri kısıtlamalarla yoksa JoinType.LEFT parametresini specifing benim ListJoin denedik bir LeftJoin ile çözülmüş gibi görünüyor. Ben Kriterler API ve Yüklem ile nispeten yeni olduğumu belirtmek istiyorum
JPA CriteriaBuilder - How to use "IN" comparison operator
JPA2 Criteria-API: select... in (select from where)
:
İşte bağlantıları zaten whitout başarı çözümleri test için vardır. Belki basit bir şey eksik ama bu deneyimli JPA geliştiriciler için açıktır!
Yardımlarınız için teşekkürler çok!