Assign datablock to custom property
You can't. See the wiki page: Properties, ID-Properties and their differences.


+--------------------------------------------------------------------------------------+
|           |             Property             |        Property        | ID-Property  |
|           |             (static)             |       (dynamic)        |              |
|-----------+----------------------------------+------------------------+--------------|
| Creation  |      bpy.types.Object.foo =      | bpy.types.Object.foo = | ob["foo"] =  |
|           |    bpy.props.StringProperty()    |     property(bar)      |    "bar"     |
|-----------+----------------------------------+------------------------+--------------|
| Declared  |   all datablocks of same type    | all datablocks of same |    single    |
|    for    |                                  |          type          |  datablock   |
|-----------+----------------------------------+------------------------+--------------|
| Assigning |          ob.foo = "bar"          |     ob.foo = "bar"     | ob["foo"] =  |
|  values   |                                  |                        |    "bar"     |
|-----------+----------------------------------+------------------------+--------------|
|           |                                  |                        |   Floats,    |
| Accepted  |           Any property           |       Functions        |  integers,   |
|  values   |                                  |                        |   lists*,    |
|           |                                  |                        |   strings    |
|-----------+----------------------------------+------------------------+--------------|
| Stored in |              Yes**               |           No           |     Yes      |
|  .blend   |                                  |                        |              |
+--------------------------------------------------------------------------------------+

  
  * List may only contain floats and integers.
  ** Datablocks that have a value assigned to the property, save that value as an ID-property.


You could instead store a pickled list of material names, e.g.

import pickle
import bpy

def fget(self):
    try:
        for name in pickle.loads(self["_interaction_materials"]):
            yield bpy.data.materials[name]
    except KeyError:
        raise StopIteration

def fset(self, materials):
    self["_interaction_materials"] = pickle.dumps([m.name for m in materials])

bpy.types.Object.interaction_materials = property(fget, fset)