2014-09-02 23 views
5

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!

cevap

2

Son olarak, sorunumu çözdü için bir yol buldu. Yalnızca alt kuruluşların kısmi koleksiyonlarını talep etmek, veri bütünlüğü açısından tehlikeli bulduğumuz bir şeydir.Bir uzaktan servis, ebeveyn varlığımın bir kısmi çocuk varlıkları topluluğuna sahip olmasını talep ederse, bu ana varlık nesnesi, değiştirilen bir işlemin geri dönüşü olabilir; bu durum, çocukların varlıkları kaldırılmış örneklerinde birçok "silme" çağrısına neden olur. Kalıcılık API'si bu eksik çocukları, kaldırılmayan ilişkiler olarak görecek, ki bu da istemediğimiz bir şey.

İstenmeyen bir değişiklik aktarma nesnesini, bu küme aktarım nesnesinin gelecekte yapılacak bir değişiklik çağrısı çağrısı sırasında kullanılamaması için talep edilen çocuk varlıklarının kısmi koleksiyonlarını içeren oluşturdum. Ana varlığın tam sürümü "değişiklik" amacı için kullanılacaktır.

2

JPA sağlayıcınız hazırda bekletiliyor musunuz? Filtreleri, onları kaldırmak yerine alt öğelerini filtreleyebilecek şekilde hazırda bekletmiş saydınız.Ama filtre kullanımı bir şekilde anlaşılması çok zor!

İlgili konular