diff --git a/core/src/main/resources/META-INF/persistence.xml b/core/src/main/resources/META-INF/persistence.xml
index 2c170d823..6d9401e46 100644
--- a/core/src/main/resources/META-INF/persistence.xml
+++ b/core/src/main/resources/META-INF/persistence.xml
@@ -25,17 +25,11 @@
google.registry.schema.domain.RegistryLock
google.registry.schema.tmch.ClaimsList
google.registry.schema.cursor.Cursor
- google.registry.model.transfer.BaseTransferObject
google.registry.schema.tld.PremiumList
google.registry.schema.tld.PremiumEntry
google.registry.schema.tld.ReservedList
google.registry.model.domain.secdns.DelegationSignerData
- google.registry.model.domain.DesignatedContact
- google.registry.model.domain.DomainBase
google.registry.model.domain.GracePeriod
- org.joda.time.Period
- google.registry.model.transfer.TransferData
- google.registry.model.eppcommon.Trid
google.registry.persistence.BloomFilterConverter
diff --git a/core/src/test/java/google/registry/persistence/PersistenceXmlTest.java b/core/src/test/java/google/registry/persistence/PersistenceXmlTest.java
new file mode 100644
index 000000000..b700729e4
--- /dev/null
+++ b/core/src/test/java/google/registry/persistence/PersistenceXmlTest.java
@@ -0,0 +1,67 @@
+// Copyright 2020 The Nomulus Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package google.registry.persistence;
+
+import static com.google.common.collect.ImmutableList.toImmutableList;
+import static com.google.common.collect.ImmutableSet.toImmutableSet;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.truth.Expect;
+import java.util.Collections;
+import javax.persistence.AttributeConverter;
+import javax.persistence.Entity;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Unit tests to verify persistence.xml is valid. */
+@RunWith(JUnit4.class)
+public class PersistenceXmlTest {
+
+ @ClassRule public static final Expect expect = Expect.create();
+
+ @Test
+ public void verifyClassTags_containOnlyRequiredClasses() {
+ ImmutableList managedClassed = PersistenceXmlUtility.getManagedClasses();
+
+ ImmutableList unnecessaryClasses =
+ managedClassed.stream()
+ .filter(
+ clazz ->
+ !clazz.isAnnotationPresent(Entity.class)
+ && !AttributeConverter.class.isAssignableFrom(clazz))
+ .collect(toImmutableList());
+
+ ImmutableSet duplicateClasses =
+ managedClassed.stream()
+ .filter(clazz -> Collections.frequency(managedClassed, clazz) > 1)
+ .collect(toImmutableSet());
+
+ expect
+ .withMessage("Found duplicate tags defined in persistence.xml.")
+ .that(duplicateClasses)
+ .isEmpty();
+
+ expect
+ .withMessage(
+ "Found unnecessary tags defined in persistence.xml. Only entity class and"
+ + " implementation of AttributeConverter are required to be added in"
+ + " persistence.xml.")
+ .that(unnecessaryClasses)
+ .isEmpty();
+ }
+}