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

I was talking with a team about their project, and doing a very minor code review. Naturally, one of the things that I checked first is the data access portion of the application.

I looked at the data access code in a sense of shock. I was on a phone call with the team, with one of them speaking and I interrupted him to say something along the lines of: “Guys, the nineties called and they want their handed rolled data access back!”

Just to give you an idea, when I am saying that the code has hand rolled data layer, I mean that it include such things as string concatenation to build queries (although I couldn’t find SQL injection, which surprised me), manual hydration of the entities, manual support for “eager loading” using SELECT N+1 queries, manual support for transactions, etc.

The reason for that, it seems, is that they wanted to find the lowest common denominator approach, so “everyone” can use it.

Sorry, ain’t going to happen. The moment that you give me something like that, I am going to drop the entire thing. I cannot work like that. The sheer amount of grunt work involved in getting anything done in such a system is a complete and total blocker. It is not the lowest common denominator, it is the least common denominator.

It is ugly, it is nasty and people should really stop writing data access layers, get on with the program and use a real OR/M. Stop stealing from your clients!

time to read 1 min | 136 words

I was just reviewing someone’s code, and as I was browsing through the tests, I run into the following anti pattern, just about all the asserts were specified as:

Assert.True(pet.Owner == "Baz");

The problem with that is that this is a perfect case of “let’s create a test that will tell us nothing when it is failing”.

It seems like a minor thing, to use the more explicit version:

Assert.Equal("Baz", pet.Owner);

But it isn’t, when this assert fails, we are going to get a lovely error message telling us exactly what went wrong. From maintainability standpoint, being able to see why a test failed without debugging it is not a plus, it is essential.

Assert.True is a tool of last resort, don’t use it if you have any choice at all.

time to read 2 min | 284 words

Another post request from the forum:

Oren,

I'd love to get some detail on how to make the most of NHibernate's unit of work capability in a web app scenario.

It seems like in a web app, because your unit of work may be split across multiple web requests (and therefore sessions), it's hard to use NHibernate's change tracking etc effectively and I find myself doing unit of work tracking myself.

This seems to lead inevitably to an anaemic domain model and feels like fighting the tool.

Well, I am going to take that in two parts. First, having a unit of work that span requests is something that is possible (and I’ll discuss how to implement shortly), but I don’t recommend it. It is much easier to build your application so each request is a single unit of work.

Now, about actually implement a request that spans multiple requests, it is not really hard. It is called long conversation, or session per business transaction. Here is a detailed explanation on how NHibernate Burrow is achieving this.

But basically, it is quite simple. You set the session’s flush mode to Never, and you store NHibernate’s session in the ASP.Net session. Now, for each request, you can get the NHibernate session for the ASP.Net session and continue working with the same session and entities, taking advantage of change tracking, transparent persistence and all the other features that make NHibernate easy.

There are several frameworks out there that would handle this for you, Burrow, as I mentioned and Rhino Commons as well.

time to read 2 min | 219 words

This is an answer to a post request in the forum:

