private void validateValue(Object value) {
    // check validity of value against valueConstraint
    if (valueConstraint != null) {
      if (value != null) {
        if (value instanceof CachedDeserializable) {
          if (doExpensiveValidations) {
            value = ((CachedDeserializable) value).getDeserializedValue(null, null);
          } else {
            return;
          }
        }
        if (!valueConstraint.isInstance(value)) {
          String valueClassName = value.getClass().getName();
          // check for a REST object, which has a @type field denoting its class
          if (value instanceof PdxInstance) {
            PdxInstance pdx = (PdxInstance) value;
            if (pdx.getClassName().equals(JSONFormatter.JSON_CLASSNAME)) {
              Object type = pdx.getField("@type");
              if (type instanceof String) {
                valueClassName = (String) type;
              } else {
                return;
              }
            }
            if (valueClassName.equals(valueConstraint.getName())) {
              return;
            }
          }
          throw new ClassCastException(
              String.format("value ( %s ) does not satisfy valueConstraint ( %s )",
                  valueClassName, valueConstraint.getName()));
        }
      }
    }
  }
Starting in 3.5, we don't check to see if the value is {@code Serializable}. We instead rely on
the actual serialization (which happens in-thread with the put) to tell us if there are any
problems.
geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java