<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
          http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"
    version="2.2">
  <persistence-unit name="nomulus" transaction-type="RESOURCE_LOCAL">
    <description>
      Persistence unit for the Nomulus Cloud SQL database.
    </description>
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

    <!--
      All JPA entity-mapping files and annotated classes must be enumerated
      here. Automatic entity detection is not part of the JPA spec. Explicit
      declaration makes it easier to migrate to another provider.

      Although Hibernate provides the auto detection functionality (configured by
      the hibernate.archive.autodetection property), it relies on a fragile
      scanner that can be broken by certain classes. For example, in the uber jar
      for the Nomulus tool, a repackaged Guava class ( {@code
      com.google.appengine.repackaged.com.google.common.html.LinkDetector})
      from appengine-api-1.0-sdk:1.9.81 can break the scanner in
      hibernate-core:5.4.17.Final. The large number of third-party classes also
      makes JPA setup noticeably slower in the tool.

      When auto detection is enabled in Hibernate, we also need a separate
      persistence.xml for tests. See <a
      href="https://stackoverflow.com/questions/61127082/hibernate-doesnt-find-entities-in-test">
      this webpage</a> for an example.

      Because of the reasons above, we disable auto detection in Hibernate.

      When auto detection is disabled, Hibernate still invokes the scanner which always
      goes over the archive that has this file. We need to override the default scanner
      with an NOOP one for Nomulus tool.
    -->

    <mapping-file>META-INF/orm.xml</mapping-file>

    <class>google.registry.model.billing.BillingEvent$Cancellation</class>
    <class>google.registry.model.billing.BillingEvent$OneTime</class>
    <class>google.registry.model.billing.BillingEvent$Recurring</class>
    <class>google.registry.model.common.Cursor</class>
    <class>google.registry.model.contact.ContactHistory</class>
    <class>google.registry.model.contact.ContactResource</class>
    <class>google.registry.model.domain.DomainBase</class>
    <class>google.registry.model.domain.DomainHistory</class>
    <class>google.registry.model.domain.GracePeriod</class>
    <class>google.registry.model.domain.GracePeriod$GracePeriodHistory</class>
    <class>google.registry.model.domain.secdns.DelegationSignerData</class>
    <class>google.registry.model.domain.secdns.DomainDsDataHistory</class>
    <class>google.registry.model.domain.token.AllocationToken</class>
    <class>google.registry.model.host.HostHistory</class>
    <class>google.registry.model.host.HostResource</class>
    <class>google.registry.model.poll.PollMessage</class>
    <class>google.registry.model.poll.PollMessage$OneTime</class>
    <class>google.registry.model.poll.PollMessage$Autorenew</class>
    <class>google.registry.model.rde.RdeRevision</class>
    <class>google.registry.model.registrar.Registrar</class>
    <class>google.registry.model.registrar.RegistrarContact</class>
    <class>google.registry.model.registry.label.PremiumList</class>
    <class>google.registry.model.registry.label.ReservedList</class>
    <class>google.registry.model.registry.label.ReservedList$ReservedListEntry</class>
    <class>google.registry.model.registry.Registry</class>
    <class>google.registry.model.reporting.DomainTransactionRecord</class>
    <class>google.registry.model.reporting.Spec11ThreatMatch</class>
    <class>google.registry.model.server.KmsSecretRevision</class>
    <class>google.registry.model.server.Lock</class>
    <class>google.registry.model.server.ServerSecret</class>
    <class>google.registry.model.smd.SignedMarkRevocationList</class>
    <class>google.registry.model.tmch.ClaimsList</class>
    <class>google.registry.model.tmch.ClaimsEntry</class>
    <class>google.registry.model.tmch.TmchCrl</class>
    <class>google.registry.persistence.transaction.TransactionEntity</class>
    <class>google.registry.schema.domain.RegistryLock</class>
    <class>google.registry.schema.replay.SqlReplayCheckpoint</class>
    <class>google.registry.schema.tld.PremiumEntry</class>

    <!-- Customized type converters -->
    <class>google.registry.persistence.converter.AllocationTokenStatusTransitionConverter</class>
    <class>google.registry.persistence.converter.BillingCostTransitionConverter</class>
    <class>google.registry.persistence.converter.BillingEventFlagSetConverter</class>
    <class>google.registry.persistence.converter.BloomFilterConverter</class>
    <class>google.registry.persistence.converter.CidrAddressBlockListConverter</class>
    <class>google.registry.persistence.converter.CreateAutoTimestampConverter</class>
    <class>google.registry.persistence.converter.CurrencyToBillingConverter</class>
    <class>google.registry.persistence.converter.CurrencyUnitConverter</class>
    <class>google.registry.persistence.converter.DateTimeConverter</class>
    <class>google.registry.persistence.converter.DurationConverter</class>
    <class>google.registry.persistence.converter.InetAddressSetConverter</class>
    <class>google.registry.persistence.converter.LocalDateConverter</class>
    <class>google.registry.persistence.converter.PostalInfoChoiceListConverter</class>
    <class>google.registry.persistence.converter.PremiumListKeyConverter</class>
    <class>google.registry.persistence.converter.RegistrarPocSetConverter</class>
    <class>google.registry.persistence.converter.ReservedListKeySetConverter</class>
    <class>google.registry.persistence.converter.Spec11ThreatMatchThreatTypeSetConverter</class>
    <class>google.registry.persistence.converter.StatusValueSetConverter</class>
    <class>google.registry.persistence.converter.StringListConverter</class>
    <class>google.registry.persistence.converter.StringSetConverter</class>
    <class>google.registry.persistence.converter.TldStateTransitionConverter</class>
    <class>google.registry.persistence.converter.TransferServerApproveEntitySetConverter</class>
    <class>google.registry.persistence.converter.ZonedDateTimeConverter</class>

    <!-- Generated converters for VKey -->
    <class>google.registry.model.billing.VKeyConverter_Cancellation</class>
    <class>google.registry.model.billing.VKeyConverter_Modification</class>
    <class>google.registry.model.billing.VKeyConverter_OneTime</class>
    <class>google.registry.model.billing.VKeyConverter_Recurring</class>
    <class>google.registry.model.contact.VKeyConverter_ContactResource</class>
    <class>google.registry.model.domain.VKeyConverter_DomainBase</class>
    <class>google.registry.model.domain.token.VKeyConverter_AllocationToken</class>
    <class>google.registry.model.host.VKeyConverter_HostResource</class>
    <class>google.registry.model.poll.VKeyConverter_Autorenew</class>
    <class>google.registry.model.poll.VKeyConverter_OneTime</class>

    <!-- TODO(weiminyu): check out application-layer validation. -->
    <validation-mode>NONE</validation-mode>
    <properties>
      <!-- Disables auto detection. -->
      <property name="hibernate.archive.autodetection" value=""/>
      <!-- NOOP scanner needed for Nomulus tool. -->
      <property name="hibernate.archive.scanner"
          value="google.registry.persistence.NoopJpaEntityScanner"/>
    </properties>
  </persistence-unit>
</persistence>
