nhibernate / nhibernate-core

NHibernate Object Relational Mapper
https://nhibernate.info
GNU Lesser General Public License v2.1
2.13k stars 931 forks source link

Postgres wrong data type/s #2974

Closed aetasoul closed 2 years ago

aetasoul commented 2 years ago

Hi, I'm using Postgresql as database, the tables were manually generated.

------- TABLE AUTHOR -------
CREATE TABLE author (
    id bigint NOT NULL,
    name character varying(50)
);
ALTER TABLE author OWNER TO myuser;

CREATE SEQUENCE author_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1;
ALTER TABLE author_id_seq OWNER TO myuser;
ALTER SEQUENCE author_id_seq OWNED BY author.id;
ALTER TABLE ONLY author ALTER COLUMN id SET DEFAULT nextval('author_id_seq'::regclass);
ALTER TABLE ONLY author ADD CONSTRAINT author_pkey PRIMARY KEY (id);

------- TABLE BOOK -------
CREATE TABLE book (
    id bigint NOT NULL,
    author_id bigint NOT NULL,
    title character varying(100)
);
ALTER TABLE book OWNER TO myuser;

CREATE SEQUENCE book_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1;
ALTER TABLE book_id_seq OWNER TO myuser;
ALTER SEQUENCE book_id_seq OWNED BY book.id;
ALTER TABLE ONLY book ALTER COLUMN id SET DEFAULT nextval('book_id_seq'::regclass);
ALTER TABLE ONLY book ADD CONSTRAINT fko5rb7l9pwc20t4465iphn69wt FOREIGN KEY (author_id) REFERENCES author(id);
ALTER TABLE ONLY book ADD CONSTRAINT book_pkey PRIMARY KEY (id);

Classes

public class AuthorClass
{
    public virtual long Id { get; protected set; }
    public IList<BookClass> Books { get; set; }
    public virtual string Name { get; set; }
}

public class BookClass
{
    public virtual long Id { get; protected set; }
    public AuthorClass Author { get; set; }
    public virtual string Title { get; set; }
}

Mappings

public class AuthorMap : ClassMap<AuthorClass>
{
    public AuthorMap()
    {
        Table("author");

        Id(x => x.Id).Column("id").CustomSqlType("bigint").GeneratedBy.SequenceIdentity("author_id_seq");
        Map(x => x.Name).Column("name").CustomSqlType("character varying(50)");
    }
}

public class BookMap : ClassMap<BookClass>
{
    public BookMap()
    {
        Table("book");

        Id(x => x.Id).Column("id").CustomSqlType("bigint").GeneratedBy.SequenceIdentity("book_id_seq");
        References(x => x.Author).Column("author_id").Cascade.All().Not.Nullable();
        Map(x => x.Title).Column("title").CustomSqlType("character varying(100)");
    }
}

Code

ISessionFactory _sessionFactory = Fluently.Configure()
.Database(PostgreSQLConfiguration.Standard.ConnectionString("Server=localhost;Port=5432;Database=MyDatabase;User Id=myuser;Password=mypassword;"))
.Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.GetExecutingAssembly()))
.ExposeConfiguration(config =>
{
  SchemaValidator schemaValidator = new SchemaValidator(config);
  schemaValidator.Validate();
})
.BuildSessionFactory();

The schema validation generate an Exception, checking the ValidationErrors array:

- ValidationErrors  Count = 1   System.Collections.ObjectModel.ReadOnlyCollection<string>
    [0] "Wrong column type in MyDatabase.public.book for column author_id. Found: bigint, Expected int8" string

Changing the Mappings without .CustomSqlType:

public class AuthorMap : ClassMap<AuthorClass>
{
    public AuthorMap()
    {
        Table("author");

        Id(x => x.Id).Column("id").GeneratedBy.SequenceIdentity("author_id_seq");
        Map(x => x.Name).Column("name");
    }
}

public class BookMap : ClassMap<BookClass>
{
    public BookMap()
    {
        Table("book");

        Id(x => x.Id).Column("id").GeneratedBy.SequenceIdentity("book_id_seq");
        References(x => x.Author).Column("author_id").Cascade.All().Not.Nullable();
        Map(x => x.Title).Column("title");
    }
}

The schema validation generate an Exception for each data type, checking the ValidationErrors array:

-   ValidationErrors    Count = 5   System.Collections.ObjectModel.ReadOnlyCollection<string>
    [0] "Wrong column type in MyDatabase.public.author for column id. Found: bigint, Expected int8" string
    [1] "Wrong column type in MyDatabase.public.author for column name. Found: character varying, Expected varchar(255)"    string
    [2] "Wrong column type in MyDatabase.public.book for column id. Found: bigint, Expected int8"   string
    [3] "Wrong column type in MyDatabase.public.book for column author_id. Found: bigint, Expected int8"    string
    [4] "Wrong column type in MyDatabase.public.book for column title. Found: character varying, Expected varchar(255)" string

Changing the version of the Npgsql to 4.1.10 all works correctly, would you fix this?

fredericDelaporte commented 2 years ago

Duplicate of #2876 or #1895, according to viewpoint.