0

I have the following (simplified) entity that I need to bulk-insert:

public class BookmarkEntity
{
    public virtual Guid Id { get; set; }

    public virtual ISet<string> Tags { get; set; }
}

And the Tags property is configured (via FluentNHibernate):

public class BookmarkEntityMappingOverride : IAutoMappingOverride<BookmarkEntity>
{
    public void Override(AutoMapping<BookmarkEntity> mapping)
    {
        mapping.HasMany(x => x.Tags)
               .AsSet().Element("Value")
               .Cascade.Delete()
               .Not.LazyLoad();
    }
}

This results in these tables (using SQLite):

CREATE TABLE "BookmarkEntity" (
    Id UNIQUEIDENTIFIER not null,
    primary key (Id)
)

CREATE TABLE Tags (
    BookmarkEntity_id UNIQUEIDENTIFIER not null,
    Value TEXT,
    constraint FK9061CD2928F7F2F9 foreign key (BookmarkEntity_id) references "BookmarkEntity"
)

I would like to use a stateless session to reduce memory consumption and improve the speed a little. I realize that because stateless sessions do not perform any cascading, I must insert the Tags collection myself. I tried the following:

void InsertIntoStatelessSession(BookmarkEntity entity, IStatelessSession statelessSession)
{
    statelessSession.Insert(entity);
    if (entity.Tags != null)
    {
        foreach (string tag in entity.Tags)
            statelessSession.Insert("Tags", tag);
    }
}

But this fails with an exception:

NHibernate.MappingException : No persister for: Tags

So, how can I insert the bookmark entity and its set of tags?

Patrick Quirk
  • 23,334
  • 2
  • 57
  • 88
  • That is impossible. And saving some time by stateless session.. not sure if that could be achieved. In case that you do not store so many data in one requst.. I'd use standard session. And if you really need optimization... you have to do more manually (CreateSQLStatement...) – Radim Köhler Oct 28 '15 at 13:51

1 Answers1

0

Stateless sessions do not support cascading, so what you're trying to do is impossible.

You could remove the mapping on BookmarkEntity, then fill the Tags collection manually after doing a get, like:

BookmarkEntity bookmark = session.Get<BookmarkEntity>(1);
bookmark.Tags = session.Query<Tag>().Where(t => t.BookmarkEntityID == bookmark.ID).ToList();

Maybe the getter of "Tags" could do this automatically.

When inserting you'll need to save the BookmarkEntity, grab the generated ID (unless you decide to handle that yourself too), set the foreign-key on the Tags, then save the tags. For example:

Object id = session.Insert(bookmark);
List<Tag> tags = new List<Tag>() {new Tag() {BookmarkEntityID = Convert.ToInt32(id), Data= "test123"}};
session.Insert(tags);
Shahin Dohan
  • 6,149
  • 3
  • 41
  • 58