Why keep NHibernate tied to Hibernate or is it not tied to it anymore? (NHibernate would be easier to pick up if the nomenclature wasn't ripped from Hibernate, ie AliasToBeanResultTransformer, etc...)

There are two separate questions here that needs answering. The first is easier, we keep NHibernate close to Hibernate because it makes our lives so much easier. By keeping the code bases close to one another, we can more easily port new features, documentation and bug fixes. There are no plans, and I don’t believe there would be plans, for making a clean break. Simply because it is not beneficial for the project.

The second question is about Javaism in the project. I fully agree that AliasToBeanResultTransformer is a head scratching name, this is simply a case where we didn’t match the name to the .Net standard. Those sort of cases are things that can and probably should be fixed, and a patch for that (including backward compatibility!) would be appreciated.

While we want to keep NHibernate close to Hibernate in order to reap the benefits, we also intend it to be a full class citizen in the .Net ecosystem. The two aren’t contradictory to one another.

time to read 1 min | 84 words

This is from a post request in the forum:

I notice that a lot of the "debate" in the comments of your posts tend to ignore this. You tend to be very clear when you post about the context that helped make a decision, but then comments tend to ignore that and go after the fact that your decision doesn't follow X guideline, Y pattern, or the Z principle.

Yes, I noticed that as well.

time to read 1 min | 160 words

This book (free online version!) is part of the Posleen series, and I stands quite well in that series. Ringo manages to weave a complete tale, and even there are some stuff there that stretch my credulity even in SF novel, I liked it.

One very interesting aspect of the book is the treatment for “war crimes” during the book. I don’t want to give any spoilers, since it is a good book, but let us just say that I could more than see how the enemies were able to use stupid and insane laws to hinder the protagonists.

The book ends in a rather surprising article, which I recommend reading.

I don’t agree with everything that they say there, mostly because it is primarily aimed for US readers, but they are saying quite a lot that I do agree with.

time to read 2 min | 373 words

When working with UI, quite often some part of the UI is dependant on some condition. The problem is that this condition is often subject to change, and we need some way of dealing with those changes. That is why I created the following class:

public class Fact : INotifyPropertyChanged
{
	private readonly Func<bool> predicate;

	public Fact(INotifyPropertyChanged observable, Func<bool> predicate)
	{
		this.predicate = predicate;
		observable.PropertyChanged += (sender, args) =>
		                              PropertyChanged(this, new PropertyChangedEventArgs("Value"));
	}

	public bool Value
	{
		get
		{
			return predicate();
		}
	}

	public event PropertyChangedEventHandler PropertyChanged = delegate { };
}

While it doesn’t looks like much, it does offer me a lot of value in terms of simplifying conditional logic. For example:

public Fact CanMovePrev
{
	get { return new Fact(CurrentPage, () => CurrentPage > 0); }
}

public void OnMovePrev()
{
	LoadPage(CurrentPage - 1);
}

Where CurrentPage is an Observable<T>, which I discussed previously.

My infrastructure knows about the naming convention and will automatically generate a Command and bind it to the MovePrev action, including both the action to execute upon commit and whatever or not we can execute this. For that matter, it will also gracefully handle can execute changes very easily. Here is the code to actually do that (I’ll spare you the convention based wiring code):

public class DelegatingCommand : ICommand
{
	private readonly Action action;
	private readonly Fact canExecute;

	public DelegatingCommand(Action action, Fact canExecute)
	{
		this.action = action;
		this.canExecute = canExecute;
		var dispatcher = Dispatcher.CurrentDispatcher;
		if (canExecute != null)
		{
			this.canExecute.PropertyChanged +=
				(sender, args) =>
					dispatcher.Invoke(CanExecuteChanged, this, EventArgs.Empty);
		}
	}

	public void Execute(object parameter)
	{
		action();
	}

	public bool CanExecute(object parameter)
	{
		if (canExecute == null)
			return true;
		return canExecute.Value;
	}

	public event EventHandler CanExecuteChanged = delegate { };
}

Tada! :-)

time to read 1 min | 117 words

Well, it is no wonder that my attempts to debug the system where futile. I am using a 3rd party library to handle SQL parsing, and it fails on big SQL statements (admittedly, big here is defined in megabytes, but still). The part that utterly kills me is that I decided to track down the problem.

Here is what I found:

image

So if it is failing to parse the text it is going to kill the entire application!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Oh yeah, you can bet that I am angry now!

time to read 1 min | 142 words

Here is an interesting problem that I have no solution for so far.

class Program
{
	static void Main(string[] args)
	{
		var foo = new Important();
		try
		{
			AppDomain.CurrentDomain.UnhandledException += (sender, eventArgs) =>
			{
				Console.WriteLine(eventArgs.ExceptionObject);
			};
			using (var backend = new BackendBridge())
			{
				backend.Start(23321);

				string filePath = @"E:\Samples\blob.nhprof";
				using (var stream = File.OpenRead(filePath))
				{
					backend.LoadFromFile(stream, new CancellationToken());
				}
			}
			Console.WriteLine(foo);
		}
		catch (Exception e)
		{
			Console.WriteLine(e);
		}
		finally
		{
			Console.WriteLine("Done!");
		}
	}

	private class Important : CriticalFinalizerObject
	{
		~Important()
		{
			Console.WriteLine("finalized");
		}
	}
}

The problem is quite simple, reading the file will kill the application. The problem? I don’t know why.

The only output from the program is “finalized”, which suggest that there is something really nasty going on there. I am open for suggestions, because I have no idea how to deal with this thing, to tell you the truth.

FUTURE POSTS

  1. Semantic image search in RavenDB - about one day from now

There are posts all the way to Jul 28, 2025

RECENT SERIES

  1. RavenDB 7.1 (7):
    11 Jul 2025 - The Gen AI release
  2. Production postmorterm (2):
    11 Jun 2025 - The rookie server's untimely promotion
  3. Webinar (7):
    05 Jun 2025 - Think inside the database
  4. Recording (16):
    29 May 2025 - RavenDB's Upcoming Optimizations Deep Dive
  5. RavenDB News (2):
    02 May 2025 - May 2025
View all series

Syndication

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