public function insert($dataOrModel, $tableName = null, HydratorInterface $hydrator = null)
    {
        $tableName = $tableName ?: $this->getTableName();
        $data = $this->extract($dataOrModel, $hydrator);

        if ($tableName === $this->getTableName()) {
            $data = $this->cleanData($data);
        }

        if ($tableName === $this->getTableName() && $this->findRow($this->dataToKeyData($data))) {
            throw new \RuntimeException('row already exists');
        }

        $sql = $this->getSql();
        $insert = $sql->insert($tableName);

        $insert->values($data);

        $statement = $sql->prepareStatementForSqlObject($insert);
        $result = $statement->execute();

        return $result->getGeneratedValue();
    }