Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

> 0.10.2: error[E0119]: conflicting implementations of trait #1287

Closed
frederikhors opened this issue Dec 6, 2022 · 10 comments · Fixed by #1298
Closed

> 0.10.2: error[E0119]: conflicting implementations of trait #1287

frederikhors opened this issue Dec 6, 2022 · 10 comments · Fixed by #1298
Assignees

Comments

@frederikhors
Copy link
Contributor

Description

Using unfortunately on a new PC the new sea-orm-cli@0.10.5 instead of 0.10.2 I get the below error with the same PG schema.

I cannot publish code because of NDA.

Actual Behavior

It gives this error after generation:

error[E0119]: conflicting implementations of trait `sea_orm::Related<generated::tenant::Entity>` for type `generated::player::Entity`
   |
63 | impl Related<super::tenant::Entity> for Entity {
   | ---------------------------------------------- first implementation here
...
69 | impl Related<super::tenant::Entity> for Entity {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `generated::player::Entity`

Versions

Ôöé   Ôöé   Ôö£ÔöÇÔöÇ sea-orm v0.10.5
Ôöé   Ôöé   Ôöé   Ôö£ÔöÇÔöÇ sea-orm-macros v0.10.5 (proc-macro)
Ôöé   Ôöé   Ôöé   Ôö£ÔöÇÔöÇ sea-query v0.27.2
Ôöé   Ôöé   Ôöé   Ôöé   Ôö£ÔöÇÔöÇ sea-query-derive v0.2.0 (proc-macro)
Ôöé   Ôöé   Ôöé   Ôö£ÔöÇÔöÇ sea-query-binder v0.2.2
Ôöé   Ôöé   Ôöé   Ôöé   Ôö£ÔöÇÔöÇ sea-query v0.27.2 (*)
Ôöé   Ôöé   Ôöé   Ôö£ÔöÇÔöÇ sea-strum v0.23.0
Ôöé   Ôöé   Ôöé   Ôöé   ÔööÔöÇÔöÇ sea-strum_macros v0.23.0 (proc-macro)
Ôöé   Ôöé   ÔööÔöÇÔöÇ sea-orm v0.10.5 (*)
Ôöé   Ôöé   Ôö£ÔöÇÔöÇ sea-orm v0.10.5 (*)
Ôöé   Ôö£ÔöÇÔöÇ sea-orm v0.10.5 (*)
@frederikhors frederikhors changed the title > 0.10.2 : error[E0119]: conflicting implementations of trait > 0.10.2: error[E0119]: conflicting implementations of trait Dec 6, 2022
@billy1624
Copy link
Member

Hey @frederikhors, thanks for the reporting!! I want to understand the situation before formulating the solution.

image

I guess the schema is similar to above?

There are two paths between cake and baker

  • cake <-> baker
  • cake <-> cake_bakers <-> baker

cake entity file:

use sea_orm::entity::prelude::*;

#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "cake")]
pub struct Model {
    #[sea_orm(primary_key)]
    pub id: i32,
    pub name: String,
    #[sea_orm(column_type = "Decimal(Some((19, 4)))")]
    pub price: Decimal,
    pub bakery_id: Option<i32>,
    pub gluten_free: bool,
    pub serial: Uuid,
    pub recipe_author: Option<i32>,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
    #[sea_orm(
        belongs_to = "super::baker::Entity",
        from = "Column::RecipeAuthor",
        to = "super::baker::Column::Id",
        on_update = "NoAction",
        on_delete = "NoAction"
    )]
    Baker,
    #[sea_orm(
        belongs_to = "super::bakery::Entity",
        from = "Column::BakeryId",
        to = "super::bakery::Column::Id",
        on_update = "NoAction",
        on_delete = "NoAction"
    )]
    Bakery,
    #[sea_orm(has_many = "super::lineitem::Entity")]
    Lineitem,
}

impl Related<super::bakery::Entity> for Entity {
    fn to() -> RelationDef {
        Relation::Bakery.def()
    }
}

impl Related<super::lineitem::Entity> for Entity {
    fn to() -> RelationDef {
        Relation::Lineitem.def()
    }
}

impl Related<super::baker::Entity> for Entity { // Conflicting implementation!!
    fn to() -> RelationDef {
        Relation::Baker.def()
    }
}

impl Related<super::baker::Entity> for Entity { // Conflicting implementation!!
    fn to() -> RelationDef {
        super::cakes_bakers::Relation::Baker.def()
    }
    fn via() -> Option<RelationDef> {
        Some(super::cakes_bakers::Relation::Cake.def().rev())
    }
}

impl ActiveModelBehavior for ActiveModel {}

baker entity file:

use sea_orm::entity::prelude::*;

#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "baker")]
pub struct Model {
    #[sea_orm(primary_key)]
    pub id: i32,
    pub name: String,
    pub contact_details: Json,
    pub bakery_id: Option<i32>,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
    #[sea_orm(
        belongs_to = "super::bakery::Entity",
        from = "Column::BakeryId",
        to = "super::bakery::Column::Id",
        on_update = "Cascade",
        on_delete = "Cascade"
    )]
    Bakery,
    #[sea_orm(has_many = "super::cake::Entity")]
    Cake,
}

