## Impacted versions:
 8.0 / 9.0 / 10.0
## Steps to reproduce:
* see https://github.com/odoo/odoo/issues/11841
* in a shell
  1. create an in memory record `order = self.env['purcahse.order'].new({....})`
  2. create an in memory record with a reference to the first one `order_line = self.env['purchase.order.line'].new({'order_id': order, ....})`
  3. order_line.order_id is an in memory recordset
  4. create a record for a model that inherits from mail.thread `self.env['product.product'].create({....})`
  5. At this stage order_line.order_id is an empty recordset

## Current behavior:
 In memory records are dropped when a call is done to self.invalidate_cache
## Expected behavior:
In memory records are preserved when a call is done to self.invalidate_cache


There are lot of places where the method `invalidate_cache` is called and the silent removal of the in memory records from all environments has unpredictable effects on fields modified by a computed method or an onchange or even related fields .... Moreover since all caches are invalidated each time you create / write / unlink  (https://github.com/odoo/odoo/blob/10.0/addons/mail/models/mail_followers.py#L111) an instance of a model that inherits from 'mail.thread', the performances of the server are severely penalized.

OPW703903

'''PO is done at the delivery side if all the incoming shipments are done'''
        for purchase in self.browse(cr, uid, ids, context=context):
            for picking in purchase.picking_ids:
                if picking.state != 'done':
                    return False
        return True
    def test_moves_except(self, cr, uid, ids, context=None):
        ''' PO is in exception at the delivery side if one of the picking is canceled
            and the other pickings are completed (done or canceled)
        '''
        at_least_one_canceled = False
        alldoneorcancel = True
        for purchase in self.browse(cr, uid, ids, context=context):
            for picking in purchase.picking_ids:
                if picking.state == 'cancel':
                    at_least_one_canceled = True
                if picking.state not in ['done', 'cancel']:
                    alldoneorcancel = False
        return at_least_one_canceled and alldoneorcancel
    def move_lines_get(self, cr, uid, ids, *args):