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,565
|
Comments: 51,184
Privacy Policy · Terms
filter by tags archive
time to read 2 min | 266 words

I just finished doing my reverse bills. Unlike doing my bills (which are usually handled automatically), this is tracking down who I owe money to that haven’t been paid. I just had three different incidents where I had to call up people and remind them that I probably need to pay them money.

Some highlights from those conversations:

  • Hey, I owe you money, can I pay it already?
  • What do you mean, I don’t owe you money. I say I do, and the customer is always right.
  • You promised that you would send me that invoice, but it isn’t here… What do you mean, it is in the mail?

It feel funny, because some of those talks went along the line of “you own me money”, but what I was trying to get is just an invoice so I could actually pay it. Hell, I had to call my landlord and setup time & place so I can pay for utilities (he has been avoiding that for the last few months). And the last rent check I had to ring him up and ask him why he didn’t deposit the check he had.

It is a funny world we are living at.

On the one hand, I don’t feel it is ethical not to pay, or even to wait until they wake up and remember that they need to be paid. On the other hand, I like that there is enough of a trust that this situation can actually come up.

time to read 3 min | 464 words

So, I am sitting there quietly trying to get EF Prof to work in a way that I actually like, when all of a sudden I realize that I am missing something very important, I can’t see the generated queries parameters in the profiler.

Looking closely, I started investigating what appear to be a possible SQL injection issue with EF. My issue was that this query:

entities.Posts.Where(x=>x.Title == “hello”)

Generated the following SQL:

SELECT
1 AS [C1],
[Extent1].[Id] AS [Id],
[Extent1].[Title] AS [Title],
[Extent1].[Text] AS [Text],
[Extent1].[PostedAt] AS [PostedAt],
[Extent1].[BlogId] AS [BlogId],
[Extent1].[UserId] AS [UserId]
FROM [dbo].[Posts] AS [Extent1]
WHERE N'hello' = [Extent1].[Title]

It literally drove me crazy. Eventually I tried this query:

var hello = "hello";
entities.Posts.Where(x=>x.Title==hello);

Which generated:

SELECT
1 AS [C1],
[Extent1].[Id] AS [Id],
[Extent1].[Title] AS [Title],
[Extent1].[Text] AS [Text],
[Extent1].[PostedAt] AS [PostedAt],
[Extent1].[BlogId] AS [BlogId],
[Extent1].[UserId] AS [UserId]
FROM [dbo].[Posts] AS [Extent1]
WHERE [Extent1].[Title] = @p__linq__1

This was more like it.

It seems (and Julie Lerman confirmed it) that EF is sticking constant expressions directly into the SQL, and treating parameters differently.

I am not quite sure why, but from security standpoint, it is obviously not a problem if it does so for constants. It have a lot less hair now, though.

time to read 2 min | 313 words

Über Prof is the codename for the multi-OR/M profiler that I have been working on for the last several weeks.

Today is a good milestone, because it marks the shift from treating it as an experimental to production ready.

image

Über Prof also brings with it several changes to the way I mange the profiler profiles. Each profile (NHProf, HProf, L2SProf and EFProf, currently) is built on top of the same codebase, but contains slightly different functionality to fits it target audience. I might talk about exactly how we are doing that in a later post.

That required making a small number of breaking changes:

  • The executable filename was changed to NHProf.exe (or HProf.exe, or L2SProf.exe, etc)
  • The appender filename was changed to HibernatingRhinos.Profiler.Appender.dll
  • The appender type name was changed to HibernatingRhinos.Profiler.Appender.[profile].[profile]Profiler.Initialize();

In practice, those changes are annoying, but should be very easy to fix.

Something important to note, however, is that NHibernate profiling and Hibernate profiling has been split.

For NHibernate, we have NHProf, and for Hibernate, we have HProf.

I hope to have L2sProf out in public beta this week. And EFProf is currently in private beta for this week and hopefully poke its nose out as public beta next week.

Updates:

  • There is going to be a bundle, yes. No details yet on what it will be, though. I am leaning more toward a discount model rather than a bundle, since it seems that it would be more appropriate.
  • People who already bought NHProf license can use that for HProf as well with no issues.
time to read 3 min | 523 words

