From e2e692ce8323f170c244da53b63dfa330f7392dc Mon Sep 17 00:00:00 2001 From: Thomas Darimont Date: Sat, 15 Mar 2014 20:28:16 +0100 Subject: [PATCH] DATAJPA-497 - Fixed handling of OrderSpecifier for Querydsl based repositories. We now only generate an additional left-join for the order expression of the targetPath is an EntityPath. Original pull request: #69. --- .../data/jpa/repository/support/Querydsl.java | 3 +- .../sample/EmbeddedIdExampleDepartment.java | 6 +- .../sample/EmbeddedIdExampleEmployee.java | 9 +- .../sample/EmbeddedIdExampleEmployeePK.java | 12 ++- .../sample/IdClassExampleEmployeePK.java | 16 ++-- .../RepositoryWithCompositeKeyTests.java | 82 +++++++++++++++++++ .../EmployeeRepositoryWithEmbeddedId.java | 15 +++- .../sample/EmployeeRepositoryWithIdClass.java | 15 +++- 8 files changed, 142 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/springframework/data/jpa/repository/support/Querydsl.java b/src/main/java/org/springframework/data/jpa/repository/support/Querydsl.java index 6dc604dbd..3afd09aa6 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/Querydsl.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/Querydsl.java @@ -171,11 +171,12 @@ public class Querydsl { boolean targetPathRootIsEntityRoot = targetPath.getRoot().equals(builder.getRoot()); boolean targetPathEqualsRootEnityPath = targetPath.toString().equals(builder.toString()); + boolean targetPathIsEntityPath = targetPath instanceof EntityPath; if (!targetPathRootIsEntityRoot) { query.leftJoin((EntityPath) builder.get((String) targetPath.getMetadata().getElement()), targetPath); - } else if (targetPathRootIsEntityRoot && !targetPathEqualsRootEnityPath) { + } else if (targetPathRootIsEntityRoot && !targetPathEqualsRootEnityPath && targetPathIsEntityPath) { PathBuilder joinPathBuilder = new PathBuilder(targetPath.getType(), targetPath.getMetadata().getElement() .toString()); diff --git a/src/test/java/org/springframework/data/jpa/domain/sample/EmbeddedIdExampleDepartment.java b/src/test/java/org/springframework/data/jpa/domain/sample/EmbeddedIdExampleDepartment.java index 5dd7bb46b..fb954dca5 100644 --- a/src/test/java/org/springframework/data/jpa/domain/sample/EmbeddedIdExampleDepartment.java +++ b/src/test/java/org/springframework/data/jpa/domain/sample/EmbeddedIdExampleDepartment.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 the original author or authors. + * Copyright 2013-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,8 +18,12 @@ package org.springframework.data.jpa.domain.sample; import javax.persistence.Entity; import javax.persistence.Id; +/** + * @author Thomas Darimont + */ @Entity public class EmbeddedIdExampleDepartment { + private String name; @Id private Long departmentId; diff --git a/src/test/java/org/springframework/data/jpa/domain/sample/EmbeddedIdExampleEmployee.java b/src/test/java/org/springframework/data/jpa/domain/sample/EmbeddedIdExampleEmployee.java index 9fd138cce..d56ce2aa0 100644 --- a/src/test/java/org/springframework/data/jpa/domain/sample/EmbeddedIdExampleEmployee.java +++ b/src/test/java/org/springframework/data/jpa/domain/sample/EmbeddedIdExampleEmployee.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 the original author or authors. + * Copyright 2013-2104 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,11 +21,16 @@ import javax.persistence.Entity; import javax.persistence.ManyToOne; import javax.persistence.MapsId; +/** + * @author Thomas Darimont + */ @Entity public class EmbeddedIdExampleEmployee { @EmbeddedId EmbeddedIdExampleEmployeePK employeePk; - @MapsId("departmentId") @ManyToOne(cascade = CascadeType.ALL)// + + @MapsId("departmentId")// + @ManyToOne(cascade = CascadeType.ALL)// EmbeddedIdExampleDepartment department; public EmbeddedIdExampleEmployeePK getEmployeePk() { diff --git a/src/test/java/org/springframework/data/jpa/domain/sample/EmbeddedIdExampleEmployeePK.java b/src/test/java/org/springframework/data/jpa/domain/sample/EmbeddedIdExampleEmployeePK.java index f5027362e..d27d9e8a4 100644 --- a/src/test/java/org/springframework/data/jpa/domain/sample/EmbeddedIdExampleEmployeePK.java +++ b/src/test/java/org/springframework/data/jpa/domain/sample/EmbeddedIdExampleEmployeePK.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 the original author or authors. + * Copyright 2013-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,9 @@ import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Embeddable; +/** + * @author Thomas Darimont + */ @Embeddable public class EmbeddedIdExampleEmployeePK implements Serializable { private static final long serialVersionUID = 1L; @@ -28,6 +31,13 @@ public class EmbeddedIdExampleEmployeePK implements Serializable { @Column(nullable = false) private Long departmentId; + public EmbeddedIdExampleEmployeePK() {} + + public EmbeddedIdExampleEmployeePK(Long employeeId, Long departmentId) { + this.employeeId = employeeId; + this.departmentId = departmentId; + } + public Long getEmployeeId() { return this.employeeId; } diff --git a/src/test/java/org/springframework/data/jpa/domain/sample/IdClassExampleEmployeePK.java b/src/test/java/org/springframework/data/jpa/domain/sample/IdClassExampleEmployeePK.java index 0b874c557..1ceb76b84 100644 --- a/src/test/java/org/springframework/data/jpa/domain/sample/IdClassExampleEmployeePK.java +++ b/src/test/java/org/springframework/data/jpa/domain/sample/IdClassExampleEmployeePK.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 the original author or authors. + * Copyright 2013-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,9 @@ package org.springframework.data.jpa.domain.sample; import java.io.Serializable; +/** + * @author Thomas Darimont + */ public class IdClassExampleEmployeePK implements Serializable { private static final long serialVersionUID = 1L; @@ -25,6 +28,11 @@ public class IdClassExampleEmployeePK implements Serializable { public IdClassExampleEmployeePK() {} + public IdClassExampleEmployeePK(long empId, long department) { + this.empId = empId; + this.department = department; + } + public long getEmpId() { return this.empId; } @@ -41,9 +49,6 @@ public class IdClassExampleEmployeePK implements Serializable { this.department = department; } - /* (non-Javadoc) - * @see java.lang.Object#hashCode() - */ @Override public int hashCode() { final int prime = 31; @@ -53,9 +58,6 @@ public class IdClassExampleEmployeePK implements Serializable { return result; } - /* (non-Javadoc) - * @see java.lang.Object#equals(java.lang.Object) - */ @Override public boolean equals(Object obj) { if (this == obj) { diff --git a/src/test/java/org/springframework/data/jpa/repository/RepositoryWithCompositeKeyTests.java b/src/test/java/org/springframework/data/jpa/repository/RepositoryWithCompositeKeyTests.java index e9138a815..6fd98addf 100644 --- a/src/test/java/org/springframework/data/jpa/repository/RepositoryWithCompositeKeyTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/RepositoryWithCompositeKeyTests.java @@ -18,6 +18,8 @@ package org.springframework.data.jpa.repository; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; +import java.util.List; + import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -32,6 +34,8 @@ import org.springframework.data.jpa.domain.sample.EmbeddedIdExampleEmployeePK; import org.springframework.data.jpa.domain.sample.IdClassExampleDepartment; import org.springframework.data.jpa.domain.sample.IdClassExampleEmployee; import org.springframework.data.jpa.domain.sample.IdClassExampleEmployeePK; +import org.springframework.data.jpa.domain.sample.QEmbeddedIdExampleEmployee; +import org.springframework.data.jpa.domain.sample.QIdClassExampleEmployee; import org.springframework.data.jpa.repository.sample.EmployeeRepositoryWithEmbeddedId; import org.springframework.data.jpa.repository.sample.EmployeeRepositoryWithIdClass; import org.springframework.data.jpa.repository.sample.SampleConfig; @@ -133,4 +137,82 @@ public class RepositoryWithCompositeKeyTests { assertThat(page, is(notNullValue())); assertThat(page.getTotalElements(), is(1L)); } + + /** + * @see DATAJPA-497 + */ + @Test + public void sortByEmbeddedPkFieldInCompositePkWithEmbeddedIdInQueryDsl() { + + EmbeddedIdExampleDepartment dep1 = new EmbeddedIdExampleDepartment(); + dep1.setDepartmentId(1L); + dep1.setName("Dep1"); + + EmbeddedIdExampleDepartment dep2 = new EmbeddedIdExampleDepartment(); + dep2.setDepartmentId(2L); + dep2.setName("Dep2"); + + EmbeddedIdExampleEmployee emp1 = new EmbeddedIdExampleEmployee(); + emp1.setEmployeePk(new EmbeddedIdExampleEmployeePK(3L, null)); + emp1.setDepartment(dep2); + emp1 = employeeRepositoryWithEmbeddedId.save(emp1); + + EmbeddedIdExampleEmployee emp2 = new EmbeddedIdExampleEmployee(); + emp2.setEmployeePk(new EmbeddedIdExampleEmployeePK(2L, null)); + emp2.setDepartment(dep1); + emp2 = employeeRepositoryWithEmbeddedId.save(emp2); + + EmbeddedIdExampleEmployee emp3 = new EmbeddedIdExampleEmployee(); + emp3.setEmployeePk(new EmbeddedIdExampleEmployeePK(1L, null)); + emp3.setDepartment(dep2); + emp3 = employeeRepositoryWithEmbeddedId.save(emp3); + + QEmbeddedIdExampleEmployee emp = QEmbeddedIdExampleEmployee.embeddedIdExampleEmployee; + List result = employeeRepositoryWithEmbeddedId.findAll( + emp.employeePk.departmentId.eq(dep2.getDepartmentId()), emp.employeePk.employeeId.asc()); + + assertThat(result, is(notNullValue())); + assertThat(result, hasSize(2)); + assertThat(result.get(0), is(emp3)); + assertThat(result.get(1), is(emp1)); + } + + /** + * @see DATAJPA-497 + */ + @Test + public void sortByEmbeddedPkFieldInCompositePkWithIdClassInQueryDsl() { + + IdClassExampleDepartment dep1 = new IdClassExampleDepartment(); + dep1.setDepartmentId(1L); + dep1.setName("Dep1"); + + IdClassExampleDepartment dep2 = new IdClassExampleDepartment(); + dep2.setDepartmentId(2L); + dep2.setName("Dep2"); + + IdClassExampleEmployee emp1 = new IdClassExampleEmployee(); + emp1.setEmpId(3L); + emp1.setDepartment(dep2); + emp1 = employeeRepositoryWithIdClass.save(emp1); + + IdClassExampleEmployee emp2 = new IdClassExampleEmployee(); + emp2.setEmpId(2L); + emp2.setDepartment(dep1); + emp2 = employeeRepositoryWithIdClass.save(emp2); + + IdClassExampleEmployee emp3 = new IdClassExampleEmployee(); + emp3.setEmpId(1L); + emp3.setDepartment(dep2); + emp3 = employeeRepositoryWithIdClass.save(emp3); + + QIdClassExampleEmployee emp = QIdClassExampleEmployee.idClassExampleEmployee; + List result = employeeRepositoryWithIdClass.findAll( + emp.department.departmentId.eq(dep2.getDepartmentId()), emp.empId.asc()); + + assertThat(result, is(notNullValue())); + assertThat(result, hasSize(2)); + assertThat(result.get(0), is(emp3)); + assertThat(result.get(1), is(emp1)); + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/sample/EmployeeRepositoryWithEmbeddedId.java b/src/test/java/org/springframework/data/jpa/repository/sample/EmployeeRepositoryWithEmbeddedId.java index 912a9f2c5..dbfd9c5b4 100644 --- a/src/test/java/org/springframework/data/jpa/repository/sample/EmployeeRepositoryWithEmbeddedId.java +++ b/src/test/java/org/springframework/data/jpa/repository/sample/EmployeeRepositoryWithEmbeddedId.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 the original author or authors. + * Copyright 2013-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,10 +15,16 @@ */ package org.springframework.data.jpa.repository.sample; +import java.util.List; + import org.springframework.context.annotation.Lazy; import org.springframework.data.jpa.domain.sample.EmbeddedIdExampleEmployee; import org.springframework.data.jpa.domain.sample.EmbeddedIdExampleEmployeePK; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.querydsl.QueryDslPredicateExecutor; + +import com.mysema.query.types.OrderSpecifier; +import com.mysema.query.types.Predicate; /** * Demonstrates the support for composite primary keys with {@code @EmbeddedId}. @@ -27,4 +33,9 @@ import org.springframework.data.jpa.repository.JpaRepository; */ @Lazy public interface EmployeeRepositoryWithEmbeddedId extends - JpaRepository {} + JpaRepository, + QueryDslPredicateExecutor { + + List findAll(Predicate predicate, OrderSpecifier... orders); + +} diff --git a/src/test/java/org/springframework/data/jpa/repository/sample/EmployeeRepositoryWithIdClass.java b/src/test/java/org/springframework/data/jpa/repository/sample/EmployeeRepositoryWithIdClass.java index 7f67eedee..17828740d 100644 --- a/src/test/java/org/springframework/data/jpa/repository/sample/EmployeeRepositoryWithIdClass.java +++ b/src/test/java/org/springframework/data/jpa/repository/sample/EmployeeRepositoryWithIdClass.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 the original author or authors. + * Copyright 2013-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,10 +15,16 @@ */ package org.springframework.data.jpa.repository.sample; +import java.util.List; + import org.springframework.context.annotation.Lazy; import org.springframework.data.jpa.domain.sample.IdClassExampleEmployee; import org.springframework.data.jpa.domain.sample.IdClassExampleEmployeePK; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.querydsl.QueryDslPredicateExecutor; + +import com.mysema.query.types.OrderSpecifier; +import com.mysema.query.types.Predicate; /** * Demonstrates the support for composite primary keys with {@code @IdClass}. @@ -26,4 +32,9 @@ import org.springframework.data.jpa.repository.JpaRepository; * @author Thomas Darimont */ @Lazy -public interface EmployeeRepositoryWithIdClass extends JpaRepository {} +public interface EmployeeRepositoryWithIdClass extends JpaRepository, + QueryDslPredicateExecutor { + + List findAll(Predicate predicate, OrderSpecifier... orders); + +}