Question

I´m having some trouble mapping a Dictionary with Nhibernate Map By Code. I`m trying to make my classes Multilingual. So for that i made a Dictionary which safes for each LanguageCode the appropriate _i18n LanguageClass.

Mapping seemed to work, but if I want to get a Product with its Language Dictionary it is always null and I don't know why.

Here is my code:

public class Product
{
    public virtual String ArticleNumber { get; set; }

    public virtual Dictionary<String, Product_i18n> Languages { get; set; }
}

    public class Product_i18n
{
    public virtual long Id { get; set; }
    public virtual Product Product { get; set; }
    public virtual String LanguageCode { get; set; }

    public virtual String Name { get; set; }
}

Here is the mapping:

    class ProductMap : ClassMapping<Product>
{
    public ProductMap()
    {
        Lazy(true);
        // Sets Tablename
        Table("Prodcut");

        // primary key
        Id(product => product.ArticleNumber, mapping =>
                                                 {
                                                           mapping.Column("ArticleNumber");
                                                     mapping.Generator(Generators.Native);
                                                 });

        Map<string, Product_i18n>(
            product => product.Languages,
            mapping =>
                {
                },
            mapkey =>
                {
                    mapkey.Element(k =>
                                       {
                                           k.Column("LanguageCode");
                                       });
                }, 
            mapvalue =>
                {
                    mapvalue.OneToMany();
                });
    }
}
class Product_i18n_Map : ClassMapping<Product_i18n>
{
    public Product_i18n_Map()
    {
        /*ComposedId(mapper =>
                    {
                        mapper.Property(n => n.Product);
                        mapper.Property(n => n.LanguageCode);
                    });
         * */
        Table("Product_i18n");
        Id(n => n.Id, mapper =>
                          {
                              mapper.Column("Product_i18nId");
                              mapper.Generator(Generators.Native);
                          });

        Property(n => n.LanguageCode, mapping =>
                                          {
                                              mapping.Column("LanguageCode");
                                          });

        ManyToOne(n => n.Product, mapping =>
                                      {
                                          mapping.Column("Product");
                                      });
        Property(n => n.Name);
    }
}

And thats my main function to get information:

        Configuration config = new Configuration();
        config.SessionFactory().GenerateStatistics();
        config.DataBaseIntegration(Configure);

        ModelMapper mapper = new ModelMapper();
        mapper.AddMapping<Product_i18n_Map>();
        mapper.AddMapping<ProductMap>();

        config.AddMapping(mapper.CompileMappingForAllExplicitlyAddedEntities());

        var lines = config.GenerateSchemaCreationScript(new MsSql2008Dialect());

        foreach (var curLine in lines)
            Console.WriteLine(curLine);

        Console.WriteLine(Thread.CurrentThread.CurrentUICulture.IetfLanguageTag);

        ISessionFactory factory = config.BuildSessionFactory();
        using (ISession session = factory.OpenSession())
        {
            Product p1 = new Product() { ArticleNumber = "4711" };
            session.Save(p1);

            Product_i18n p1ger = new Product_i18n() { LanguageCode = "de-DE", Name = "Playstation", Product = p1 };
            Product_i18n p1jap = new Product_i18n() { LanguageCode = "JP", Name = "プレイステーション", Product = p1 };
            session.Save(p1ger);
            session.Save(p1jap);

            var query = session.QueryOver<Product>().List();
            var query2 = session.QueryOver<Product_i18n>().List();

            session.Close();
        }
Was it helpful?

Solution

The problem is actually your test - you create a new Product (p1) and attach it to the session by calling Save, which will associate p1 with the session, so anytime you retrieve that product from the same session, it will return the same instance. This means that when you do session.QueryOver().List(), that list will contain the exact same instance of p1 - it will not create a new instance and populate it from the database.

You have 2 options: 1) Add your Product_i18n instances to the p1 dictionary explicitly 2) Flush and close the session before retrieving the products in a new session

I would suggest doing both for your test, the first option to maintain consistency in your code, and the second, to test whether other sessions retrieve the data correctly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top