Getting Started With db4o

on

Recently I was starting up a new project and got to the point where I needed to persist some of my objects to a database.  Instead of doing what I normally do, NHibernate and SQL Server, I decided to try something new.  A colleague of mine told me about db4o a few weeks ago so I decided to take it for a spin.

Just in case you don’t already know, an object-oriented database stores your objects directly in the database without having to map it into a relational structure.  No object-relational impedance mismatch that we usually get with relational databases.

db4o uses a custom file format to store your objects.  It supports both local in-process access as well as remote access over TCP/IP.   It supports all your standard CRUD stuff, has transactions, and extensive query support through a custom query API and LINQ.

Get db4o

Head on over to http://www.db4o.com and download db4o.  In addition to the db4o runtime, you can also install ObjectManager Enterprise which is a Visual Studio plugin for browsing objects in a db4o database.  OME is an object browser for a db4o database. 

The SDK and runtime are in the bin\net-3.5 directory of the installation location.  Db4objects.Db4o.dll, Db4objects.db4o.CS.dll, and Db4objects.Linq.dll are the core libraries.  There are other libraries in the same folder that add additional features.

Host db4o

There are two ways to host db4o: embedded single client and client/server.  The client/server mode can be configured for local or remote connections.

Embedded Single-Client Mode

Embedded single client mode is great if you have a desktop app that needs to persist some data to the local file system.  It allows only a single connection to the database.  Other connections will get an exception when opening the database file.  The embedded database API is in the Db4objects.Db4o.dll library

To open or create a new embedded database, call Db4oEmbedded.OpenFile, passing in a configuration object and the path to the database file.  The returned object will be of type IObjectContainer and is the primary interface for interacting with your database.

Client/Server Mode

When you need more than a single connection to the database, as typical in web applications, you need to use the client/server mode. Whether you need remote, out of process connections or local inprocess connections will determine how the client/server mode is configured. For in process connections only, configure the server to run with a port number of zero(0). To allow remote connections, give the server a port number greater than zero. Remote connections use TCP/IP. The client/server API is in the Db4objects.db4o.dll library.

To start the database server, call Db4oClientServer.OpenServer, passing in a configuration object, the path to the database file, and a port number.  A port number greater than zero will allow TCP/IP connections to db4o. For servers that will allow remote connections, you need to grant access to a username and specify a password for the username

How you open a client is determined by if you are connecting to a local or a remote server. For local servers, you call the OpenClient method of the IObjectServer. For remote servers, you call Db4oClientServer.OpenClient, passing in a configuration, host name, port, username, and password

The CRUD

db4o handles the basic CRUD operations.

There are a few gotchas when doing updates/deletes with object graphs.  You must tell db4o how to cascade when you open the connection.  This is accomplished through the configuration object that is passed as the first parameter to the OpenClient/OpenServer methods.

Querying

db4o has extensive querying support including query-by-example (QBE), native queries, SODA, and LINQ. LINQ is the preferred way to query in .net applications and should be used for the majoriy of your queries. An example of a LINQ query was provided in the previous example. SODA queries are db4o's low level API. Native queries use the native language, C# in this case, to query the object store. QBE is where you give db4o a prototype of what you want and it will find everything matching it

SODA Queries

Query-by-Example

Native Queries

Transactions

Similar to other database systems, db4o provides a transaction mechanism. Opening a transaction is implicit when you open a connection to the database and implicitly committed when you close it. During the lifespan of an open connection, you can commit any changed state to the database before closing the connection. You can also perform a rollback to reset the state of an open connection to the last commit point or to the opening state of the connection if you have not done a commit. 

Rolling back the database poses a problem though.  When doing a rollback, we rollback the database but not any of our live objects.  The solution to this is found in the Ext library in the form of the Refresh method.

Wrapping Up

There is a lot more to db4o than I talk about here. Read through the documentation that comes with it and then head over to the developer forums at the db4o site to get answers for any outstanding questions you may have.

Monitoring MSMQ

2
on

I have been looking for a solution to monitor MSMQ queues at work.  Luckily, Windows ships with 2 tools that we can utilize to help us out: Performance Monitor and Event Log.

Alerts are defined in perfmon to monitor the number of messages in our queues.  When the limit is reached, a trigger is fired.  In our installation, we have the trigger set to write a message to the event log using a specific event id.  The operations/infrastructure team responsible for keeping the systems running use a commercial product to watch the event logs for our event id.

How do you monitor MSMQ?

What I’ve been up to

0
on

It’s been awhile since I last posted anything.  This post is just to let the world know that I am still alive and what I have been working on these past few months.

At the office

At work, its the same old boring stuff of maintaining a legacy asp.net web forms app from hell.  I say from hell because it has a hand rolled DAL, over 20 projects, table based markup, asp.net ajax toolkit, …well you get the point.  Our marching orders are to keep it up and running while adding features to support our ever changing business.

Early on we did some broad refactorings (code reformatting, removing singletons, cleaning up cross project dependencies) with marginal success.  Here lately the work has been on improving performance.  Part of that has been me analyzing performance counters and log files from our production systems.  Hopefully I will get the urge to write about the specifics as I believe it is valuable information that I will need again in the future.