impl Related<super::bakery::Entity> for Entity {
    fn to() -> RelationDef {
        Relation::Bakery.def()
    }
}

impl Related<super::cake::Entity> for Entity { // Conflicting implementation!!
    fn to() -> RelationDef {
        Relation::Cake.def()
    }
}

impl Related<super::cake::Entity> for Entity { // Conflicting implementation!!
    fn to() -> RelationDef {
        super::cakes_bakers::Relation::Cake.def()
    }
    fn via() -> Option<RelationDef> {
        Some(super::cakes_bakers::Relation::Baker.def().rev())
    }
}

impl ActiveModelBehavior for ActiveModel {}

@frederikhors
Copy link
Contributor Author

frederikhors commented Dec 7, 2022

Yeah. I think the issue is because we have tenant_id column on both tables. And sea-orm-cli goes crazy about it! 😄

@TurtIeSocks
Copy link

I think I'm seeing something similar on 0.10.*.

I was previously using 0.9.0 without issue.

error[E0119]: conflicting implementations of trait `std::fmt::Display` for type `sea_orm_active_enums::Type`
 --> entity/src/sea_orm_active_enums.rs:7:53
  |
7 |     Debug, Display, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, Deserialize, Serialize,
  |            ------- first implementation here        ^^^^^^^^^^^^^^^^ conflicting implementation for `sea_orm_active_enums::Type`
  |
  = note: this error originates in the derive macro `DeriveActiveEnum` (in Nightly builds, run with -Z macro-backtrace for more info)

Imports and macro for the file in question:

use sea_orm::{entity::prelude::*, strum::Display};
use serde::{Deserialize, Serialize};

#[derive(
    Debug, Display, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, Deserialize, Serialize,
)]

Downgrading to 0.9.3 solves the issue. Let me know if you'd like me to open a separate issue @billy1624.

@frederikhors
Copy link
Contributor Author

I think this is not the same.

@clay07g
Copy link

clay07g commented Dec 8, 2022

I was talking about this in the discord a bit.

The generator seems to generate all relations as Related functions without considering multiple relationships between two entities.

You can manually code the solution to this with, I believe, Chained Relations, so in the example could do:

// cake.rs
// ....


pub struct CakeBakersLink;

impl Linked for CakeBakersLink {
    type FromEntity = Entity;

    type ToEntity = cake_bakers::Entity;

    fn link(&self) -> Vec<RelationDef> {
        vec![
            cake_bakers::Relation::Cakes.def().rev(),
            cake_bakers::Relation::Bakers.def(),
        ]
    }
}

So the default relationship from Cake will give you its recipe author. To get its bakers, you use CakeBakersLink. You can also ditch the Relation function entirely and also make the recipe author relationship a chained one, too, so that it's more clear.

Short term maybe the generator should generate Linked structs for secondary relationships for entities.

And long term, maybe make it customizable for how the user wants to handle relationships. For example, I think I'd like the ability to generate all relationships as Linked instead of Related, except for linking tables like cake_bakers. I like chained relationships because the Linked struct can be named to give context. Cake::find().also_find_related(Baker) is less intuitive to me than Cake::find().also_find_linked(RecipeAuthorBakerLink) (which can be generated based on column name).

@billy1624
Copy link
Member

billy1624 commented Dec 8, 2022

Hey @TurtIeSocks, the problem you mention isn't related to this issue.

In sea-orm 0.10.x, DeriveActiveEnum implement Display trait for you. So, you don't need to derive or implement it on your own.

#1255

@billy1624
Copy link
Member

Hey everyone, thanks for the input! I've created #1298 which will skip the implementation of

impl Related<super::baker::Entity> for Entity {
    fn to() -> RelationDef {
        Relation::Baker.def()
    }
}

While keeping this

impl Related<super::baker::Entity> for Entity {
    fn to() -> RelationDef {
        super::cakes_bakers::Relation::Baker.def()
    }
    fn via() -> Option<RelationDef> {
        Some(super::cakes_bakers::Relation::Cake.def().rev())
    }
}

@frederikhors
Copy link
Contributor Author

Hey everyone, thanks for the input! I've created #1298 which will skip the implementation of

impl Related<super::baker::Entity> for Entity {
    fn to() -> RelationDef {
        Relation::Baker.def()
    }
}

While keeping this

impl Related<super::baker::Entity> for Entity {
    fn to() -> RelationDef {
        super::cakes_bakers::Relation::Baker.def()
    }
    fn via() -> Option<RelationDef> {
        Some(super::cakes_bakers::Relation::Cake.def().rev())
    }
}

Can you release this ASAP?

@billy1624
Copy link
Member

I'll publish it tomorrow morning

@billy1624
Copy link
Member

sea-orm-cli 0.10.6 has been published
https://crates.io/crates/sea-orm-cli/0.10.6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants