www.flickr.com
Michael Kovacs' photos More of Michael Kovacs' photos
Recommend Me Cable Car Software logo

Wednesday, May 17, 2006

Kodo 4.0 & WebLogic EJB3.0 Tech Preview

After many months of hard work by the WebLogic and Solarmetric teams BEA released Kodo 4.0 and WebLogic Server EJB3.0 Tech Preview yesterday. Kodo 4.0 is a major release which includes support for EJB3.0 persistence (JPA 1.0). What this means is that you can take Kodo 4.0 and use it with any Java EE 5.0 application server as the persistence provider for your entities.

Additionally we released a preview version of WebLogic Server that integrates this same Kodo 4.0 product and adds support for the rest of the EJB3 spec. Support for injection, interceptors, and some of the Java EE 5.0 technologies are there. For more information check out the edocs. Though not a final release developers can get started using EJB3 technologies in WLS today with a full production ready implementation coming at the end of this year or early next year.

You can download both Kodo 4.0 and the tech preview at:

http://commerce.bea.com/products/wls-techpreview.jsp
http://commerce.bea.com/products/kodo_latest.jsp

Also check out http://dev2dev.bea.com for more information and articles as well as links to newsgroups for questions/answers.

And by all means feel free to provide feedback either to myself here or email me: mkovacs at bea dot com.

Enjoy!

Monday, May 01, 2006

Rails realities part 12 (Active record, the relationship breaker, create em and leave em)

I recently was trying to activate optimistic locking on my rails model classes but have been receiving optimistic concurrency errors that aren't readily reproduceable. After looking into my code a little further I realized that now might be a good time to explore polymorphic relations to address some ugly design decisions that I'd made last October while learning ruby/rails and just trying to get an application off the ground. Very simply I have an Address class which has need to be involved in "has_one" relations to more than one class. So in order to not pollute my Addresses table with more than one FK I decided to have the other sides of these relationships to hold the FK columns. So my tables look like this:

addresses
:id

loan_roles
:address_id

loan
:mailing_address_id

So to model these relationships active record requires the the side holding the FK column is the "belongs_to" side of the relationship. So I have the following code:

class LoanRole
belongs_to :address
end

class Loan
belongs_to :mailing_address,
:class_name => "Address",
:foreign_key => 'mailing_address_id'
end

So the fallout here is that I need to actively manage this address information. A save from Loan or LoanRole won't cascade the save operation to the related address classes. And since I was having problems with optimistic concurrency I thought that perhaps cutting down on the number of save operations that I'm doing can only help. I recently upgrated to rails 1.1.2 (not voluntarily as I blogged about before) and I thought now would be a fine time to cleanup this earlier mess and migrate my schema to take advantage of the new polymorphic relations in active record. So my relations can change from belongs_to to the proper has_one by making the following change to my database schema:

addresses
:addressable_type
:addressable_id

What this allows me to do is to have one FK column in addresses and have a relation to more than one class by including a "type" column. There are drawbacks to this approach (like not being able to share object instances between classes, that is I can't have Loan.mailing_address be the same value as LoanRole.address). That aside I thought that this would be a fantastic way to clean up my code and not have to manage the cascading of save operations.

My model objects now become:

class LoanRole
has_one :address, :as => :addressable
end

class Loan
has_one :mailing_address,
:class_name => 'Address',
:as => :addressable
end

OK so with that backdrop (not really necessary but I thought someone out there might appreciate a brief overview of polymorphic relations), I get into the topic of today's post:

Active Record does not cascade save operations in has_many relations after the initial save



I was surprised to find this out but after thinking about it for a minute it makes sense. AR doesn't do any dirty field checking and instead always saves all attributes to the DB. In order to cascade save operations ons collection based relations you'd have to implement a dirty flag. But what's kind of sucky is that you get lulled into believing that AR does manage your relations for you because it does cascade the initial save operation when you build up a hierarchy of related objects. But once that first save is over AR does its best Sam Malone impression and gets the f**k out of dodge for any of your has_many relations. It will continue to cascade save operations to any has_one relations you may have but your has_manies are out of luck.

So for those that are visual like me here's a synopsis:

class Parent
has_many :foos <-- AR will calls save on foo objects on the first parent.save calls but will not call save of foo objects on subsequent save calls on parent

has_one :bar <-- AR will call save all the time

end

Where this became an issue in my object model was Loan has_many -> Lenders (LoanRoles) and LoanRole has_one address. In my current code I was always saving things explicitly so when I made the switch to polymorphic relations I assumed a top level save would do all the work for me and after it didn't I spiraled down the rat hole that is now this blog post.

After discussing it further with one of the rails core team members he suggested that adding dirty field checking would make a good plugin for AR and suggested I get to work :-). Unfortunately I don't have the time right now but I can't imagine I'd be the only one that would be happy to see dirty flags and cascading save operations work on all parent -> child relation types as well as from child -> parent if you declare that you'd like that on the relation definition.

This page is powered by Blogger. Isn't yours?