Skip to content

Commit d828773

Browse files
committed
/category/add: fix DuplicateKeyException when name differs from existing only by case.
Do case-insensitive search for category name in English and Russian. Fix #442
1 parent 95b59c2 commit d828773

File tree

4 files changed

+20
-8
lines changed

4 files changed

+20
-8
lines changed

src/main/java/ru/mystamps/web/service/CategoryServiceImpl.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import java.util.Date;
2121
import java.util.List;
22+
import java.util.Locale;
2223

2324
import org.apache.commons.lang3.StringUtils;
2425
import org.apache.commons.lang3.Validate;
@@ -38,6 +39,7 @@
3839
import ru.mystamps.web.dao.dto.UrlEntityDto;
3940
import ru.mystamps.web.service.dto.AddCategoryDto;
4041
import ru.mystamps.web.support.spring.security.HasAuthority;
42+
import ru.mystamps.web.util.LocaleUtils;
4143
import ru.mystamps.web.util.SlugUtils;
4244

4345
@RequiredArgsConstructor
@@ -112,14 +114,22 @@ public long countCategoriesOf(Integer collectionId) {
112114
@Transactional(readOnly = true)
113115
public long countByName(String name) {
114116
Validate.isTrue(name != null, "Name must be non null");
115-
return categoryDao.countByName(name);
117+
118+
// converting to lowercase to do a case-insensitive search
119+
String categoryName = name.toLowerCase(Locale.ENGLISH);
120+
121+
return categoryDao.countByName(categoryName);
116122
}
117123

118124
@Override
119125
@Transactional(readOnly = true)
120126
public long countByNameRu(String name) {
121127
Validate.isTrue(name != null, "Name in Russian must be non null");
122-
return categoryDao.countByNameRu(name);
128+
129+
// converting to lowercase to do a case-insensitive search
130+
String categoryName = name.toLowerCase(LocaleUtils.RUSSIAN);
131+
132+
return categoryDao.countByNameRu(categoryName);
123133
}
124134

125135
@Override

src/main/java/ru/mystamps/web/util/LocaleUtils.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424

2525
public final class LocaleUtils {
2626

27+
public static final Locale RUSSIAN = new Locale("ru", "RU");
28+
2729
private LocaleUtils() {
2830
}
2931

src/main/resources/sql/category_dao_queries.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ SELECT COUNT(*) \
2626
category.count_categories_by_name = \
2727
SELECT COUNT(*) \
2828
FROM categories \
29-
WHERE name = :name
29+
WHERE LOWER(name) = :name
3030

3131
category.count_categories_by_name_ru = \
3232
SELECT COUNT(*) \
3333
FROM categories \
34-
WHERE name_ru = :name
34+
WHERE LOWER(name_ru) = :name
3535

3636
category.count_categories_of_collection = \
3737
SELECT COUNT(DISTINCT s.category_id) AS counter \

src/test/groovy/ru/mystamps/web/service/CategoryServiceImplTest.groovy

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -323,12 +323,12 @@ class CategoryServiceImplTest extends Specification {
323323
result == 2L
324324
}
325325

326-
def "countByName() should pass category name to dao"() {
326+
def "countByName() should pass category name to dao in lowercase"() {
327327
when:
328328
service.countByName('Sport')
329329
then:
330330
1 * categoryDao.countByName({ String name ->
331-
assert name == 'Sport'
331+
assert name == 'sport'
332332
return true
333333
})
334334
}
@@ -353,12 +353,12 @@ class CategoryServiceImplTest extends Specification {
353353
result == 2L
354354
}
355355

356-
def "countByNameRu() should pass category name to dao"() {
356+
def "countByNameRu() should pass category name to dao in lowercase"() {
357357
when:
358358
service.countByNameRu('Спорт')
359359
then:
360360
1 * categoryDao.countByNameRu({ String name ->
361-
assert name == 'Спорт'
361+
assert name == 'спорт'
362362
return true
363363
})
364364
}

0 commit comments

Comments
 (0)