Fixed #2395
diff --git a/release-notes/CREDITS-2.x b/release-notes/CREDITS-2.x
index 8ee09a0..edff566 100644
--- a/release-notes/CREDITS-2.x
+++ b/release-notes/CREDITS-2.x
@@ -850,3 +850,8 @@
 Edgar Asatryan (nstdio@github)
   * Reported #2374: `ObjectMapper. getRegisteredModuleIds()` throws NPE if no modules registered
    (2.9.9.1)
+
+Michael Simons (michael-simons@github)
+  * Reported #2395: `NullPointerException` from `ResolvedRecursiveType` (regression due to
+    fix for #2331)
+   (2.9.9.3)
diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x
index c36cddd..c6e0ec4 100644
--- a/release-notes/VERSION-2.x
+++ b/release-notes/VERSION-2.x
@@ -4,6 +4,11 @@
 === Releases === 
 ------------------------------------------------------------------------
 
+2.9.9.3 (not yet released)
+
+#2395: `NullPointerException` from `ResolvedRecursiveType` (regression due to fix for #2331)
+ (reported by Michael S)
+
 2.9.9.2 (27-Jul-2019)
 
 #2331: `JsonMappingException` through nested getter with generic wildcard return type
diff --git a/src/main/java/com/fasterxml/jackson/databind/type/ResolvedRecursiveType.java b/src/main/java/com/fasterxml/jackson/databind/type/ResolvedRecursiveType.java
index 7a69744..ae0e884 100644
--- a/src/main/java/com/fasterxml/jackson/databind/type/ResolvedRecursiveType.java
+++ b/src/main/java/com/fasterxml/jackson/databind/type/ResolvedRecursiveType.java
@@ -39,16 +39,25 @@
     // 23-Jul-2019, tatu: [databind#2331] Need to also delegate this...
     @Override
     public TypeBindings getBindings() {
-        return _referencedType.getBindings();
+        if (_referencedType != null) { // `null` before resolution [databind#2395]
+            return _referencedType.getBindings();
+        }
+        return super.getBindings();
     }
 
     @Override
     public StringBuilder getGenericSignature(StringBuilder sb) {
+        if (_referencedType != null) {
+            return _referencedType.getGenericSignature(sb);
+        }
         return _referencedType.getGenericSignature(sb);
     }
 
     @Override
     public StringBuilder getErasedSignature(StringBuilder sb) {
+        if (_referencedType != null) {
+            return _referencedType.getErasedSignature(sb);
+        }
         return _referencedType.getErasedSignature(sb);
     }
 
diff --git a/src/main/java/com/fasterxml/jackson/databind/type/TypeFactory.java b/src/main/java/com/fasterxml/jackson/databind/type/TypeFactory.java
index b50018d..afe787f 100644
--- a/src/main/java/com/fasterxml/jackson/databind/type/TypeFactory.java
+++ b/src/main/java/com/fasterxml/jackson/databind/type/TypeFactory.java
@@ -182,7 +182,11 @@
             typeCache = null;
         } else if (_modifiers == null) {
             mods = new TypeModifier[] { mod };
+            // 29-Jul-2019, tatu: Actually I think we better clear cache in this case
+            //    as well to ensure no leakage occurs (see [databind#2395])
+            typeCache = null;
         } else {
+            // but may keep existing cache otherwise
             mods = ArrayBuilders.insertInListNoDup(_modifiers, mod);
         }
         return new TypeFactory(typeCache, _parser, mods, _classLoader);