diff --git a/dotCMS/src/main/java/com/dotcms/config/DotInitializationService.java b/dotCMS/src/main/java/com/dotcms/config/DotInitializationService.java
index b4e7f5ac1e4c..1d9b4da3ab36 100644
--- a/dotCMS/src/main/java/com/dotcms/config/DotInitializationService.java
+++ b/dotCMS/src/main/java/com/dotcms/config/DotInitializationService.java
@@ -5,7 +5,10 @@
import com.dotcms.api.system.event.PayloadVerifierFactoryInitializer;
import com.dotcms.api.system.event.SystemEventProcessorFactoryInitializer;
import com.dotcms.business.SystemTableInitializer;
+import com.dotcms.cdi.CDIUtils;
import com.dotcms.contenttype.business.ContentTypeInitializer;
+import com.dotcms.contenttype.business.uniquefields.UniqueFieldValidationStrategyResolver;
+import com.dotcms.contenttype.business.uniquefields.extratable.UniqueFieldsTableCleanerInitializer;
import com.dotcms.rendering.velocity.events.ExceptionHandlersInitializer;
import com.dotcms.system.event.local.business.LocalSystemEventSubscribersInitializer;
import com.dotcms.util.ReflectionUtils;
@@ -132,6 +135,7 @@ private Set getInternalInitializers() {
new DefaultVariantInitializer(),
new SystemTableInitializer(),
new EmbeddingsInitializer(),
+ CDIUtils.getBeanThrows(UniqueFieldsTableCleanerInitializer.class),
new AnalyticsInitializer()
);
} // getInternalInitializers.
diff --git a/dotCMS/src/main/java/com/dotcms/content/elasticsearch/business/ESContentFactoryImpl.java b/dotCMS/src/main/java/com/dotcms/content/elasticsearch/business/ESContentFactoryImpl.java
index f1302003b92d..61de303f746e 100644
--- a/dotCMS/src/main/java/com/dotcms/content/elasticsearch/business/ESContentFactoryImpl.java
+++ b/dotCMS/src/main/java/com/dotcms/content/elasticsearch/business/ESContentFactoryImpl.java
@@ -622,8 +622,7 @@ protected void delete(List contentlets, boolean deleteIdentifier) th
}
if(verInfo.get().getWorkingInode().equals(contentlet.getInode()))
APILocator.getVersionableAPI()
- .deleteContentletVersionInfo(contentlet.getIdentifier(),
- contentlet.getLanguageId());
+ .deleteContentletVersionInfoByLanguage(contentlet);
}
delete(contentlet.getInode());
}
diff --git a/dotCMS/src/main/java/com/dotcms/contenttype/business/FieldAPIImpl.java b/dotCMS/src/main/java/com/dotcms/contenttype/business/FieldAPIImpl.java
index b507bfe83ff2..8825e97669e8 100644
--- a/dotCMS/src/main/java/com/dotcms/contenttype/business/FieldAPIImpl.java
+++ b/dotCMS/src/main/java/com/dotcms/contenttype/business/FieldAPIImpl.java
@@ -778,7 +778,7 @@ public void delete(final Field field, final User user) throws DotDataException,
}
CleanUpFieldReferencesJob.triggerCleanUpJob(field, user);
- localSystemEventsAPI.notify(new FieldDeletedEvent(field.variable()));
+ localSystemEventsAPI.notify(new FieldDeletedEvent(field));
}
diff --git a/dotCMS/src/main/java/com/dotcms/contenttype/business/uniquefields/UniqueFieldValidationStrategy.java b/dotCMS/src/main/java/com/dotcms/contenttype/business/uniquefields/UniqueFieldValidationStrategy.java
index 1c5363404a68..2dbead470238 100644
--- a/dotCMS/src/main/java/com/dotcms/contenttype/business/uniquefields/UniqueFieldValidationStrategy.java
+++ b/dotCMS/src/main/java/com/dotcms/contenttype/business/uniquefields/UniqueFieldValidationStrategy.java
@@ -4,6 +4,7 @@
import com.dotcms.contenttype.model.field.Field;
import com.dotcms.contenttype.model.type.ContentType;
import com.dotcms.util.DotPreconditions;
+import com.dotmarketing.beans.VersionInfo;
import com.dotmarketing.business.APILocator;
import com.dotmarketing.exception.DotDataException;
import com.dotmarketing.exception.DotSecurityException;
@@ -102,7 +103,6 @@ void innerValidate(final Contentlet contentlet, final Field field, final Object
default void afterSaved(final Contentlet contentlet, final boolean isNew) throws DotDataException, DotSecurityException {
// Default implementation does nothing
}
-
default void recalculate(final Field field, final boolean uniquePerSite) throws UniqueFieldValueDuplicatedException {
// Default implementation does nothing
}
@@ -120,4 +120,46 @@ default void validateField(final Field field) {
}
}
+ /**
+ * Clean the Extra unique validation field table after a {@link Contentlet} have been removed.
+ * We need to remove all the unique values of this {@link Contentlet} and {@link com.dotmarketing.portlets.languagesmanager.model.Language}
+ * from the extra table.
+ *
+ * @param contentlet
+ */
+ default void cleanUp(final Contentlet contentlet, final boolean deleteAllVariant) throws DotDataException {
+ //Default implementation do nothing
+ }
+
+ /**
+ * Method call after publish a {@link Contentlet} it allow the {@link UniqueFieldValidationStrategy} do any extra
+ * work that it need it.
+ *
+ * @param inode Published {@link Contentlet}'s inode
+ */
+ default void afterPublish(final String inode) {
+ //Default implementation do nothing
+ }
+
+ /**
+ * Method call after unpublished a {@link Contentlet} it allow thw {@link UniqueFieldValidationStrategy} do any extra
+ * work that it need it.
+ *
+ * @param versionInfo {@link Contentlet}'s {@link VersionInfo} before un publish
+ */
+ default void afterUnpublish(final VersionInfo versionInfo){
+ //Default implementation do nothing
+ }
+
+ /**
+ * Method called after delete a Unique {@link Field}, to allow the {@link UniqueFieldValidationStrategy} do any extra
+ * work that it need it.
+ *
+ * @param field deleted field
+ * @throws DotDataException
+ */
+ default void cleanUp(final Field field) throws DotDataException {
+ //Default implementation do nothing
+ }
+
}
diff --git a/dotCMS/src/main/java/com/dotcms/contenttype/business/uniquefields/extratable/DBUniqueFieldValidationStrategy.java b/dotCMS/src/main/java/com/dotcms/contenttype/business/uniquefields/extratable/DBUniqueFieldValidationStrategy.java
index 708d497a2859..cf37368e0f96 100644
--- a/dotCMS/src/main/java/com/dotcms/contenttype/business/uniquefields/extratable/DBUniqueFieldValidationStrategy.java
+++ b/dotCMS/src/main/java/com/dotcms/contenttype/business/uniquefields/extratable/DBUniqueFieldValidationStrategy.java
@@ -9,7 +9,9 @@
import com.dotcms.exception.ExceptionUtil;
import com.dotcms.util.JsonUtil;
import com.dotmarketing.beans.Host;
+import com.dotmarketing.beans.VersionInfo;
import com.dotmarketing.business.APILocator;
+import com.dotmarketing.business.DotStateException;
import com.dotmarketing.exception.DotDataException;
import com.dotmarketing.exception.DotRuntimeException;
import com.dotmarketing.exception.DotSecurityException;
@@ -78,6 +80,7 @@ public void innerValidate(final Contentlet contentlet, final Field field, final
.setContentType(contentType)
.setValue(fieldValue)
.setVariantName(contentlet.getVariantId())
+ .setLive(isLive(contentlet))
.build();
insertUniqueValue(uniqueFieldCriteria, contentlet.getIdentifier());
@@ -103,38 +106,41 @@ private static boolean isContentletBeingUpdated(final Contentlet contentlet) {
* is not re-generated as the Contentlet ID is not used in it.
*
* @param contentlet The {@link Contentlet} being updated.
- * @param field The {@link Field} representing the Unique Field.
*
* @throws DotDataException An error occurred when interacting with the database.
*/
@SuppressWarnings("unchecked")
- private void cleanUniqueFieldsUp(final Contentlet contentlet, final Field field) throws DotDataException {
- final Optional