diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java index c5d1b3f8bb..02f6ea1d7d 100644 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java @@ -873,8 +873,9 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, GroupPro public boolean updateLocalizationText(RealmModel realm, String locale, String key, String text) { RealmLocalizationTextsEntity entity = getRealmLocalizationTextsEntity(locale, realm.getId()); if (entity != null && entity.getTexts() != null && entity.getTexts().containsKey(key)) { - entity.getTexts().put(key, text); - + Map keys = new HashMap<>(entity.getTexts()); + keys.put(key, text); + entity.setTexts(keys); em.persist(entity); return true; } else { @@ -891,7 +892,9 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, GroupPro entity.setLocale(locale); entity.setTexts(new HashMap<>()); } - entity.getTexts().put(key, text); + Map keys = new HashMap<>(entity.getTexts()); + keys.put(key, text); + entity.setTexts(keys); em.persist(entity); } @@ -931,8 +934,9 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, GroupPro public boolean deleteLocalizationText(RealmModel realm, String locale, String key) { RealmLocalizationTextsEntity entity = getRealmLocalizationTextsEntity(locale, realm.getId()); if (entity != null && entity.getTexts() != null && entity.getTexts().containsKey(key)) { - entity.getTexts().remove(key); - + Map keys = new HashMap<>(entity.getTexts()); + keys.remove(key); + entity.setTexts(keys); em.persist(entity); return true; } else { diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java index 2555bf3308..2610e72952 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java @@ -2230,6 +2230,9 @@ public class RealmAdapter implements RealmModel, JpaModel { Map currentLocalizationTexts = realm.getRealmLocalizationTexts(); if(currentLocalizationTexts.containsKey(locale)) { RealmLocalizationTextsEntity localizationTextsEntity = currentLocalizationTexts.get(locale); + Map keys = new HashMap<>(localizationTextsEntity.getTexts()); + keys.putAll(localizationTexts); + localizationTextsEntity.setTexts(keys); localizationTextsEntity.getTexts().putAll(localizationTexts); em.persist(localizationTextsEntity); diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmLocalizationTextsEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmLocalizationTextsEntity.java index 3faaec7382..66b9ea97ec 100644 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmLocalizationTextsEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmLocalizationTextsEntity.java @@ -18,6 +18,7 @@ package org.keycloak.models.jpa.entities; import java.io.Serializable; +import java.util.Collections; import java.util.Map; import java.util.Objects; import javax.persistence.Column; @@ -32,6 +33,11 @@ import org.keycloak.models.jpa.converter.MapStringConverter; @IdClass(RealmLocalizationTextsEntity.RealmLocalizationTextEntityKey.class) @Table(name = "REALM_LOCALIZATIONS") public class RealmLocalizationTextsEntity { + + // TODO: Remove this constant once the quarkus issue is fixed and use the @Convert annotation in the proper JPA way. Ideally see the github history and revert whole commit, + // which adds this "TODO" once the quarkus issue is fixed + private static final MapStringConverter MAP_STRING_CONVERTER = new MapStringConverter(); + static public class RealmLocalizationTextEntityKey implements Serializable { private String realmId; private String locale; @@ -76,15 +82,25 @@ public class RealmLocalizationTextsEntity { private String locale; @Column(name = "TEXTS") - @Convert(converter = MapStringConverter.class) - private Map texts; + private String texts; + // TODO: The @Convert does not work as expected on quarkus. It doesn't update the "texts" in case that updated map has same keys (but different values) as old map had +// @Convert(converter = MapStringConverter.class) +// private Map texts; public Map getTexts() { - return texts; + if (texts == null) { + return Collections.emptyMap(); + } else { + return Collections.unmodifiableMap(MAP_STRING_CONVERTER.convertToEntityAttribute(texts)); + } } public void setTexts(Map texts) { - this.texts = texts; + if (texts == null) { + this.texts = null; + } else { + this.texts = MAP_STRING_CONVERTER.convertToDatabaseColumn(texts); + } } public String getLocale() {