Skip to content

Commit

Permalink
OY-798 Migroidaan laskentakaavat jsonb:ksi inkrementaalisesti
Browse files Browse the repository at this point in the history
  • Loading branch information
jkorri committed Jan 24, 2025
1 parent b11ca03 commit 3993801
Show file tree
Hide file tree
Showing 15 changed files with 187 additions and 13 deletions.
4 changes: 4 additions & 0 deletions valintaperusteet-domain/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
<name>Valintaperusteet :: Domain</name>

<dependencies>
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package fi.vm.sade.service.valintaperusteet.model;

import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.*;
import java.io.Serializable;

Expand All @@ -13,6 +14,7 @@ public class BaseEntity implements Serializable {
@Id
@Column(name = ID_COLUMN_NAME, unique = true, nullable = false)
@GeneratedValue
@JsonIgnore
private Long id;

@Version
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package fi.vm.sade.service.valintaperusteet.model;

import jakarta.persistence.EntityManager;

public class EntityManagerUtils {

private static EntityManager em;

public static void setEntityManager(EntityManager em) {
EntityManagerUtils.em = em;
}

public static EntityManager getEntityManager() {
return em;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
package fi.vm.sade.service.valintaperusteet.model;

import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import jakarta.persistence.*;
import jakarta.validation.constraints.Min;
import java.io.IOException;

@Entity
@Table(name = "funktioargumentti")
Expand All @@ -10,6 +20,7 @@ public class Funktioargumentti extends BaseEntity implements Comparable<Funktioa

@JoinColumn(name = "funktiokutsuparent_id", nullable = false)
@ManyToOne(optional = false, cascade = CascadeType.PERSIST)
@JsonBackReference
private Funktiokutsu parent;

@JoinColumn(name = "funktiokutsuchild_id", nullable = true)
Expand All @@ -18,6 +29,8 @@ public class Funktioargumentti extends BaseEntity implements Comparable<Funktioa

@JoinColumn(name = "laskentakaavachild_id", nullable = true)
@ManyToOne(cascade = CascadeType.PERSIST)
@JsonSerialize(using = CustomLaskentakaavaSerializer.class)
@JsonDeserialize(using = CustomLaskentakaavaDeserializer.class)
private Laskentakaava laskentakaavaChild;

@Min(1)
Expand Down Expand Up @@ -70,4 +83,26 @@ public void setLaajennettuKaava(Funktiokutsu laajennettuKaava) {
public int compareTo(Funktioargumentti o) {
return indeksi - o.indeksi;
}

static class CustomLaskentakaavaSerializer extends JsonSerializer<Laskentakaava> {

@Override
public void serialize(Laskentakaava value, JsonGenerator gen, SerializerProvider serializers)
throws IOException {
gen.writeNumber(value.getId());
}
}

static class CustomLaskentakaavaDeserializer extends JsonDeserializer<Laskentakaava> {

@Override
public Laskentakaava deserialize(JsonParser p, DeserializationContext ctxt) {
try {
return EntityManagerUtils.getEntityManager()
.find(Laskentakaava.class, p.getNumberValue().longValue());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package fi.vm.sade.service.valintaperusteet.model;

import com.fasterxml.jackson.annotation.JsonBackReference;
import jakarta.persistence.*;

@MappedSuperclass
Expand All @@ -9,6 +10,7 @@ public abstract class Konvertteriparametri extends BaseEntity {

@JoinColumn(name = "funktiokutsu_id", nullable = false)
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JsonBackReference
private Funktiokutsu funktiokutsu;

public String getPaluuarvo() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
package fi.vm.sade.service.valintaperusteet.model;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.*;
import fi.vm.sade.service.valintaperusteet.dto.model.Funktiotyyppi;
import jakarta.persistence.Cacheable;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.PrePersist;
import jakarta.persistence.PreUpdate;
import jakarta.persistence.Table;
import jakarta.persistence.*;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;

@Entity
@Table(name = "laskentakaava")
Expand Down Expand Up @@ -56,6 +48,11 @@ public class Laskentakaava extends BaseEntity implements FunktionArgumentti {
@OneToMany(fetch = FetchType.LAZY, mappedBy = "laskentakaava", cascade = CascadeType.PERSIST)
private Set<Jarjestyskriteeri> jarjestyskriteerit = new HashSet<Jarjestyskriteeri>();

@JdbcTypeCode(SqlTypes.JSON)
@Column(columnDefinition = "jsonb")
@Convert(converter = JsonNodeConverter.class)
private Funktiokutsu formula;

public Boolean getOnLuonnos() {
return onLuonnos;
}
Expand Down Expand Up @@ -97,11 +94,15 @@ public void setHakukohde(HakukohdeViite hakukohde) {
}

public Funktiokutsu getFunktiokutsu() {
if (this.formula != null) {
return this.formula;
}
return funktiokutsu;
}

public void setFunktiokutsu(Funktiokutsu funktiokutsu) {
this.funktiokutsu = funktiokutsu;
this.formula = funktiokutsu;
}

public Funktiotyyppi getTyyppi() {
Expand All @@ -128,6 +129,10 @@ public void setKopiot(Set<Laskentakaava> kopiot) {
this.kopiot = kopiot;
}

public void migrateFormula() {
this.formula = this.funktiokutsu;
}

@Override
public Long getId() {
return super.getId();
Expand Down Expand Up @@ -163,4 +168,28 @@ public Laskentakaava getKopioLaskentakaavasta() {
public void setKopioLaskentakaavasta(Laskentakaava kopioLaskentakaavasta) {
this.kopioLaskentakaavasta = kopioLaskentakaavasta;
}

@Converter(autoApply = true)
static class JsonNodeConverter implements AttributeConverter<Funktiokutsu, String> {

private final ObjectMapper objectMapper = new ObjectMapper();

@Override
public String convertToDatabaseColumn(Funktiokutsu funktiokutsu) {
try {
return objectMapper.writeValueAsString(funktiokutsu);
} catch (JsonProcessingException e) {
throw new RuntimeException("Error while serializing JsonNode to JSON", e);
}
}

@Override
public Funktiokutsu convertToEntityAttribute(String dbData) {
try {
return dbData == null ? null : objectMapper.readValue(dbData, Funktiokutsu.class);
} catch (JsonProcessingException e) {
throw new RuntimeException("Error while deserializing JSON to JsonNode", e);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package fi.vm.sade.service.valintaperusteet.model;

import com.fasterxml.jackson.annotation.JsonBackReference;
import fi.vm.sade.service.valintaperusteet.dto.model.Kieli;
import jakarta.persistence.*;

Expand All @@ -19,6 +20,7 @@ public class LokalisoituTeksti extends BaseEntity {

@JoinColumn(name = "tekstiryhma_id", nullable = false)
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JsonBackReference
private TekstiRyhma ryhma;

public String getTeksti() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package fi.vm.sade.service.valintaperusteet.model;

import com.fasterxml.jackson.annotation.JsonBackReference;
import jakarta.persistence.*;

@Entity
Expand All @@ -14,6 +15,7 @@ public class Syoteparametri extends BaseEntity {

@JoinColumn(name = "funktiokutsu_id", nullable = false)
@ManyToOne(optional = false)
@JsonBackReference
private Funktiokutsu funktiokutsu;

public String getAvain() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package fi.vm.sade.service.valintaperusteet.model;

import com.fasterxml.jackson.annotation.JsonBackReference;
import fi.vm.sade.service.valintaperusteet.dto.model.Valintaperustelahde;
import jakarta.persistence.*;

Expand Down Expand Up @@ -28,6 +29,7 @@ public class ValintaperusteViite extends BaseEntity implements Comparable<Valint

@JoinColumn(name = "funktiokutsu_id", nullable = false)
@ManyToOne(optional = false)
@JsonBackReference
private Funktiokutsu funktiokutsu;

@Column(name = "on_pakollinen", nullable = false)
Expand Down Expand Up @@ -117,6 +119,7 @@ public void setIndeksi(Integer indeksi) {
}

@Transient
@JsonBackReference
public String getOsallistuminenTunniste() {
String osallistuminenTunniste = null;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package fi.vm.sade.service.valintaperusteet.model;

import com.fasterxml.jackson.annotation.JsonBackReference;
import jakarta.persistence.*;
import java.util.*;

Expand All @@ -26,6 +27,7 @@ public class Valintaryhma extends BaseEntity {

@JoinColumn(name = "parent_id")
@ManyToOne(fetch = FetchType.LAZY)
@JsonBackReference
private Valintaryhma ylavalintaryhma;

@OneToMany(fetch = FetchType.LAZY, mappedBy = "ylavalintaryhma")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class App {
public static final String CONTEXT_PATH = "/valintaperusteet-service";

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package fi.vm.sade.service.valintaperusteet.config;

import fi.vm.sade.service.valintaperusteet.model.EntityManagerUtils;
import jakarta.persistence.EntityManager;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

@Configuration
public class EntityManagerConfiguration implements InitializingBean {

@Autowired private EntityManager entityManager;

public void afterPropertiesSet() throws Exception {
EntityManagerUtils.setEntityManager(this.entityManager);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,7 @@ List<Laskentakaava> findKaavas(
String hakukohdeOid,
fi.vm.sade.service.valintaperusteet.dto.model.Funktiotyyppi tyyppi);

void migrateLaskentakaavat(int limit);

void flush();
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,18 @@
import fi.vm.sade.service.valintaperusteet.dao.LaskentakaavaDAO;
import fi.vm.sade.service.valintaperusteet.dto.model.Funktiotyyppi;
import fi.vm.sade.service.valintaperusteet.model.*;
import jakarta.persistence.EntityManager;
import java.util.Collection;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository
public class LaskentakaavaDAOImpl extends AbstractJpaDAOImpl<Laskentakaava, Long>
implements LaskentakaavaDAO {

@Autowired EntityManager em;

@Override
public Laskentakaava getLaskentakaava(Long id) {
QLaskentakaava lk = QLaskentakaava.laskentakaava;
Expand Down Expand Up @@ -92,4 +98,17 @@ protected JPAQueryFactory queryFactory() {
public void flush() {
getEntityManager().flush();
}

@Override
public void migrateLaskentakaavat(int limit) {
QLaskentakaava lk = QLaskentakaava.laskentakaava;
Collection<Laskentakaava> laskentakaavat =
queryFactory().selectFrom(lk).where(lk.formula.isNull()).limit(limit).distinct().fetch();

laskentakaavat.forEach(
kaava -> {
kaava.migrateFormula();
this.update(kaava);
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package fi.vm.sade.service.valintaperusteet.service.background;

import fi.vm.sade.service.valintaperusteet.dao.LaskentakaavaDAO;
import fi.vm.sade.service.valintaperusteet.dto.mapping.ValintaperusteetModelMapper;
import fi.vm.sade.service.valintaperusteet.service.LaskentakaavaService;
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Component
public class LaskentaKaavaMigrationService {

private static final Logger LOG = LoggerFactory.getLogger(LaskentaKaavaMigrationService.class);

@Autowired private LaskentakaavaService laskentakaavaService;

@Autowired private LaskentakaavaDAO laskentakaavaDAO;

@Autowired private ValintaperusteetModelMapper modelMapper;

@Scheduled(initialDelay = 5, fixedDelay = 50, timeUnit = TimeUnit.MILLISECONDS)
@Transactional
public void migrateLaskentakaavat() {
Instant start = Instant.now();

laskentakaavaDAO.migrateLaskentakaavat(1);

LOG.warn(
"Saved laskentakaavat, duration: " + Duration.between(start, Instant.now()).toMillis());
}
}

0 comments on commit 3993801

Please sign in to comment.