Oren Eini

CEO of RavenDB

a NoSQL Open Source Document Database

Get in touch with me:

oren@ravendb.net +972 52-548-6969

Posts: 7,640
|
Comments: 51,260
Privacy Policy · Terms
filter by tags archive
time to read 2 min | 360 words

It is not often that I am arriving to work and the first application that I open is Visual Studio, and I can't get it to open fast enough. Today was such a day, mostly because I got an Eureka moment. It is not often that I get those, so I really want to try it out.

Check out the following code:

public class Aggregator<T> : Aggregator<T, List<T>>

{}

 

public class Aggregator<T, TCollection>

     where TCollection : ICollection<T>, new()

{

     private ICollection<T> collection = new TCollection();

}

Can you tell why I am excited? Because this means that I have static generic specialization (I already have dynamic generic specialization, thanks to Windsor) back!

Notice that for all intents and purposes, I can either use Aggerator<T>, or use the more generic version of Aggerator<T, TCollection>, which allows me to pass my own ICollection<T> implementation.

This is actually compiler supported Inversion Of Control!

Now, of course that I can do this using ctor parameter, but this puts the burden on the client code, and couples the base implementation to the defaults. This approach keeps the base implementation frees from any default whatsoever.

I intend to make use of this soon, so I'll post about the results.

time to read 2 min | 281 words

I got a ton of suggestion to my Bug Tracking? question. As I mentioned, I don't want to use BugZilla, and JIRA is out of the immediate price range that I have in mind - I really want it to be free :-) And although anything without per-user cost is good, JIRA is expensive, although it certainly worth the price.

I tried Gemini, but I managed to hit two seperate bugs in the space of an hour, one of them a show stopper, and it didn't have an integration with Active Directory, which means that I need to handle more passowrd (bad thing in general). Leaving that aside for now, because I really liked the UI and it uses NHibernate.

I then started trying Trac, which was a bit hard to install on Windows, but I managed. The UI is really nice, and I love the SVN integration. It took me a couple of minutes to set it up with mod_python and Active Directory integration, so I don't need to remember yet another password. I'm not crazy about the command line interface to admin the project, but it has a reasonable CLI UI, so it is not that bad. I tried the web admin plugin, but it didn't work that well (kept erasing all the settings). One thing that bugs me :-) is that I can't seem to figure out how to set a default component / ticket type / version.

Thanks for everyone who gave a suggestion to the previous post. I think that we will try that out for a while and see how it goes.

time to read 15 min | 2819 words

I'm constantly on the look up for good questions to ask in interviews, mainly because "describe the page life-cycle" gets boring and I would like to get away from the page lifecycle myself. The problem with finding good questions is that it has to expose as much knowledge from the candidate, while keeping the answer short and possible to answer within the time limits of an interview.

Here is one that I just thought of:

Given an Employee class, create a collection that accepts employees but doesn't allow duplicate employees to be entered. You are free to use any of the classes in the .Net framework.

Basically, build a set class. This is a good question in my opinion because it tests a wide range of knowledge, in a short question, which can be implemented in about 10 minutes. The question test the following:

  • Basic data structure / efficencies knowledge - if they decide to use ArrayList and compare each time, that would cost in both time to develop and performance
  • Thinking toward reuse - if they implement this from scratch (starting from building growable arrays and moving forward), that means that they either have a problem with knowing the building blocks of the framework or they suffer from NIH.
  • Understanding basic idioms of the framework - implementing IEnumerable will make the collection usable for foreach(), for instnace.
  • Understanding how low level stuff works - can they explain what reference equality vs. value equality is, can the explain how the Dictionary works?

It then leads to another question:

In certain circumstances, I wasnt to be able to able to allow no employees with duplicate names, how would you extend the collection to support this?

And this question tests how they can extend an existing class, and whatever they can come up with something that fits into the .Net idioms cleanly. Adding a boolean to check for an employee name is not a good way to do this.

