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 1 min | 110 words

A few weeks ago I got really tired of all the spam that I was getting (on the order of 100s a day), and I moved my email to Gmail my domains. Almost immediately the amount of spam that I get dropped to 1 - 3 a day. Obviously, I wanted to connect to it via Outlook, and keep the familiar user interface and offline features.

It was no problem setting this up, but I find that for the past week and a half I have no opened Outlook. I am using Gmail for everything, and I am very happy about it, too.

time to read 3 min | 502 words

I have posted in the past about NHibernate's cascade being one of the places that require careful attention. But I run into an issue with it yesterday.

The issue was that we had a typical parent-children scenario, but the requirement changed and we had to support orphans. That is, children without a parent. This isn't that big of a deal, after all, and I told Imperial to just change the cascade from all-delete-orphan to all, and forgot about it.

I was called a few minutes afterward, and saw that the change didn't have the desired effect. The scenario that we were working on was deleting the parent, where the child needed to remain behind (will null foreign key, of course). Now, I was being stupid, and I started debugging into NHibernate to figure out what was the cause of this "bug". Ten minutes later (took a while to find where exactly this was happening), I had an "Oh, I am so dumb" moment.

So, to save myself from future embarrassment, let me try to articulate what it means:

NHibernate Cascades:
Entities has associations to other objects, this may be an association to a single item (many-to-one) or an association to a collection (one-to-many, many-to-any).
At any rate, you are able to tell NHibernate to automatically traverse an entity's associations, and act according to the cascade option. For instance, adding an unsaved entity to a collection with save-update cascade will cause it to be saved along with its parent object, without any need for explicit instructions on our side.

Here is what each cascade option means:

  • none - do not do any cascades, let the users handles them by themselves.
  • save-update - when the object is saved/updated, check the associations and save/update any object that require it (including save/update the associations in many-to-many scenario).
  • delete - when the object is deleted, delete all the objects in the association.
  • delete-orphan - when the object is deleted, delete all the objects in the association. In addition to that, when an object is removed from the association and not associated with another object (orphaned), also delete it.
  • all - when an object is save/update/delete, check the associations and save/update/delete all the objects found.
  • all-delete-orphan - when an object is save/update/delete, check the associations and save/update/delete all the objects found. In additional to that, when an object is removed from the association and not associated with another object (orphaned), also delete it.

Fairly simple, isn't it? I have no idea why I managed to forget this. At any rate, my issue was that I set the cascade to all, and then deleted to root object, which naturally deleted all the child objects. Setting it to save-update was what I wanted to do, once I did that, everything went just fine.

time to read 4 min | 624 words

If you ever had to work with someone else's database (I assume that yours are perfect), you know that not all databases are nice and clean. In fact, some of them fail to do even simple things, like foreign keys. In some cases, FK is not even possible (think a view over a main frame table that you don't control).

In such cases, almost invariablely, the database slightly corrupts itself. Sometimes it is a programmer error, sometime a failed set of commands without transactions, etc. The end result is that you get an id to another table, but no row that match this id. To say that it is hard to deal with this kind of scenario is an understatement. Even if we are dealing with a nullable FK (which is not always the case), if it has a value, but no matching record, this is a big issue.

Most often, this lead to an attempt to "clean up the data", but this usually lead to finding even more issues, and in many cases there is a big fear that this will damage business critical data. The developers are then left to fend themselves against the unruly database (and the damaged relational model is weaping at the corner).

In NHibernate 1.2, a new attribute was introduced to help solve this issue, this is not-found="ignore", which instruct NHibernate to treat non existing FK not as errors (as is the default), but as nulls. Here is a simple example:

<many-to-one name="Parent" column="ParentId"

                      lazy="proxy" not-found="ignore"

                      class="Item"/>

The nice thing about this feature is that if you save this object into the database, NHibernate will update the column to NULL, helping to restore the database to a sane state.

time to read 3 min | 404 words

Dennis is talking about the shutdown button issue, and bring some new insight into it:

Is that really all that surprizing [lots of people with a say on this feature]? We are, of course, talking about a critical UI element of the flagship of a $300 billion dollar company. In particular about one of the most communicated and referenced features of an operating system that will see installation on hundreds of millions (possibly over a billion) PCs.

Is it really that surprizing that a lot of people have a say in this critical feature? Maybe not. I agree that this is a highly visible feature, and that it has ties to all sort of surpising places (the kernel for one, the messaging system to inform other applications - including the hot boot support, etc).

The problem that most of us have with this is not the complexity of the ties to this feature, I think that if someone sat down and thought about all the places that this feature would touch, they would be amazed. I spend half a minute on this and I can think of a lot of issues, and I have little interest in Windows Internals.

The problem is that someone spent a year actively working on the menu. And the way it was managed. A quick calculation shows that 3.5 man-months were wasted just in meetings about this feature. 3.5 months

There is also the huge hassle in getting your dependencies through all the the gate keepers along the way. Let me give you a simple scenario, two teams need a feature from a third team, which is on another branch. Team A discover that it needs a certain feature, and ask team C to implement it. Team C does this, and goes their own merry way. Two months later, Team A gets the change, and they start working on that. Team B, a month later, discovers that there is a bug in their code because of this feature, and request a fix. Two months later, Team C's fix reach them, but four months afterward, Team A disocver that this fix broke their code. Rinse, repeat, weap.

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
}