public function insert($data, $validate_datatypes = false)
    {
        $prefixed_table = $this->prefixed_table;

        if ($data instanceof \ArrayObject) {
            $d = (array) $data;
        } elseif (is_array($data)) {
            $d = $data;
        } else {
            $type = gettype($data);
            throw new Exception\InvalidArgumentException(__METHOD__ . ": expects data to be array or ArrayObject. Type receive '$type'");
        }

        $this->checkDataColumns($d);

        if ($validate_datatypes) {
            $this->validateDatatypes($d);
        }

        $insert = $this->sql->insert($prefixed_table);
        $insert->values($d);

        $this->executeStatement($insert);

        $pks = $this->getPrimaryKeys();

        // Should never happen, as getPrimaryKeys throws Exception when no pk exists
        //@codeCoverageIgnoreStart
        if (!is_array($pks)) {
            $msg = __METHOD__ . " Error getting primary keys of table " . $this->table . ", require array, returned type is: " . gettype($pks) ;
            throw new Exception\UnexpectedValueException($msg);
        }
        //@codeCoverageIgnoreEnd

        $nb_pks = count($pks);
        if ($nb_pks > 1) {
            // In multiple keys there should not be autoincrement value
            $id = [];
            foreach ($pks as $pk) {
                $id[$pk] = $d[$pk];
            }
        } elseif (array_key_exists($pks[0], $d) && $d[$pks[0]] !== null) {
            // not using autogenerated value
            //$id = $d[$this->getPrimaryKey()];
            $id = $d[$pks[0]];
        } else {
            $id = $this->tableManager->getDbAdapter()->getDriver()->getLastGeneratedValue();
        }

        return $this->findOrFail($id);
    }