diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,9 @@
 ## Unreleased changes
 
+## 2.13.0.4
+
+* `aeson-2.0` support
+
 ## 2.13.0.3
 
 * Accidentally released 2.13.0.2 with some testing changes.
diff --git a/persistent-test.cabal b/persistent-test.cabal
--- a/persistent-test.cabal
+++ b/persistent-test.cabal
@@ -1,5 +1,5 @@
 name:            persistent-test
-version:         2.13.0.3
+version:         2.13.0.4
 license:         MIT
 license-file:    LICENSE
 author:          Michael Snoyman <michael@snoyman.com>
@@ -31,6 +31,7 @@
         Init
         LargeNumberTest
         MaxLenTest
+        MaybeFieldDefsTest
         MigrationColumnLengthTest
         MigrationIdempotencyTest
         MigrationOnlyTest
diff --git a/src/Init.hs b/src/Init.hs
--- a/src/Init.hs
+++ b/src/Init.hs
@@ -74,6 +74,7 @@
 import Data.Char (GeneralCategory(..), generalCategory)
 import Data.Fixed (Micro, Pico)
 import Data.Proxy
+import Data.String (IsString, fromString)
 import qualified Data.Text as T
 import Data.Time
 import Test.Hspec
@@ -213,9 +214,9 @@
       d' = max d $ fromGregorian 1950 1 1
   return $ UTCTime d' $ picosecondsToDiffTime picoi
 
-arbText :: Gen Text
+arbText :: IsString s => Gen s
 arbText =
-     T.pack
+     fromString
   .  filter ((`notElem` forbidden) . generalCategory)
   .  filter (<= '\xFFFF') -- only BMP
   .  filter (/= '\0')     -- no nulls
diff --git a/src/MaybeFieldDefsTest.hs b/src/MaybeFieldDefsTest.hs
new file mode 100644
--- /dev/null
+++ b/src/MaybeFieldDefsTest.hs
@@ -0,0 +1,26 @@
+{-# LANGUAGE DeriveAnyClass #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# OPTIONS_GHC -Wno-unused-top-binds #-}
+
+module MaybeFieldDefsTest (specsWith, maybeFieldDefMigrate) where
+
+import Data.String (IsString)
+
+import Init
+
+share [mkPersist sqlSettings { mpsGeneric = True },  mkMigrate "maybeFieldDefMigrate"] [persistLowerCase|
+  MaybeFieldDefEntity
+    optionalString    (Maybe String)
+    optionalInt       (Maybe Int)
+    deriving Eq Show
+|]
+
+specsWith :: (Runner backend m) => RunDb backend m -> Spec
+specsWith runDb = describe "Maybe Field Definitions" $ do
+  it "runs appropriate migrations" $ runDb $ do
+    emptyEntity <- insert $ MaybeFieldDefEntity Nothing Nothing
+    emptyResult <- get emptyEntity
+    liftIO $ emptyResult @?= Just (MaybeFieldDefEntity Nothing Nothing)
+    populatedEntity <- insert $ MaybeFieldDefEntity (Just "text") (Just 8)
+    populatedResult <- get populatedEntity
+    liftIO $ populatedResult @?= Just (MaybeFieldDefEntity (Just "text") (Just 8))
diff --git a/src/PersistentTest.hs b/src/PersistentTest.hs
--- a/src/PersistentTest.hs
+++ b/src/PersistentTest.hs
@@ -17,7 +17,6 @@
 import qualified Data.Conduit.List as CL
 import Data.Functor.Constant
 import Data.Functor.Identity
-import qualified Data.HashMap.Lazy as M
 import qualified Data.Map as Map
 import Data.Maybe (fromJust)
 import Test.Hspec.QuickCheck(prop)
@@ -632,7 +631,7 @@
       let p = Person "D" 0 Nothing
       k <- insert p
       liftIO $ toJSON (Entity k p) @?=
-        Object (M.fromList [("id", toJSON k), ("color",Null),("name",String "D"),("age",Number 0)])
+        object [("id", toJSON k), ("color",Null),("name",String "D"),("age",Number 0)]
 
 {- FIXME
     prop "fromJSON . toJSON $ key" $ \(person :: Key Person) ->
diff --git a/src/PersistentTestModels.hs b/src/PersistentTestModels.hs
--- a/src/PersistentTestModels.hs
+++ b/src/PersistentTestModels.hs
@@ -4,7 +4,7 @@
 {-# LANGUAGE UndecidableInstances #-} -- FIXME
 module PersistentTestModels where
 
-import Data.Aeson
+import Data.Aeson hiding (Key)
 
 import qualified Data.List.NonEmpty as NEL
 import Data.Proxy
@@ -239,3 +239,5 @@
   deleteWhere ([] :: [Filter (OutdoorPetGeneric backend)])
   deleteWhere ([] :: [Filter (UserPTGeneric backend)])
   deleteWhere ([] :: [Filter (EmailPTGeneric backend)])
+  deleteWhere ([] :: [Filter (UpsertGeneric backend)])
+  deleteWhere ([] :: [Filter (UpsertByGeneric backend)])
