diff --git a/core/src/main/java/google/registry/model/domain/DomainContent.java b/core/src/main/java/google/registry/model/domain/DomainContent.java
index d538a19b3..a395add00 100644
--- a/core/src/main/java/google/registry/model/domain/DomainContent.java
+++ b/core/src/main/java/google/registry/model/domain/DomainContent.java
@@ -24,6 +24,7 @@ import static com.google.common.collect.Sets.intersection;
import static google.registry.model.EppResourceUtils.projectResourceOntoBuilderAtTime;
import static google.registry.model.EppResourceUtils.setAutomaticTransferSuccessProperties;
import static google.registry.model.ofy.ObjectifyService.ofy;
+import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
import static google.registry.util.CollectionUtils.forceEmptyToNull;
import static google.registry.util.CollectionUtils.nullToEmpty;
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
@@ -378,6 +379,25 @@ public class DomainContent extends EppResource
}
}
+ /**
+ * Callback to delete grace periods and DelegationSignerData records prior to domain delete.
+ *
+ *
See {@link google.registry.schema.replay.ReplaySpecializer}.
+ */
+ public static void beforeSqlDelete(VKey key) {
+ // Delete all grace periods associated with the domain.
+ jpaTm()
+ .getEntityManager()
+ .createQuery("DELETE FROM GracePeriod WHERE domain_repo_id = :repo_id")
+ .setParameter("repo_id", key.getSqlKey())
+ .executeUpdate();
+ jpaTm()
+ .getEntityManager()
+ .createQuery("DELETE FROM DelegationSignerData WHERE domain_repo_id = :repo_id")
+ .setParameter("repo_id", key.getSqlKey())
+ .executeUpdate();
+ }
+
public static VKey restoreOfyFrom(Key domainKey, VKey key, Long historyId) {
if (historyId == null) {
// This is a legacy key (or a null key, in which case this works too)
diff --git a/core/src/test/java/google/registry/flows/domain/DomainTransferApproveFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainTransferApproveFlowTest.java
index 485c28a33..0bf31de3e 100644
--- a/core/src/test/java/google/registry/flows/domain/DomainTransferApproveFlowTest.java
+++ b/core/src/test/java/google/registry/flows/domain/DomainTransferApproveFlowTest.java
@@ -25,6 +25,7 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
import static google.registry.testing.DatabaseHelper.assertBillingEventsForResource;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.deleteResource;
+import static google.registry.testing.DatabaseHelper.getBillingEvents;
import static google.registry.testing.DatabaseHelper.getOnlyHistoryEntryOfType;
import static google.registry.testing.DatabaseHelper.getOnlyPollMessage;
import static google.registry.testing.DatabaseHelper.getPollMessages;
@@ -71,18 +72,25 @@ import google.registry.model.transfer.DomainTransferData;
import google.registry.model.transfer.TransferResponse.DomainTransferResponse;
import google.registry.model.transfer.TransferStatus;
import google.registry.persistence.VKey;
+import google.registry.testing.ReplayExtension;
import java.util.Arrays;
import java.util.stream.Stream;
import org.joda.money.Money;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
/** Unit tests for {@link DomainTransferApproveFlow}. */
class DomainTransferApproveFlowTest
extends DomainTransferFlowTestCase {
+ @Order(value = Order.DEFAULT - 2)
+ @RegisterExtension
+ final ReplayExtension replayExtension = ReplayExtension.createWithCompare(clock);
+
@BeforeEach
void setUp() {
setEppInput("domain_transfer_approve.xml");
@@ -521,7 +529,24 @@ class DomainTransferApproveFlowTest
@Test
void testFailure_nonexistentDomain() throws Exception {
- deleteResource(domain);
+ Iterable billingEvents = getBillingEvents();
+ Iterable historyEntries = tm().loadAllOf(HistoryEntry.class);
+ Iterable pollMessages = tm().loadAllOf(PollMessage.class);
+ tm().transact(
+ () -> {
+ deleteResource(domain);
+ for (BillingEvent event : billingEvents) {
+ deleteResource(event);
+ }
+ for (PollMessage pollMessage : pollMessages) {
+ deleteResource(pollMessage);
+ }
+ deleteResource(subordinateHost);
+ for (HistoryEntry hist : historyEntries) {
+ deleteResource(hist);
+ }
+ });
+
ResourceDoesNotExistException thrown =
assertThrows(
ResourceDoesNotExistException.class,
diff --git a/core/src/test/java/google/registry/testing/DatabaseHelper.java b/core/src/test/java/google/registry/testing/DatabaseHelper.java
index bc8c6958e..feed9ca31 100644
--- a/core/src/test/java/google/registry/testing/DatabaseHelper.java
+++ b/core/src/test/java/google/registry/testing/DatabaseHelper.java
@@ -766,7 +766,7 @@ public class DatabaseHelper {
return newRegistrars.build();
}
- private static Iterable getBillingEvents() {
+ public static Iterable getBillingEvents() {
return transactIfJpaTm(
() ->
Iterables.concat(
diff --git a/db/src/main/resources/sql/er_diagram/brief_er_diagram.html b/db/src/main/resources/sql/er_diagram/brief_er_diagram.html
index 5b814152e..4dbd103de 100644
--- a/db/src/main/resources/sql/er_diagram/brief_er_diagram.html
+++ b/db/src/main/resources/sql/er_diagram/brief_er_diagram.html
@@ -261,11 +261,11 @@ td.section {
generated on |
- 2021-02-25 19:33:39.25711 |
+ 2021-03-04 16:08:40.773463 |
last flyway file |
- V86__third_poll_message.sql |
+ V87__fix_super_domain_fk.sql |
@@ -274,19 +274,19 @@ td.section {