use only persistViaSql #156

Merged
hsh-michaelhoennig merged 1 commits from feature/faster-hosting-assets-import-by-using-sql into master 2025-02-07 09:31:43 +01:00
2 changed files with 77 additions and 34 deletions

View File

@ -4,6 +4,8 @@ import com.opencsv.CSVParserBuilder;
import com.opencsv.CSVReader; import com.opencsv.CSVReader;
import com.opencsv.CSVReaderBuilder; import com.opencsv.CSVReaderBuilder;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItem;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProject;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset; import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset;
import net.hostsharing.hsadminng.rbac.context.ContextBasedTest; import net.hostsharing.hsadminng.rbac.context.ContextBasedTest;
import net.hostsharing.hsadminng.persistence.BaseEntity; import net.hostsharing.hsadminng.persistence.BaseEntity;
@ -155,37 +157,78 @@ public class CsvDataImport extends ContextBasedTest {
return record; return record;
} }
public <T extends BaseEntity> T persist(final Integer id, final T entity) { @SneakyThrows
try { public void persistViaSql(final Integer id, final HsBookingProject entity) {
if (entity instanceof HsHostingAsset ha) { entity.setUuid(UUID.randomUUID());
//noinspection unchecked
return (T) persistViaSql(id, ha);
}
return persistViaEM(id, entity);
} catch (Exception exc) {
errors.add("failed to persist #" + entity.hashCode() + ": " + entity);
errors.add(exc.toString());
}
return entity;
}
public <T extends BaseEntity> T persistViaEM(final Integer id, final T entity) { final var query = em.createNativeQuery("""
if (em.contains(entity)) { insert into hs_booking.project(
return entity; uuid,
} version,
try { debitorUuid,
em.persist(entity); caption)
em.flush(); // makes it a bit slower, but produces better error messages values (
System.out.println("persisted #" + id + " as " + entity.getUuid()); :uuid,
return entity; :version,
} catch (final Exception exc) { :debitorUuid,
System.err.println("persist failed for #" + id + " as " + entity); :caption)
throw exc; // for breakpoints """)
} .setParameter("uuid", entity.getUuid())
.setParameter("version", entity.getVersion())
.setParameter("debitorUuid", entity.getDebitor().getUuid())
.setParameter("caption", entity.getCaption());
final var count = query.executeUpdate();
logError(() -> {
assertThat(count).describedAs("persisting BookingProject #" + id + " failed: " + entity).isEqualTo(1);
});
} }
@SneakyThrows @SneakyThrows
public BaseEntity<HsHostingAsset> persistViaSql(final Integer id, final HsHostingAsset entity) { public void persistViaSql(final Integer id, final HsBookingItem entity) {
if (entity.getUuid() != null) {
return;
}
entity.setUuid(UUID.randomUUID());
final var query = em.createNativeQuery("""
insert into hs_booking.item(
uuid,
version,
type,
projectUuid,
parentItemUuid,
validity,
caption,
resources)
values (
:uuid,
:version,
:type,
:projectUuid,
:parentItemUuid,
:validity,
:caption,
cast(:resources as jsonb))
""")
.setParameter("uuid", entity.getUuid())
.setParameter("version", entity.getVersion())
.setParameter("projectUuid", ofNullable(entity.getProject()).map(BaseEntity::getUuid).orElse(null))
.setParameter("type", entity.getType().name())
.setParameter("parentItemUuid", ofNullable(entity.getParentItem()).map(BaseEntity::getUuid).orElse(null))
.setParameter("validity", entity.getValidity())
.setParameter("caption", entity.getCaption())
.setParameter("resources", entity.getResources().toString().replace("\t", "\\t"));
final var count = query.executeUpdate();
logError(() -> {
assertThat(count).describedAs("persisting BookingItem #" + id + " failed: " + entity).isEqualTo(1);
});
}
@SneakyThrows
public HsHostingAsset persistViaSql(final Integer id, final HsHostingAsset entity) {
if (entity.getUuid() == null) { if (entity.getUuid() == null) {
entity.setUuid(UUID.randomUUID()); entity.setUuid(UUID.randomUUID());
} }
@ -229,7 +272,7 @@ public class CsvDataImport extends ContextBasedTest {
final var count = query.executeUpdate(); final var count = query.executeUpdate();
logError(() -> { logError(() -> {
assertThat(count).isEqualTo(1); assertThat(count).describedAs("persisting HostingAsset #" + id + " failed: " + entity).isEqualTo(1);
}); });
return entity; return entity;
} }

View File

@ -142,13 +142,13 @@ public class ImportHostingAssets extends CsvDataImport {
liquibase.assertThatCurrentMigrationsGotApplied(331, "hs-booking-SCHEMA"); liquibase.assertThatCurrentMigrationsGotApplied(331, "hs-booking-SCHEMA");
} }
record PartnerLegacyIdMapping(UUID uuid, Integer bp_id){}
record DebitorRecord(UUID uuid, Integer version, String defaultPrefix){}
@Test @Test
@Order(11010) @Order(11010)
void createBookingProjects() { void createBookingProjects() {
record PartnerLegacyIdMapping(UUID uuid, Integer bp_id){}
record DebitorRecord(UUID uuid, Integer version, String defaultPrefix){}
final var partnerLegacyIdMappings = em.createNativeQuery( final var partnerLegacyIdMappings = em.createNativeQuery(
""" """
select debitor.uuid, pid.bp_id select debitor.uuid, pid.bp_id
@ -755,7 +755,7 @@ public class ImportHostingAssets extends CsvDataImport {
jpaAttempt.transacted(() -> { jpaAttempt.transacted(() -> {
context(rbacSuperuser); context(rbacSuperuser);
bookingProjects.forEach(this::persist); bookingProjects.forEach(this::persistViaSql);
}).assertSuccessful(); }).assertSuccessful();
} }
@ -1115,7 +1115,7 @@ public class ImportHostingAssets extends CsvDataImport {
if (bi.getParentItem() != null) { if (bi.getParentItem() != null) {
persistRecursively(key, HsBookingItemEntityValidatorRegistry.validated(em, bi.getParentItem())); persistRecursively(key, HsBookingItemEntityValidatorRegistry.validated(em, bi.getParentItem()));
} }
persist(key, HsBookingItemEntityValidatorRegistry.validated(em, bi)); persistViaSql(key, HsBookingItemEntityValidatorRegistry.validated(em, bi));
} }
private void persistHostingAssets(final Map<Integer, HsHostingAssetRealEntity> assets) { private void persistHostingAssets(final Map<Integer, HsHostingAssetRealEntity> assets) {
@ -1139,7 +1139,7 @@ public class ImportHostingAssets extends CsvDataImport {
"'EMAIL_ADDRESS:.*\\.config\\.target' .*" "'EMAIL_ADDRESS:.*\\.config\\.target' .*"
) )
.prepareForSave() .prepareForSave()
.saveUsing(entity -> persist(entry.getKey(), entity)) .saveUsing(entity -> persistViaSql(entry.getKey(), entity))
.validateContext() .validateContext()
)); ));
} }