RED-5883 - duplicate dossier fix
This commit is contained in:
parent
502d7a949d
commit
1ba979a257
@ -10,8 +10,8 @@ import java.util.Set;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.transaction.Transactional;
|
|
||||||
|
|
||||||
|
import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@ -28,6 +28,8 @@ import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.do
|
|||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.transaction.annotation.Isolation;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@ -42,6 +44,7 @@ public class DossierPersistenceService {
|
|||||||
private final WatermarkService watermarkService;
|
private final WatermarkService watermarkService;
|
||||||
|
|
||||||
|
|
||||||
|
@Transactional
|
||||||
public DossierEntity insert(CreateOrUpdateDossierRequest createOrUpdateDossierRequest) {
|
public DossierEntity insert(CreateOrUpdateDossierRequest createOrUpdateDossierRequest) {
|
||||||
|
|
||||||
DossierEntity dossier = new DossierEntity();
|
DossierEntity dossier = new DossierEntity();
|
||||||
@ -55,8 +58,8 @@ public class DossierPersistenceService {
|
|||||||
dossier.setReportTemplates(reportTemplates);
|
dossier.setReportTemplates(reportTemplates);
|
||||||
this.handleDossierStatus(createOrUpdateDossierRequest, dossier);
|
this.handleDossierStatus(createOrUpdateDossierRequest, dossier);
|
||||||
this.handleWatermark(createOrUpdateDossierRequest, dossier);
|
this.handleWatermark(createOrUpdateDossierRequest, dossier);
|
||||||
return dossierRepository.save(dossier);
|
|
||||||
|
|
||||||
|
return dossierRepository.saveAndFlush(dossier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,9 @@ import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.do
|
|||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import javax.validation.ConstraintViolationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the internal interface between dossier request and the actual persistence.
|
* Provides the internal interface between dossier request and the actual persistence.
|
||||||
@ -51,7 +54,16 @@ public class DossierService {
|
|||||||
throw new BadRequestException("Dossier template is not active.");
|
throw new BadRequestException("Dossier template is not active.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
return dossierPersistenceService.insert(createOrUpdateDossierRequest);
|
return dossierPersistenceService.insert(createOrUpdateDossierRequest);
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (e.getCause() instanceof ConstraintViolationException) {
|
||||||
|
throw new ConflictException("Dossier with this name already exists");
|
||||||
|
} else {
|
||||||
|
log.debug("Unknown error when creating a dossier: ", e);
|
||||||
|
throw new BadRequestException("Failed to save dossier!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -111,3 +111,5 @@ databaseChangeLog:
|
|||||||
file: db/changelog/tenant/44-add-redaction-preview-color-column.changelog.yaml
|
file: db/changelog/tenant/44-add-redaction-preview-color-column.changelog.yaml
|
||||||
- include:
|
- include:
|
||||||
file: db/changelog/tenant/sql/43-add-applied-redaction-color.sql
|
file: db/changelog/tenant/sql/43-add-applied-redaction-color.sql
|
||||||
|
- include:
|
||||||
|
file: db/changelog/tenant/sql/45-unique-dossier-name.sql
|
||||||
|
|||||||
@ -0,0 +1,15 @@
|
|||||||
|
-- update duplicate dossier names
|
||||||
|
update dossier d1 set dossier_name = (
|
||||||
|
select
|
||||||
|
case when cnt = 1 then dossier_name
|
||||||
|
else dossier_name || ' ' || rn
|
||||||
|
end as dossier_name
|
||||||
|
from
|
||||||
|
(
|
||||||
|
select *, row_number() over w rn, count(*) over w cnt
|
||||||
|
from dossier
|
||||||
|
window w as (partition by dossier_name)
|
||||||
|
) t where t.id = d1.id);
|
||||||
|
|
||||||
|
-- create unique index on dossier_name and hard_deleted_time
|
||||||
|
CREATE UNIQUE INDEX dossier_name_index ON dossier (dossier_name, (hard_deleted_time IS NULL)) WHERE hard_deleted_time IS NULL;
|
||||||
@ -6,7 +6,12 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
|||||||
import java.time.OffsetDateTime;
|
import java.time.OffsetDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
import com.iqser.red.service.persistence.management.v1.processor.utils.multitenancy.TenantContext;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -50,6 +55,31 @@ public class DossierTest extends AbstractPersistenceServerServiceTest {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private WatermarkClient watermarkClient;
|
private WatermarkClient watermarkClient;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDossierRaceCondition() {
|
||||||
|
var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();
|
||||||
|
IntStream.range(0, 30).parallel().forEach(x -> dossierTesterAndProvider.provideTestDossier(dossierTemplate, "dossier: " + x));
|
||||||
|
var allDossiers = dossierClient.getAllDossiers(true, true);
|
||||||
|
var dossierCount = allDossiers.size();
|
||||||
|
assertThat(dossierCount).isEqualTo(30);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateDuplicateDossier() {
|
||||||
|
var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();
|
||||||
|
IntStream.range(0, 30).parallel().forEach(x -> {
|
||||||
|
try {
|
||||||
|
dossierTesterAndProvider.provideTestDossier(dossierTemplate, "sameNameDossier");
|
||||||
|
} catch (Exception e) {
|
||||||
|
// conflict exception is expected
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var allDossiers = dossierClient.getAllDossiers(true, true);
|
||||||
|
var dossierCount = allDossiers.size();
|
||||||
|
assertThat(dossierCount).isEqualTo(1);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDossier() {
|
public void testDossier() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user