My post about applying YAGNI in Impleo has gotten a lot of comments, and instead of answering them one at a time, I think it would be useful to just have a post answering all of them together.

Ryan Riley: I suppose I'm still wondering, how did WebForms appear as a result of YAGNI? I realize that's the original ASP.NET platform, but MVC seems simpler to me, and even simpler would be starting with HTML, CSS, and JavaScript (or, heaven forbid, classic ASP) with some AJAX.

Ryan, it is quite simple. It is all about friction, using HTML, CSS & Javascript would have added more friction initially than the webforms solution.

Torkel: Any plans to open source it?

Highly unlikely.

Andrew: I know we all hate Web Forms, yada yada yada, but if you need to just setup a few pages, it's dead easy and much faster than MVC, a WCF service or any other method to deliver content.  Hence why it makes perfect sense in this "I'm using YAGNI to the letter of the law" experiment.
But the reality is, you rarely have a project where you can work in this pure YAGNI way, since there almost always is requirements such as make it testible, make it easy to maintain, make it SOE friendly, etc. so working in ASP.NET Webforms a poor choice for the job.  But there does come a time where a project is "All we need is one page that shows data in a grid", it can be done in literally 10 minutes with a WebForm.

I agree, except that there is an additional thing that I want to bring to the table. The most important thing for me in most of my apps is the first customer demo. That is important for a host of reasons, but most importantly, because it make a product real. Building fancy architecture and buzzward compliant development is usually in the way of that. The first customer demo is simple, stupid and should be out as soon as possible.

Dmitriy Nagirnyak:  

Your own website framework?
Hmm.
What are the reason for starting it from scratch if there are some of them already available?
- Exercise?
- Lack of extensibility?
- Wrong architecture?
- "Just want my own" thing?
- others?

Quite simple, I wanted something that would work the way I need it to work. Anything that adds friction to the process is not acceptable. I am willing to build my own thing to get a friction free process.

Richard Dingwall: Article starts with YAGNI and ends up writing a whole new CMS from scratch! Ayende!!

See previous reply.

time to read 1 min | 82 words

Recently all my technorati feeds started to give me stuff like this:

image

It looks like someone managed to crack the way that technorati is searching feeds, and I am getting what amounts to spammed search results. If this continues, it looks like I’ll just have to give up on it completely.

Any good alternatives?

time to read 5 min | 816 words

This started out as a support question, but it is an interesting enough (and general enough) that I think it is important to make sure that it is recorded.

When working with detached entities (from another session), sometimes, at seemingly random places, NHibernate will throw a NonUniqueObjectException. Where it actually happen and the exact cause depend on several variables, but the root problem is simple: working with detached entities safely requires that you be aware of possible identity map violations.

Let us look at some code and then I can explain:

using (var session = sessionFactory.OpenSession())
using (var tx = session.BeginTransaction())
{
// get the entity
post = session.Get<Post>(postId);
// force the association to be eagerly loaded
System.Console.WriteLine(post.User.Username);
tx.Commit();
}

using (var session = sessionFactory.OpenSession())
using (var tx = session.BeginTransaction())
{
// get the user for the entity
var anotherUser = session.Get<User>(post.User.Id);

// will return false
ReferenceEquals(anotherUser, post.User);

// opps, user instance with the same id but with different
// reference was detected
session.SaveOrUpdate(post);

tx.Commit();
}

The reason that the problem seems obscure at first is that there are quite a few variables that are going to affect how this will behave. In order to reproduce the issue you need:

  • An association that is marked with a cascade option, such as “save-update”, “all” or “all-delete-orphan”
  • The entity this association points needs to be loaded in the second session.

Depending on what you are doing (saving an entity vs. updating it) and what the options are for the id generation, you may get the error on the SaveOrUpdate or on the Commit.

The actual details are pretty unimportant, but understanding what is going on is. The issue is that NHibernate has been asked to perform something that violate one of its core assumptions, break the identity map.

Because of the cascade options set on Post.User, we are asking NHibernate to also save the User instance associated with the post. The problem is that when NHibernate is encountering that, it is going to see an entity with an id that is already on the session but as a different reference. That violates the identity map rules and force NHibernate to throw an exception.

The root cause is, as I mentioned, trying to work with a detached entity as if it was a regular entity. NHibernate provides a different API for working with detached entities safely, precisely because of those sort of reasons.