Here is what I would consider an excellent implementation (not great, because it doesn't implement ICollection<T>):

public class EmployeesSet : IEnumerable<Employee>

{

       Dictionary<Employee, object> internalDic;

 

       public EmployeesSet()

       {

              internalDic = new Dictionary<Employee, object>();

       }

 

       public EmployeesSet(IEqualityComparer<Employee> comparer)

       {

              internalDic=new Dictionary<Employee, object>(comparer);

       }

      

       public void Add(Employee item)

       {

              if(!Contains(item))

                     internalDic.Add(item,null);

       }

 

       public bool Contains(Employee item)

       {

              return internalDic.ContainsKey(item);

       }

 

       public bool Remove(Employee item)

       {

              return internalDic.Remove(item);

       }

 

       public int Count

       {

              get { return internalDic.Count; }

       }

 

       public IEnumerator<Employee> GetEnumerator()

       {

              return internalDic.Keys.GetEnumerator();

       }

 

       IEnumerator IEnumerable.GetEnumerator()

       {

              return internalDic.Keys.GetEnumerator();

       }

}

time to read 2 min | 376 words

Mission Critical application, running quitely in production, suddenly stopped working. No warning, not errors. The application is still up, still running, but for all intent and purposes, it is not operational. I get a call that basically says: "Fix it!"

The main interface to this application (windows service) is a huge amount of logs that is being outputed. The target for the logs is the same SQL Server database that the application is using. Any error in this application should be logged and some errors should go directly to the administrators (and me).

But, the application is not doing its job, and worse, it doesn't write anything to the logs. This is a heavily multi-threaded application, so the first thing that I thought of was a deadlock, but restarting the application didn't help. I am on the phone with the sys-admin, going over the application configuration, trying to figure why it doesn't even log its startup event (which is singled threaded, so no chance for deadlocks).

I give up and drive there. Restarting the service doesn't help, and no logs are written, even thought the cofniguration seems just fine. The first thing that I do is taking a look at the logs table. But it currently has about 500,000 records, so queries take longer than instantenous. I get annoyed and try to add an index for the main search criterias. It errors. I double-check my syntax and tries again. It errors.

This time I read the error. It says that it doesn't have enough space to create the index. I didn't think that it is that large an index, but now I operate on a hunch. I tries to insert a row to the database (row size: 40bytes or so). The database refuses, says that it doesn't have enough space.

They had a rigorous backup procedure that kept backups on the same disks as the database files and never purged them. Once I cleared some of the old backups, the application immediately resume normal processing.

Total time trying to fix the issue: ~3 hours.

Total time fixing the issues since arrival: ~10 minutes.

time to read 18 min | 3524 words

I got some interesting replies to my post about what not to do with ORM. I got several comments back, and the major one was how to do a query about an entity collections with using string concantation, which I said was a code smell.

Specifically, the most interesting challange was presented by Josh Robb, and it goes like this:

Blog
    m:n Author
    1:m Posts
        n:m Categories
        1:m Comments

Find all Posts where:

Blog.Author = 'josh' and Categories includes 'Nhibernate'  and a Comment.Author = 'ayende'.

This being a part of a search screen where you can searc h by mulitply criteria, which are change dynamically. This is interesting because is spans just about any interesting assoication type that exists. So I set up to figure out how to do this.

My first step was to try to understand what I want NHibernate to do, so I started by writing the SQL for the above query:

SELECT

    [post].[post_id],

    [post].[post_blogid]

FROM

    [dbo].[Posts] post

INNER JOIN [dbo].[Blogs] blog

    ON post.post_blogid = blog.blog_id

INNER JOIN [dbo].[UsersBlogs] user2blog

    ON blog.blog_id = user2blog.blog_id

INNER JOIN [dbo].[Users] author

    ON author.user_id = user2blog.user_id

WHERE

    author.user_name = 'josh' AND

    EXISTS ( SELECT 1  FROM

                [dbo].[Categories] category

             INNER JOIN [dbo].[PostsCategories] post2category

                ON post2category.category_id = category.category_id

             WHERE

                category.name = 'NHibernate' AND

                post2category.post_id = post.post_id ) AND

    EXISTS ( SELECT 1 FROM

                [dbo].[Comments] comment

             INNER JOIN [dbo].[Users] commenter

                ON comment.user_id = commenter.user_id

             WHERE

                comment.comment_postid = post.post_id AND

                commenter.user_name = 'Ayende' )a

Complex, isn't it? There may be better ways to do this, but that is the most straight forward way I could think of.  Here is the query in HQL:

select post from Post post, User user

where  user.UserName = 'Josh'

and    user in elements(post.Blog.Users)

and    exists (from  Category category

               where post in elements(category.Posts)

               and   category.Name = 'NHibernate')

and    exists (from  Comment comment

               where comment.Post = post

               and   comment.Commenter.UserName = 'Ayende')

It generate nearly the same SQL that I wrote by hand, but uses tetha joins instead of ansi joins (I am not sure why, but the end result is the same).

Just a reminder, this isn't just a single query, this is something that that needs to be built dynamically, and we wish to handle this without using string concantation. In general, this means using the Criteria API. The first problem is that NHibernate's Criteria API doesn't allow you to query collections. This is very bad when you consider that this query is all about collections.

Strings are bad, I said so myself, so I put decided to add this to NHibernate (add is too strong a word, I went to Hibernate's source, found the relevant piece of code, and ported that). Now NHibernate can execute queries like section 15.8 in this page. All fine and dandy, until you get to the point where you need to query many-to-many assoications. You can't do that using the Criteria API in NHibernate (nor in Hibernate, as far as I can tell).

Many to many assoications are a funny beast, since you need to join through a second table to get the real value. I played a bit trying to implement support for that, but I wasn't successfull in the time frame that I could dedicate to it.

But, as the politician said, "This is a great question, but let me answer this one instead.", let us see what happens when we don't have many to many collections, shall we? The model is this, I change the assoication from Blogs to users to be a many to one, so a blog can now belong to a single author and remove categories.

Blog
    m:1 Author
    1:m Posts
        1:m Comments

The query then becomes get all posts where:

Blog.Author = 'josh' and Post Title includes 'Nhibernate'  and a Comment.Author = 'ayende'.

That being the case, we can use the following code the create the query (again, SVN trunk only, I am afraid):

DetachedCriteria theComment = DetachedCriteria.For(typeof(Comment))

       .SetProjection(Projections.Property("id"))

       .Add(Expression.Property.ForName("Post.id").EqProperty("post.id"))

       .CreateCriteria("User")

              .Add(Expression.Expression.Eq("Name", "Ayende"));

 

IList list = s.CreateCriteria(typeof(Post), "post")

       .Add(Expression.Expression.Like("PostTitle", "NHibernate",MatchMode.Anywhere))

       .CreateCriteria("Blog.User")

              .Add(Expression.Expression.Eq("Name", "Josh"))

       .Add(Subqueries.Exists(theComment))

       .List();

To conclude, at the moment NHibernate doesn't support queries over memebers of many to many collections using the criteria API (at the moment). But it does offer a good way to handle queries over memebers of collections in nearly all other cases.

So, allow me to retract my words a bit, if you have dynamic queries and you need to handle many-to-many assoication, HQL is your only choice. Nevertheless, I would strongly suggest to encapsulate this in an OO layer that would generate HQL under the cover, rather than build the HQL dynamically in the UI layer.

time to read 3 min | 504 words

A lot of my posts about NHibernate assume a certain level of familarity with the library and what it can do. For someone who doesn't know NHibernate, I believe that it so much nonesense...

Anyway, this post is intended to give some information about kick-starting your NHibernate development.

The classic articles about NHibernate, at least for me, are the Server Side .Net ones, here and here, by Justin Gehtland.

There is, of course, the online manual, but that is for reference, not to get how to use it. The Officual Quick Start Guide will take you from "NHibernate, huh?" to wielding the NHibernate magic in a short time, but will skip the background. A great resource is this page, which aggregate a lot of this stuff.

There are two example applications for NHibreante: This one by Scott Bellware and this by Paul Wilson. While Cuyahoga is using NHibernate (and my site run on Cuyahoga), I wouldn't recommend it to a beginner, it is definately a very advance application.

Ben Scheirman has a good series of posts about this, actually is it not so much about NHibernate per se, but how to structure your project to make it easier to work with (in general, and with NHibernate):

Benjamin has a lot to say about NHibernate. And Nikola has a very nice introductory post ot it here.

The Hibernate In Action book is wonderful, but many are holding back because they don't want to read a "java" book. I know of at least one (good) NHibernate books that is going to be coming out soon, but until it does, Hibernate In Action remains the best resource to learning about NHibernate.

time to read 1 min | 193 words

It seems to me that I started to accomolate quite a few presentations, and in the spirit of not keeping stuff internal if I can make it public, I decided to publish them.

Here you can find all the public ones.

They are of varying quality, and are mostly used by me to keep me on track and not digress to interesting (but irrelevant) topics in mid talk.

Not suprisingly, most of them are about OR/M, specifically, Active Record and NHibernate. All the ones that start with "NHibernate " are from a course I gave on NHibernate nearly six months ago. The one about Active Record is from an internal presentation that I gave at work (not the one that I am going to give on Monday). There is also an Inversion of Control presentation that I never really had a chance to give for some reason, which I am particulary proud of.

Have fun, and if you intend to use this, I would like to get a link to any recording / video made.

time to read 1 min | 146 words

[Via Eber Irigoyen] [Via Javi Moya's blog]

1. Highlight the text below
2. Ctrl+C
3. Alt+D (Ctrl+L in opera) (or just go to the address bar)
4. Ctrl+V
5. [Enter]

 

javascript:scroll(0,0); R=0; x1=.1; y1=.05; x2=.25; y2=.24; x3=1.6; y3=.24; x4=300; y4=200; x5=300; y5=200; DI=document.getElementsByTagName("img"); DIL=DI.length; function A(){for(i=0; i-DIL; i++){DIS=DI[ i ].style; DIS.position='absolute'; DIS.left=(Math.sin(R*x1+i*x2+x3)*x4+x5)+"px" DIS.top=(Math.cos(R*y1+i*y2+y3)*y4+y5)+"px"}R++}setInterval('A()',5); void(0);

Here is how my site looks like after doing this.

(Image from clipboard).png

FUTURE POSTS

No future posts left, oh my!

RECENT SERIES

  1. API Design (10):
    29 Jan 2026 - Don't try to guess
  2. Recording (20):
    05 Dec 2025 - Build AI that understands your business
  3. Webinar (8):
    16 Sep 2025 - Building AI Agents in RavenDB
  4. RavenDB 7.1 (7):
    11 Jul 2025 - The Gen AI release
  5. Production postmorterm (2):
    11 Jun 2025 - The rookie server's untimely promotion
View all series

Syndication

Main feed ... ...
Comments feed   ... ...