2016-07-03 17 views
5

Próbuję przekonwertować ten surowy zapytanie SQL:Wiosna Dane Dołącz do specyfikacji

select product.* from following_relationship 
join product on following_relationship.following=product.owner_id 
where following_relationship.owner=input 

Do specyfikacji Wiosna danych, myślę, że mój problem jakim jest łączenie tych tabel.

Oto mój obecny przeliczeniowy Specyfikacja:

protected Specification<Product> test(final User user){ 
    return new Specification<Product>() { 
     @Override 
     public Predicate toPredicate(Root<Product> root, CriteriaQuery<?> query, CriteriaBuilder cb) { 
      Join<FollowingRelationship,Product> pfJoin = query.from(FollowingRelationship.class).join("following"); 
      pfJoin.on(cb.equal(pfJoin.get("following"),"owner")); 
      return query.where(cb.equal(pfJoin.get("following"),user)).getGroupRestriction(); 

     } 
    }; 
} 

A ja otrzymuję ten wyjątek:

Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessA 
piUsageException: org.hibernate.hql.internal.ast.InvalidWithClauseException: with clause can only reference columns in the driving table 

będą Chciałbym dodać, że jestem nowy na Spring Framework na przykład tego to moja pierwsza aplikacja na wiosnę, więc przepraszam za pytanie dla nowicjusza;)

Edytuj: dodane podmioty Produkt, obserwacjaRozmowy Statek

Product and FollowingRelationShip entity nie mają żadnych wyraźnych relacji, stąd dołączenie do mojej implementacji about.Co chcę osiągnąć to dostać wszystkie produkty od wszystkich użytkowników, które inny użytkownik śledzi w Specyfikacjach danych Spring.

+0

powinien "pfJoin.on (cb.equal (pfJoin.get (" po ")," owner "));' be 'pfJoin.on (cb.equal (pfJoin.get (" follow ")," owner_id " "));'? – Galz

+1

Jest to przypadek, w którym przeszkadza pakiet trzeciej strony.. –

+0

@ Galz yes, owner_id to nazwa połączonej kolumny, która zawiera odniesienie do pola uuid właściciela (które jest również identyfikatorem encji). Przy okazji wypróbowałem już zarówno właściciela właściciela, jak i właściciela, ale bez pracy – murielK

Odpowiedz

9

EDYCJA: Ok, zrobiłem tutaj niezły bałagan, ale mam nadzieję, że tym razem jestem bliższy właściwej odpowiedzi.

rozważenia (id są generowane automatycznie jak 1 do Jana etc.):

INSERT INTO some_user (name) VALUES ('John'); 
INSERT INTO some_user (name) VALUES ('Ariel'); 
INSERT INTO some_user (name) VALUES ('Brian'); 
INSERT INTO some_user (name) VALUES ('Kelly'); 
INSERT INTO some_user (name) VALUES ('Tom'); 
INSERT INTO some_user (name) VALUES ('Sonya'); 

INSERT INTO product (owner_id,name) VALUES (1,'Nokia 3310'); 
INSERT INTO product (owner_id,name) VALUES (2,'Sony Xperia Aqua'); 
INSERT INTO product (owner_id,name) VALUES (3,'IPhone 4S'); 
INSERT INTO product (owner_id,name) VALUES (1,'Xiaomi MI5'); 
INSERT INTO product (owner_id,name) VALUES (3,'Samsung Galaxy S7'); 
INSERT INTO product (owner_id,name) VALUES (3,'Sony Xperia Z3'); 

INSERT INTO following_relationship (follower_id, owner_id) VALUES (4,1); 
INSERT INTO following_relationship (follower_id, owner_id) VALUES (5,1); 
INSERT INTO following_relationship (follower_id, owner_id) VALUES (4,2); 
INSERT INTO following_relationship (follower_id, owner_id) VALUES (6,2); 
INSERT INTO following_relationship (follower_id, owner_id) VALUES (6,3); 
INSERT INTO following_relationship (follower_id, owner_id) VALUES (1,3); 

oparciu o uproszczoną wersją podmiotów, które Państwo zapewnione, a SomeUser jednostki jak:

@Entity 
public class FollowingRelationship { 

@Id 
@GeneratedValue(strategy=GenerationType.IDENTITY) 
private Long id; 

@ManyToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER) 
@JoinColumn(name = "owner_id") 
SomeUser owner; 

@ManyToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER) 
@JoinColumn(name = "follower_id") 
SomeUser follower; 

... 

@Entity 
public class Product { 

@Id 
@GeneratedValue(strategy=GenerationType.IDENTITY) 
private Long id; 

@ManyToOne() 
@JoinColumn(name = "owner_id") 
private SomeUser owner; 

@Column 
private String name; 

... 

@Entity 
public class SomeUser { 

@Id 
@GeneratedValue(strategy=GenerationType.IDENTITY) 
private Long id; 

@Column 
private String name; 

@OneToMany(mappedBy = "owner") 
private Set<Product> products = new HashSet<Product>(); 

@OneToMany(mappedBy = "owner") 
private Set<FollowingRelationship> ownedRelationships = new HashSet<FollowingRelationship>(); 

@OneToMany(mappedBy = "follower") 
private Set<FollowingRelationship> followedRelationships = new HashSet<FollowingRelationship>(); 

mam utworzona specyfikacja taka jak:

public static Specification<Product> joinTest(SomeUser input) { 
    return new Specification<Product>() { 
     public Predicate toPredicate(Root<Product> root, CriteriaQuery<?> query, CriteriaBuilder cb) { 
      Join<Product,SomeUser> userProd = root.join("owner"); 
      Join<FollowingRelationship,Product> prodRelation = userProd.join("ownedRelationships"); 
      return cb.equal(prodRelation.get("follower"), input); 
     } 
    }; 
} 

A teraz, gdy wykonujemy zapytanie takie jak:

SomeUser someUser = someUserRepository.findOne(Specifications.where(ProductSpecifications.userHasName("Kelly"))); 
List<Product> thatProducts = productRepository.findAll(Specifications.where(ProductSpecifications.joinTest(someUser))); 
System.out.println(thatProducts.toString()); 

Dostajemy:

[Product [id=1, name=Nokia 3310], Product [id=4, name=Xiaomi MI5], Product [id=2, name=Sony Xperia Aqua]] 

I to moim zdaniem jest odpowiednikiem: „dostać wszystkie produkty z wszystkich użytkowników, które następują inny użytkownik” - uzyskać produkty o wszystkich użytkownikach, że Kelly jest następujące.

+0

Dziękuję, zrobię to, jak tylko wrócę do domu. Proszę – murielK

+0

Produkt i następująca relacja nie mają żadnego związku. Jedyne, co mają wspólnego, to użytkownik, w którym każdy produkt ma swojego właściciela (użytkownika), gdzie FollowRelationship ma następujące pole i pole obserwatora (które są typem użytkownika lub jednostką). Próbuję więc uzyskać wszystkie produkty wszystkich użytkowników, których obserwuje jakiś inny użytkownik. – murielK

+0

To dlatego muszę dołączyć do encji Product w organizacji FollowRelationship Entity, gdzie FollowRelingship.following = product.owner – murielK