The appropriate way of handling such an issue is to use the Merge method, which will take a detached object graph and merge it into the session, properly resolving such conflict. Note, however, that Merge will return a different entity instance than the one that you passed.

Let us look at the code:

using (var session = sessionFactory.OpenSession())
using (var tx = session.BeginTransaction())
{
// get the user for the entity
var anotherUser = session.Get<User>(post.User.Id);

// will return false
ReferenceEquals(anotherUser, post.User);

// will merge the detached entity into the session
// creating NEW entity instance or re-using the one
// that is already in the session
var mergedPost = (Post)session.Merge(post);

// will return false
ReferenceEquals(mergedPost, post);

// will return true
ReferenceEquals(anotherUser, mergedPost.User);

tx.Commit();
}

As you can see, this is a fairly small change, and NHibernate now takes care of wiring up everything correctly even in the face of conflicting changes.

You can play around with the code here:

http://github.com/ayende/nhibernate-blog-model/tree/non-unique-object-execption

http://github.com/ayende/nhibernate-blog-model/tree/non-unique-object-execption-resolution

time to read 1 min | 143 words

I…. “run an experiment” today (yesterday?) to figure that one out, and the result is:

  • 2 wine glasses
  • 1 white Russian
  • 1 double bourbon
  • 6 long island iced tea
  • (probably) 1 bear (no urisdae drinking!) beer

The way to get me drunk is Long Island Iced Tea. Up until the 6th drink, I am perfectly coherent (at least I seems to be as far as I can tell), it is with the 6th that things starts to fall over rapidly, including memory loss about an hour after the last drink.

That list isn’t enough to give me hangover, though. I am still experimenting with that, but I think that mixing some blue drinks along the way would do the trick.

time to read 2 min | 281 words

I was sitting with Julie Lerman today, and we got into a discussion on how to provide more information to EF users. It appears that there is much need for that.

This is what I do, more or less, so we decided to tackle that problem in the bar. Some drinks later, we had a working version of EF Prof that was actually able to intercept all queries coming from the Entity Framework. Initial testing also shows that I’ll be able to provide much more information about EF than I’ll be able to do with Linq to SQL.

Unfortunately, the current way of intercepting EF traffic is extremely invasive, and I don’t really like it. I consider it a good proof of concept, but I am going to spend some of next week trying to figure out a less invasive approach.

In the meanwhile, take a look (not the final look & feel):

image

image

And here is the project that we profile:

image

It supports all the usual niceties, so you get stack trace support, tracking selects (including lazy loading), updates, inserts & deletes. And I tested it on both EF 3.5 and EF 4.0.

I expect to have a private beta starting next week…

time to read 2 min | 262 words

image I love the WoT series. My nickname, Ayende Rahien, is based on that series. So you can imagine how happy I was to start reading the Gathering Storm.

There are no spoilers in this post, I a going to spend some time digesting the book and then post a review about the actual details of the book.

What make this book unique is that the author was changed (the original author died), which caused a huge delay for this book and caused sever worries whatever the new author would be as good as the original.

I can tell you that I personally had not been able to figure out the original scenes vs. new author scenes. It does seems like there are less feminine clothing discussion (which I consider to be a great plus).

It is probably hard to see, but the cover art is still as bad as the previous ones, which also make me nostalgic.

This book focuses mostly on Rand, with some really interesting developments. There hasn’t been enough Rand in the last two books, so that is good. On the other hand, I could do with more Matrim scenes.

Things are moving, rushing pretty fast, actually. The book is a page turner, it is a 784 pages book that I finished in one seating, taking about 12 hours.

I can’t wait to read the rest.

FUTURE POSTS

No future posts left, oh my!

RECENT SERIES

  1. Production Postmortem (52):
    07 Apr 2025 - The race condition in the interlock
  2. RavenDB (13):
    02 Apr 2025 - .NET Aspire integration
  3. RavenDB 7.1 (6):
    18 Mar 2025 - One IO Ring to rule them all
  4. RavenDB 7.0 Released (4):
    07 Mar 2025 - Moving to NLog
  5. Challenge (77):
    03 Feb 2025 - Giving file system developer ulcer
View all series

RECENT COMMENTS

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats
}