## 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

addons/purchase/purchase.py
"""Return the base price of the line to be used for tax calculation.
        This function can be extended by other modules to modify this base
        price (adding a discount, for example).
        """
        return line.price_unit
    def _calc_line_quantity(self, cr, uid, line, context=None):
        """Return the base quantity of the line to be used for the subtotal.
        This function can be extended by other modules to modify this base
        quantity (adding for example offers 3x2 and so on).
        """
        return line.product_qty
    def _amount_line(self, cr, uid, ids, prop, arg, context=None):
        res = {}
        cur_obj=self.pool.get('res.currency')
        tax_obj = self.pool.get('account.tax')
        for line in self.browse(cr, uid, ids, context=context):
            line_price = self._calc_line_base_price(cr, uid, line,
                                                    context=context)
            line_qty = self._calc_line_quantity(cr, uid, line,
                                                context=context)
            taxes = tax_obj.compute_all(cr, uid, line.taxes_id, line_price,
                                        line_qty, line.product_id,
                                        line.order_id.partner_id)
            cur = line.order_id.pricelist_id.currency_id
            res[line.id] = cur_obj.round(cr, uid, cur, taxes['total'])
        return res
    def _get_uom_id(self, cr, uid, context=None):