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 9 min | 1716 words

I got a comment today from Jim Bolla asking about this query:

select new Address(c.Address, c.City, C.Zip) from Customer c

His comment was:

I've been using NHibernate for at least 6 months now and haven't heard of this feature. Does this really work? What are the requirements/limitations? Is this in the documentation? Or even in the example code/tests?

As he didn't leave an email or another way to contant him, I'm going to broadcast the reply to the world, hoping it would get back to him. (As an aside, if you ask a question, I need a way to get back to you, so leave a way to do so).

First, it is a documented feature that you're welcome to use. It's not used much (and sadly I couldn't find a test for it after a quick grepping), mainly because it is obscure. I just gave it a quick test, and it is working correctly. One word of caution. you need ot make sure that you imported the type that you are trying to create. Here is the sample test:

[TestFixture]

public class QueryThatCreatesAnObject

{  

    [Test]

    public void CheckCreatingObjectsInSelectClause()

    {

        ISessionFactory factory = DatabaseTests.CreateSessionFactory();

        ISession session = factory.OpenSession();

   

        session.Delete("from Blog");

        session.Flush();

 

        Blog blog = new Blog("ayende @ blog");

        session.Save(blog);

        session.Flush();

 

        IList list = session.Find(@"select

                    new System.Collections.DictionaryEntry(b.BlogID, b.BlogName)

                    from Blog b");

        Assert.AreEqual(1, list.Count);

 

        DictionaryEntry de = (DictionaryEntry)list[0];

        Assert.AreEqual(de.Key, blog.BlogID);

        Assert.AreEqual(de.Value, blog.BlogName);

    }

}

As you can see, it's pretty slick. I'm not 100% about how you import a class, and I don't have the time to investigate, but the documentation for that is here.

time to read 1 min | 192 words


I set out today to write something that I never did before, but which I thought was too small to deserve a true spike. I'm talking about my persistance to code implementation, of course.
I started by writing the following test:

[Test]
public void SaveEmptyGrap()
{
    Graph g = new Graph();
    StringWriter sw = new StringWriter();
   
    g.Save(sw);
   
    string actual = sw.ToString();
    Assert.AreEqual("??",actual);
}

I had no idea what I was going to get, but I went ahead and played with the code until it compiled, and then I looked at the result, verified that it was correct* and used that as the expected value.
I could then move on to the next test, graph with nodes, using the same method.

* Just to note, it turned out that I missed putting the method name in Code Dom, which meant that my expected string were wrong. I found out about that only when I tried to load the graphs again. It wasn't hard to fix, but I wanted to point out that this method has its weak points.

time to read 2 min | 248 words


There has been a lot said about testing and their affect on the code. I just had the tests affect me as I write the code. You are probably aware that I started a new project recently, and I've (as always) taken my time with a lot of spiking on the design.
Even when I am spiking, I feel very nervous without the tests, and because I'm making such profound changes to the application, there are long stretches of times when I can't even get the application to compile.
This mean that thinking about something and seeing it fail (and it always fails the first time) takes very long time. It also means that I waste quite a bit of time in going the wrong direction.

Today was the day when I finally settled on the design that I would have, and started sweeping thorugh the code, looking for stuff that needs to be tested. I think about this an un-legacifying the code that I wrote this past week (which had only two tests, one of them 40 lines long, yuck!).
I added a lot more tests, renamed a couple of methods, applied the Law of Demeter and voila, I got a code base that is a pleasure to work with.
Then I could start writing features using TDD, and get the rapid feedback that I crave. I actually added value today, which is a great feeling to have in the end of the day.

time to read 1 min | 129 words


I posted a few days ago about Saving object graphs to file: CodeGen and Executable GraphsI just wrote the final test that made it all happen! I got objects that knows how to persist their state to code, and then load themselves right back from this code.
This is the first time I worked in Code Dom, and it was very easy to get it to work very quickly.

This is a huge security hole, of course, but I'll probably just play with the AppDomain permissions so the only thing it will be able to do is to give me the complete object graph. I got to say, there is quite a bit of satisfaction in saving files in this format. Very readable.

time to read 1 min | 73 words

I just run into a bug that happened because I used EntitySets.
I was relying that the order I'll get the items from the set will be identical to the order I inserted them.
It even pass a couple of tests when I wrote this, but it started to break today until I figured out what was wrong. A quick change to EntityList (which does have this guarantee) solved the problem. 

time to read 2 min | 279 words

I listened to the rest of the DotNetRocks episode 169 with Rocky Lhotka. This time, I wanted to comment about the part where Rocky talks about ORM. Before everything else, I would like to comment on something he said about Microsoft and O/RM.

He said that most O/RM are using Reflection, and that only Microsoft can solve this issue, because the can modify the CLR to allow direct access to private fields.

I wanted to note that there is already such a thing in .Net 2.0, and it is called LCG (Lightwieght Code Generation), and it basically means that you can inject a method into a class, which will have full access to all the class' members, regardless of visibility (just as any class on the object does). There is a patch for NHibernate that allows it to use this functionality in .Net 2.0, so you don't need to me Microsoft to use this.

I would also like to comment that NHibernte is already avoiding Reflection whenever possible, relying on runtime code generation to read and write to public properties / fields. 

I want to address another part of what he said, where he said that O/RM assumes that objects are structure the same way as the database is. Only the simplest O/RM assumes this. One of the important charactaristics of objects is not the data they contain, but what type of object you have, and what relations it has to other objects. A good O/RM will know to map the schema of a database to your object structure without impacting the design of the object.

In fact, I would go as far as to say that this is the criteria of good O/RM.

time to read 5 min | 926 words

I was listening yesterday to DotNetRocks episode 169 with Rocky Lhotka, and I was muttering "WTF??!!" throughout the first part of the show.

The issue that I had was Rocky talking about TDD and saying stuff that simply didn't match the reality, not by a long shot. Jeffery Palermo post about it as well, by the way.

Rocky's main objections seem to be:

When you are working Test First, you don't get intelli sense for classes and methods that don't exists, and that seem to hurt his development style.

First, what is the problem. You just created a class, why do you need intelli sense for something that you'll write in a few minutes? Yes, it is convient, but the rate of creating new methods / classes in my code is not high enough that I will forget that I created that class 3 minutes ago and need to think about the interfce I want to give it.

Second, good enough tools like the wonderful ReSharper or VS.Net 2005 (far less powerful) will gladly create classes and method for you on the fly when you refer to something that do not exist. This is not an issue.

Test First require that you will first write the test, and then write the code. Doesn't mesh well with programming by the wizards.

Considerring that most of the wizards have to do with UI in the first place, and considerring the big problems in testing UI, I would say that this is a non issue. If I think that I need something that doesn't work directly in the UI, I can't see how the wizards and the tools will help me any. I am aware that other people feels just the opposite.

That said, do you really think that you can trust the code that the wizard generates? Or are you going to run it through it paces a few times, just to make sure it works? If you intend to check it yourself, you need a test for this (or several). You will change this part of the code, and you need it covered. I would also argue that you get far better design and working experiance when working in TDD fashion that you do with all the wizards.

You write a bunch of tests, and then you've to write the code to make them work, which is hard.

You know what, he is right on this one, which is why you never write a bunch of tests and then try to implement them. You write one test, then you make it work, then you write another test, etc.

On a large system, it is hard to test one method at a time.

This is possible, and it indicate a design problem in the code, fix it. Check out "Working Effectively With Legacy Code" for the details. I can't imagine trying to change something in a large system without tests. How do I know that I didn't break anything?

If he is talking that it is hard to TDD a feature with small increments, than he is right, it takes some work. The end result is worth it since you got a decoupled design you know is working.

Ater writing a test, developers fear to refactor the system, since it will break the test.

I was literally ranting at this point, and this one is really over the top. If I have ever heard a falser statement... TDD is made up of three things: "Red, Green, Refactor". If you don't do all three, you are not doing TDD. What he calls refactoring is not that, it's random code movement through the code, with the prevent wishes of the developer that he isn't breaking anything. Thanks, but "Code and Pray" are not for me.

It's easy to write your own test harness in a couple of lines.

Yes, it is easy, but you are only running one test that you keep changing, you are not check other parts of the code, can't add it to the build process, etc. In essense, this "test harness" is merely a way to execute the code as it would be on the production system, so you could debug the problems. I would rather not debug at all, and get a nice warm blanket of tests telling me where I am doing wrong.

FUTURE POSTS

  1. Semantic image search in RavenDB - 3 days 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   ... ...
}