Skip to content

Commit 3927a4f

Browse files
committed
Avoid selection of duplicate columns.
Signed-off-by: Tomasz Bielecki <[email protected]>
1 parent 520d6a7 commit 3927a4f

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
@@ -38,12 +38,14 @@
3838
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
3939
import org.springframework.data.relational.core.dialect.Escaper;
4040
import org.springframework.data.relational.core.dialect.H2Dialect;
41+
import org.springframework.data.relational.core.mapping.Column;
4142
import org.springframework.data.relational.core.mapping.Embedded;
4243
import org.springframework.data.relational.core.mapping.MappedCollection;
4344
import org.springframework.data.relational.core.mapping.Table;
4445
import org.springframework.data.relational.core.sql.LockMode;
4546
import org.springframework.data.relational.repository.Lock;
4647
import org.springframework.data.relational.repository.query.RelationalParametersParameterAccessor;
48+
import org.springframework.data.repository.ListCrudRepository;
4749
import org.springframework.data.repository.NoRepositoryBean;
4850
import org.springframework.data.repository.Repository;
4951
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
@@ -60,6 +62,7 @@
6062
* @author Jens Schauder
6163
* @author Myeonghyeon Lee
6264
* @author Diego Krupitza
65+
* @author Tomasz Bielecki
6366
*/
6467
@ExtendWith(MockitoExtension.class)
6568
public class PartTreeJdbcQueryUnitTests {
@@ -668,6 +671,17 @@ public void createsQueryForCountProjection() throws Exception {
668671
.isEqualTo("SELECT COUNT(*) FROM " + TABLE + " WHERE " + TABLE + ".\"FIRST_NAME\" = :first_name");
669672
}
670673

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

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

0 commit comments

Comments
 (0)