Skip to content

Commit 46f0309

Browse files
tomek82schauder
authored andcommitted
Avoid selection of duplicate columns.
This fixes #1865 for derived queries. Signed-off-by: Tomasz Bielecki <[email protected]> Original pull request #2125 See #1865
1 parent ea5cefe commit 46f0309

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryCreator.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616
package org.springframework.data.jdbc.repository.query;
1717

1818
import java.util.ArrayList;
19+
import java.util.LinkedHashSet;
1920
import java.util.List;
2021
import java.util.Objects;
2122
import java.util.Optional;
23+
import java.util.Set;
2224

2325
import org.springframework.data.domain.Pageable;
2426
import org.springframework.data.domain.Sort;
@@ -60,6 +62,7 @@
6062
* @author Jens Schauder
6163
* @author Myeonghyeon Lee
6264
* @author Diego Krupitza
65+
* @author Tomasz Bielecki
6366
* @since 2.0
6467
*/
6568
class JdbcQueryCreator extends RelationalQueryCreator<ParametrizedQuery> {
@@ -235,7 +238,7 @@ SelectBuilder.SelectLimitOffset createSelectClause(RelationalPersistentEntity<?>
235238

236239
private SelectBuilder.SelectJoin selectBuilder(Table table) {
237240

238-
List<Expression> columnExpressions = new ArrayList<>();
241+
Set<Expression> columnExpressions = new LinkedHashSet<>();
239242
RelationalPersistentEntity<?> entity = entityMetadata.getTableEntity();
240243
SqlContext sqlContext = new SqlContext(entity);
241244

spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/PartTreeJdbcQueryUnitTests.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,14 @@
3939
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
4040
import org.springframework.data.relational.core.dialect.Escaper;
4141
import org.springframework.data.relational.core.dialect.H2Dialect;
42+
import org.springframework.data.relational.core.mapping.Column;
4243
import org.springframework.data.relational.core.mapping.Embedded;
4344
import org.springframework.data.relational.core.mapping.MappedCollection;
4445
import org.springframework.data.relational.core.mapping.Table;
4546
import org.springframework.data.relational.core.sql.LockMode;
4647
import org.springframework.data.relational.repository.Lock;
4748
import org.springframework.data.relational.repository.query.RelationalParametersParameterAccessor;
49+
import org.springframework.data.repository.ListCrudRepository;
4850
import org.springframework.data.repository.NoRepositoryBean;
4951
import org.springframework.data.repository.Repository;
5052
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
@@ -61,6 +63,7 @@
6163
* @author Jens Schauder
6264
* @author Myeonghyeon Lee
6365
* @author Diego Krupitza
66+
* @author Tomasz Bielecki
6467
*/
6568
@ExtendWith(MockitoExtension.class)
6669
public class PartTreeJdbcQueryUnitTests {
@@ -669,6 +672,17 @@ public void createsQueryForCountProjection() throws Exception {
669672
.isEqualTo("SELECT COUNT(*) FROM " + TABLE + " WHERE " + TABLE + ".\"FIRST_NAME\" = :first_name");
670673
}
671674

675+
@Test
676+
public void mappingMapKeyToChildShouldNotResultInDuplicateColumn() throws Exception {
677+
Method method = ParentRepository.class.getMethod("findByName", String.class);
678+
var queryMethod = new JdbcQueryMethod(method, new DefaultRepositoryMetadata(ParentRepository.class),
679+
new SpelAwareProxyProjectionFactory(), new PropertiesBasedNamedQueries(new Properties()), mappingContext);
680+
PartTreeJdbcQuery jdbcQuery = createQuery(queryMethod);
681+
ParametrizedQuery query = jdbcQuery.createQuery(getAccessor(queryMethod, new Object[] { "John" }), returnedType);
682+
683+
assertThat(query.getQuery()).containsOnlyOnce("\"children\".\"NICK_NAME\" AS \"children_NICK_NAME\"");
684+
}
685+
672686
private PartTreeJdbcQuery createQuery(JdbcQueryMethod queryMethod) {
673687
return new PartTreeJdbcQuery(mappingContext, queryMethod, JdbcH2Dialect.INSTANCE, converter,
674688
mock(NamedParameterJdbcOperations.class), mock(RowMapper.class));
@@ -776,6 +790,19 @@ interface UserRepository extends Repository<User, Long> {
776790
long countByFirstName(String name);
777791
}
778792

793+
@NoRepositoryBean
794+
interface ParentRepository extends ListCrudRepository<Parent, Long> {
795+
Parent findByName(String name);
796+
}
797+
798+
@Table("parent")
799+
record Parent(@Id String name, @MappedCollection(idColumn = "NICK_NAME") Child children) {
800+
}
801+
802+
@Table("children")
803+
record Child(@Column("NICK_NAME") String nickName, String name) {
804+
}
805+
779806
@Table("users")
780807
static class User {
781808

0 commit comments

Comments
 (0)