In the next few weeks I hope to spend less time on the legacy system and more time working on the strategic enterprise architecture stuff.  Our discussions to date have been about how SOA, EDA, messaging, etc can help the software stay agile and change at the pace of the business.  More on this at a later date as well.

At the house

At home I am focusing on a side project that is built using  ASP.NET MVC, NServiceBus, and db40. 

Let me tell you, db4o is really cool.  There is very little code to get it up and running, especially when combined with a framework like NCommon,  And the whole NoSQL stuff is just great.  Head on over to www.db4o.com and have a look.

This weekend I have been writing a subscription storage and saga persister for nservicebus using db4o which I plan to contribute back to the project. 

.Net lagging behind Java in ORM adoption, maybe

0
on

I just did a quick search on Dice for C# jobs seeking NHibernate experience and compared it to the number of listings looking for Java and Hibernate experience.  This is far from scientific and does not take into consideration any overlap in job listings (we all know how recruiters post jobs on the internet), other ORMs, VB.Net, or the fact the Java camp embraced ORMs much earlier than the .Net side.

With that said, here are the results.  For Java, 1144 of the 8908 (12.8%) listings mention Hibernate.  On the C# side, only 62 of the 4501 (1.4%) listings mention NHibernate.

I must say that I was surprised by the low percentage for Java/Hibernate since it has been around so long and everyone I know working with Java use Hibernate.  Maybe recruiters don’t mention Hibernate because it is so engrained that experience with it is assumed.

I am not surprised by the low C#/NHibernate numbers given the years of poor guidance given by Microsoft in this area and the initial lack of support for the OSS community.  I do expect this number to increase as more and more developers hear about ORMs and investigate  EF/linq2Sql alternatives.

Structural Design Pattern Confusion

0
on

The other day my team was having a discussion about some software we were working on.  During the discussion, several of the structural design patterns were mentioned, sometimes interchangeably. This is a brief overview of  three of them for future reference.

The Facade

The Facade defines a single, simplified interface over one or more subsystems.  Common usage of this is simplifying a remote system’s interface.

The Adapter

The Adapter changes (aka adapts) the interface of a class to match what is expected by a caller.  I have used this in the past to provide a common interface for getting/setting the value of web controls.

The Proxy

The Proxy stands in for another class, intercepting the call and then usually passing the call on to the class the proxy is representing.  Common usage of this is a proxy defined for WCF service or an NHibernate proxy for lazy loading.  The end result is additional behavior, like remoting complexities or lazy tracking, are injected into the the call stack without the user of the proxy having to know about it.

An Integration Story

0
on

My current project has me building a system to allow an external partner to integrate with our order application.  Right now, the end users have to go out to the partner’s site, get a list of new orders and manually enter them into our system.  The entire process is inefficient and distracts people away from their normal duties.  When complete, the integration will allow the partner to send orders directly to our system without human intervention (in most cases).

There are several ways to do integration.  Enterprise Integration Patterns outlines 4 at the start of the book: File Transfer, Shared Database, Remote Procedure Invocation (RPC), and Messaging.  We chose a mix of RPC and messaging.  The RPC via web services was selected as the way we communicate with the partner mainly because the partner already has an infrastructure built around web services.  Internally, we use a mix of web services and pub/sub messaging via MassTransit.

The architecture for the solution has four main parts: an external facing web service that the partner calls, a windows service for workflow (MassTransit saga) and integration business logic, a web service into our primary application, and a web service the external partner hosts for us to send updates to. There are many benefits to this architecture.  The external facing web service can be placed in a DMZ which only allows inbound calls to be routed to MSMQ, the windows service can be taken offline for maintenance without affecting the partner’s ability to send orders, loosely coupled components with clear and distinct responsibilities, and each part can be scaled independent of the other parts.

The order process is kicked off by the partner calling our web service and sending over a message for a new order.  In addition, the partner calls the web service once for each line item on the order.  Our web services takes data from these calls, transforms it into an object model, validates the data, and publishes messages via MassTransit.  The windows service has a saga that consumes the messages from the web service.  When the saga determines all the pars of an order have arrived (the order  and its line items), it calls a web service in our primary application to create the order.  At this point, the users can go in and do what they do with the orders.  As the orders progress thru the order application, messages are published about state changes.  The saga in the windows service consumes these messages and sends updates back to the partner’s web service.

In the end, the integration should add significant business value by increasing the overall efficiency of our employees and reducing errors caused by manual data entry.

Introduction, Say Hello

0
on

So I have decided to get more involved with the community by blogging.  This is my introduction to the world.

My name is James and I am a software developer in central Texas.  My professional interests include enterprise integration, custom application development, agile processes and general best practices.  Personal interests are my family, hiking/camping, fitness and healthy living, and snow boarding.

The majority of my posts will focus on my professional interests, products I use, and the discussions I have about technology.  Through this blog, I hope to spark constructive discussion, help people solve problems, and introduce others to the concepts/topics I consider important to my career.

Thanks for reading and please bare with me as I improve my writing ability.