Most of those who pair programmed with me know that I'm not very fond of debugging code by stepping through breakpoints inside an IDE. I'd much rather construct hypotheses on why the code is failing and systematically test them with carefully placed assertions and print statements.

One reason for that is the observer effect of debugging: the execution environment can be a little different, timings are usually changed, object inspectors might end up calling methods with unwanted side-effects and so on.

The last point is a particularly important one to keep in mind when dealing with code that's been enhanced for Transparent Persistence.

Let's say we have built the latest and greatest library management application and now want to put a web front end on top of it. We've been following web development trends and so we know AJAX is a must these days. We just need some simple way to transfer the objects from the server to the browser javascript runtime: JSON to the rescue. Good thing we can reuse some reflection based JSON serialization code we had laying around.

We write a quick spike to see how well it works:

    Dim book = New Book("The God Delusion")
book.AddAuthor(New Author("Richard Dawkins"))

Console.WriteLine(New JSONSerializer().Serialize(book))

Which give us the expected output:

	{ _title: "The God Delusion", _authors: [{ _name: "Richard Dawkins" }] }

We try one more spike to convince us we can get JSON out of a db4o query result:

    Using db = OpenDatabase()
For Each book In db.Query(of Book)()
Console.WriteLine(New JSONSerializer().Serialize(book))
Next
End Using

Unfortunately this gives us something completely unexpected and it's not the Spanish Inquisition:
	{ _title: null, _authors: null }

We place a breakpoint inside the loop so we can inspect the book instance:

Debugging TA With VB

It sure looks right and oddly enough we get the right output this time:

	{ _title: "The God Delusion", _authors: [{ _name: "Richard Dawkins" }] }

What's going on?

Transparent Activation is going on or rather NOT going on:

  1. Our Book and Author classes were enhanced for Transparent Activation, Db4oTool injected the code required to implement IActivatable as well as the code that transparently activates the object before any field access;
  2. JSONSerializer uses reflection to access objects fields;
  3. Reflection completely bypasses any code introduced by Db4oTool which explains the "{ _title: null, _authors: null }" output, the object was never activated;
  4. When inspecting an object in the debugger watch window its properties are accessed;
  5. Accessing a property of our enhanced Book object causes its *transparent* activation which also explains why we got the right output aftewards;

Ok, now that we have a logical explanation for what's happening how do we get our application to work as expected?

Since JSONSerializer bypasses activation we have to ensure the object graph is completely activated before JSONSerializer gets to see it:

    Using db = OpenDatabase()
For Each book In db.Query(of Book)()
db.Activate(book, Integer.MaxValue)
Console.WriteLine(New JSONSerializer().Serialize(book))
Next
End Using
And that's it.

Hopefully that will save you some frustration next time you need to debug Transparent Persistence enhanced code or to have it interacting with reflection based libraries.

The complete code can be found here.

Have fun!