2017-08-29 2 views
1

Ici j'ai deux tables users et orders, users a deux champs first_name et last_name et orders a un champ full_name. Pour une raison quelconque, je ne peux pas changer le schéma de la base de données.Comment puis-je quitter deux tables non liées en utilisant les critères JPA?

Maintenant, j'ai une requête:

SELECT u.* FROM users u LEFT JOIN orders o ON o.full_name = CONCAT(u.first_name, ' ', u.last_name) 

et je dois convertir en spécifications JPA, car il fait partie d'autres spécifications. Voici mon essai:

Entité:

@Entity 
@Table(name = "users") 
class User { 
    @Id 
    private Integer id; 

    @Column(name = "first_name") 
    private String firstName; 

    @Column(name = "last_name") 
    private String lastName; 
} 

@Entity 
@Table(name = "orders") 
class Order { 
    @Id 
    private Integer orderId; 

    @Column(name = "full_name") 
    private String fullName; 
} 

Le problème est, que dois-je remplir la déclaration suivante pour le premier paramètre

(root, query, criteraBuilder) -> { 
    Join<User,Order> join = root.join(???,JoinType.LEFT); 
    join.on(blablabla_condition) 
} 

Est-ce faisable?

Merci

Répondre

1

Pour aller dans le sens que vous essayez de mettre en œuvre, vous devrez mapper l'association dans le User/Order comme une association paresseuse @OneToOne ou @OneToMany selon que il peut y avoir plusieurs commandes pour un utilisateur ou non. Pour cela, vous devrez mapper l'opération de jointure qui est la logique compliquée que vous avez mappée dans la requête native en haut. Je vous suggère de jeter un oeil dans le @JoinFormula et @JoinColumnOrFormula comme des moyens de mapper cette jointure.

+0

Merci. Je n'ai jamais su Joinformula, très intéressant. J'essaierai – haohaolee

+0

Si vous trouvez cette réponse utile, vous pouvez la mettre à l'ouvrage et/ou l'accepter – dimitrisli

+0

Je l'accepterai après l'avoir essayé;) – haohaolee

0

Première tentative ... Et si vous créez une méthode avec votre requête native?

@Query(value = "SELECT u.* FROM users u LEFT JOIN orders o ON o.full_name = CONCAT(u.first_name, ' ', u.last_name)", nativeQuery = true) 
List<User> getUserJoinedWithOrder(); 

MISE À JOUR

Specification<One> p = (user, query, cb) -> { 
    return cb.equal(
      query.from(Order.class).get("fullName"), 
      cb.concat(user.get("firstName"), cb.concat(" ", user.get("lastName")))); 
}; 

List<One> list = oneRepo.findAll(p); 
+0

J'ai besoin de spécifications parce que je construis une requête complexe dont c'est une partie – haohaolee

+0

@haohaolee clair .. va penser ... – Cepr0

+0

@haohaolee essayer la mise à jour ... – Cepr0