Vinelab / NeoEloquent

The Neo4j OGM for Laravel
MIT License
635 stars 200 forks source link

Error connection is of instance MysqlConnection and should be NeoEloquent Connection #159

Closed niko-n closed 8 years ago

niko-n commented 8 years ago

Hi,

I'm trying to run NeoEloquent in Laravel (Homestead). After following the installation procedure, I get this error:

FatalThrowableError in Builder.php line 79: Type error: Argument 1 passed to Vinelab\NeoEloquent\Query\Builder::__construct() must be an instance of Vinelab\NeoEloquent\Connection, instance of Illuminate\Database\MySqlConnection given, called in /home/vagrant/code/mailmine-laravel/vendor/vinelab/neoeloquent/src/Vinelab/NeoEloquent/Eloquent/Model.php on line 73

Any idea ?

Many thanks !

ctorresr commented 8 years ago

This seems that your configuration environment is wrong. Are you using 2 DB's? I have configured up to 3 DB's without problems.

niko-n commented 8 years ago

Thanks @ctorresr, we fixed the issue. Our default connection is set to mysql, causing the issue: 'default' => env('DB_CONNECTION', 'mysql')

We solved it by defining the neo4j connection inside the model class:

class User extends NeoEloquent { protected $connection = 'neo4j'; ... }

martinhschei commented 6 years ago

i'm having the same issue.

in config\database.php i have this in the connections array

'neo4j' => [
             'driver' => 'neo4j',
             'host'   => env('NEO4J_HOST', 'localhost'),
             'port'   => env('NEO4J_PORT', '7474'),
             'username' => env('NEO4J_USERNAME', 'xxxxx'),
             'password' => env('NEO4J_PASSWORD', 'xxxxx'),
        ]

.env i have this for neo4j:

NEO4J_CONNECTION=neo4j
NEO4J_HOST=127.0.0.1
NEO4J_PORT=7474
NEO4J_USERNAME=xxxxx
NEO4J_PASSWORD=xxxxx

and the default connection is mysql (which works fine): 'default' => env('DB_CONNECTION', 'mysql'),

in the model i try to save:

namespace App;

use Vinelab\NeoEloquent\Eloquent\Model as NeoEloquent;

class myClass extends NeoEloquent  {

    protected $connection = 'neo4j';

the error i get: Type error: Argument 1 passed to Vinelab\NeoEloquent\Query\Builder::__construct() must be an instance of Vinelab\NeoEloquent\Connection, instance of Illuminate\Database\MySqlConnection given, called in /home/vagrant/projects/xxxxxxxxxxx/vendor/vinelab/neoeloquent/src/Eloquent/Model.php on line 75

any suggestions for what i could have done wrong?

DeltaBravo commented 6 years ago

I am in way over my head trying to debug this issue however my entire app is broken until this is resolved so I must try.

This issue showed up after I moved from Laravel 5.3 to 5.4.

I think the issue is related to "The Model::create...[method has] been moved to the Illuminate\Database\Eloquent\Builder". (see https://laravel.com/docs/5.4/upgrade section "The create & forceCreate Methods".

It seems that create() is working up until save() is called. At this point Illuminate\Database\Eloquent\Model->resolveConnection() is receiving null rather than the $connection property of the model and so is defaulting to env('DB_CONNECTION').

DeltaBravo commented 6 years ago

Solved? Edit config/database.php and add: ['connections' => ['neo4j' => ['name' => 'neo4j']]]

At some point in creating a new instance of a model Vinelab\NeoEloquent\Eloquent\Builder->create() calls Illuminate\Database\Eloquent\Builder->newModelInstance() which calls $this->query->getConnection()->getName() (which is Illuminate\Database\Connection->getName()) which looks in config/database.php for 'neo4j' => ['name'].

Not sure if this solution is the correct one but if it is perhaps it should be documented. https://github.com/Vinelab/NeoEloquent#configuration

Should also expand this section of the documentation as it suggests that NeoEloquent must be the default database which is not true.

Awlexus commented 6 years ago

Have you found a solution for this? I'm having the same problem and none of the solutions so far helped

DeltaBravo commented 6 years ago

My short-term solution was:

Edit config/database.php and add: ['connections' => ['neo4j' => ['name' => 'neo4j']]]

My long term solution is much more drastic. I am working towards abandoning Eloquent and thereby NeoEloquent altogether. I know this is not really a solution for most but I personally see little value in ORMs especially with a graph database. Having developers understand the database is a good thing imo although I recognise this approach is less feasible at scale (think massive databases with DB analysts and developers being separate people/groups).

Awlexus commented 6 years ago

The short-term solution, unfortunately, didn't solve my problem. I haven't even set up anything with NeoEloquent because I've never gotten any further.

Unfortunately, I don't really want to apply the long-term solution either because I'm already working in an unfamiliar environment.

martinhschei commented 6 years ago

I solved it by adding this line on my models: public function getConnectionName() { return 'neo4j'; // or whatever you call it in your setup }

buonzz commented 6 years ago

none of the above solution worked for me, the quick and dirty patch i end up with is:



use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateClusterTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        \DB::connection('neo4j')->statement("CREATE INDEX ON :Cluster(name)");
        \DB::connection('neo4j')->statement("CREATE INDEX ON :Cluster(code)");
        \DB::connection('neo4j')->statement("CREATE CONSTRAINT ON (n:Cluster) ASSERT n.code IS UNIQUE");
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
       \DB::connection('neo4j')->statement("MATCH (n:Cluster) DELETE n"); 
    }
}```