So I finally took a look at Hibernate, the new kid on the block for lightweight persistance in Java. The docs described something so hideously complex, I stopped skimming after Chapter 1 (of 19). If I want to have object based access to a database, why do I need to use Tomcat, code generators, and XML config files? I just want simplified database access ferchrissakes!
I'm still twitching in disbelief. Class::DBI may have a lot of dependencies on modules from CPAN, but the interface itself is simple, easy to understand, and easy to use -- especially in the simple case. And I don't need to redefine fundemental constants of the universe in the process.
Remember, Hibernate is a reaction to EJB, which I believe was originally a conspiracy between Pope John XIII and the Byzantine Empire to divide up Africa.
This provides two constraints, and id generation from the program rather than the database. Doing those things in Class::DBI would require writing a constraint method and a trigger method, and is generally more confusing. One idea I've had is to write something that would allow Class::DBI classes to be configured with an XML file like this. So far though, I haven't used the constraints enough to make it worth the trouble.<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapp ing>
<class name="net.sf.hibernate.examples.quickstart.Cat" table="CAT">
<!-- A 32 hex character is our surrogate key. It's automatically
generated by Hibernate with the UUID pattern. -->
<id name="id" type="string" unsaved-value="null" >
<column name="CAT_ID" sql-type="char(32)" not-null="true"/>
<generator class="uuid.hex"/>
</id>
<!-- A cat has to have a name, but it shouldn' be too long. -->
<property name="name">
<column name="NAME" length="16" not-null="true"/>
</property>
<property name="sex"/>
<property name="weight"/>
</class>
</hibernate-mapping>
Class::DBI is pretty good for a simple O/R mapper, but Hibernate has a much more complete feature set. If there was a full-featured port of Hibernate for Perl, I would definitely be using it instead of Class::DBI.
Re:overstating it a bit?
tmtm on 2004-08-10T18:38:22
Personally, my brain switches off at the sight of XML, so I find it really hard to read that example at all. Seriously.
I'm not entirely convinced that
__PACKAGE__->constrain_column(name => qr/\w{1,16}/);
is that much more confusing than their XML, but the constrain_column stuff is fairly simplistic at the minute (interface wise. It's actually designed so that my base class can set up certain things to make it hook into CGI::Untaint in nice ways). I'm certainly tempted to allow:
__PACKAGE__->constrain_column(name => sub { length = 16 });
I'd certainly be interested in a list of Hibernate features that you'd like to see in Class::DBI. I tried reading their docs, but my brain shut down.Re:overstating it a bit?
tmtm on 2004-08-10T19:03:43
> __PACKAGE__->constrain_column(name => sub { length = 16 });
That was even easier than I'd expected. (Other than perl needing to disambiguate via length()...)
} elsif (ref $how eq "Regexp") {
$class->add_constraint(regexp => $col => sub { shift =~ $how });
|+ } elsif (ref $how eq "CODE") {
|+ $class->add_constraint(
|+ code => $col => sub { local $_ = $_[0]; $how->($_) });
} else {
TonyRe:overstating it a bit?
perrin on 2004-08-10T19:49:50
I'm really not a big XML fan, but I think it's applied in a very reasonable way here. The constrain_column() method requires more thinking than specifying it in the XML does. I would ideally like to see more of the stuff that Tim Bunce did to auto-detect database constraints folded into Class::DBI::SomeDBD classes. He had stuff to detect the column length, not-NULL constraints, etc. and build the same constraints in the CDBI classes.Hibernate has many good features. Here are some of the ones I would most like to have:
- Built-in support for mapping of inheritance.
- Efficient many-to-many support, including support for search criteria on the mapping table.
- Support for flexible object and query caching. (I plan to work on this.)
- Built-in support for fetching a graph of related objects in one SQL statement (like the recent question on the mailing list about fetching an object and it's might_have relation in one shot).
- Optimistic locking. This wouldn't be very hard to add, I think.
- More extensive support for collections, like delete_from_* (as opposed to add_to_*) and mapping of related objects to sets, rather than just arrays.
Re:overstating it a bit?
djberg96 on 2004-08-10T20:50:23
This is why I'm becoming less of a fan of ORM's in general every day. To me having XML config files like this feels like I'm writing the DDL *twice*.I'm now beginning to contemplate a strictly bottom-up ORM approach, where you would get this information dynamically instead of by hand.
Actually, I'm starting to think ORM's are an unnecessary layer of goo.
Re:overstating it a bit?
pdcawley on 2004-09-05T17:25:22
Down that road lies Pixie.Re:overstating it a bit?
ziggy on 2004-08-11T00:37:54
Whatever. I really don't care if Hibernate or Hibernate's docs are making my skin crawl. I've been programming long enough to know that I'm looking for a thin shim that converts application-level concepts into database actions, and that I want that as a single aspect in my codebase. If the Hibernate folks are telling me that I need a full-bore seven layer burrito to use their code, I'd rather write my own CDBI-inspired abstraction instead.Hibernate doesn't need Tomcat, although Tomcat is a common place to use it.I don't have any quibbles about autogenerated code. I do mind that I need to install yet another dependency to get code generation to work before I can even kick the tires.It uses code generation, but so Class::DBI. In both cases, the code generation is done at run-time. It does use XML config files, and I kind of like them.I don't want to touch the programming-via-XML-config-file bikeshed. If it works for you, then by all means use it. For me, I don't want to spend the effort -- however minimal -- switching gears between reading code and reading XML metacode.
Re:overstating it a bit?
perrin on 2004-08-11T04:12:21
Mapping a data model with any complexity between objects and a database is just not that simple a problem. Hibernate is pretty easy to use. It might look complex to you if you are not already familiar with current Java concepts, in the same way that Class::DBI leaves many Perl newbies scratching their heads. There is a basic assumption that you've already written some Java apps with databases and objects and thus are familiar with the terms and libraries. I wouldn't hire a Java coder who didn't know Tomcat, and the code generation library being used is pretty common in Java open source projects these days.I can't see complaining about its dependencies being fair, considering how many Class::DBI has. And it's hard for me to imagine a perl interface for declaring all of that metadata that would be any easier to read than the XML config. Plus it's neat to write classes without any database awareness in them at all and then magically persist them by writing this separate config.
All I'm saying is, don't dismiss it as needlessly complex so quickly. Hibernate is only tricky in the places where the underlying problem it's trying to solve is tricky. It has some good ideas and has really had a big impact on how object persistence is done in Java.
Re:overstating it a bit?
ziggy on 2004-08-11T04:59:52
I'm still not swayed. Let's just call this a bikeshed and move on.I've written about three database abstraction frameworks in the last two years, none of which have had a dependency aside from DBI / database drivers. So it is possible, even if it doesn't scale up to handle every degenerate schema on the planet.
That's fine. What I'm looking for is probably outside the scope of what Hibernate is trying to deliver (or, best case, what the Hibernate docs have chosen to focus on). I can live with that. I've found that ~80% of the benefit is not from purging SQL code from an application and replacing it with an ORM framework. The primary benefit comes from programming in an aspect-like manner, separating the generic database code from the schema management, and separating schema management from the rest of the application. With that big a win, I haven't found the need use ORM frameworks.
But that's just me. I could be wrong here.
I actually *like* the XML file since you can autogenerate the db schema with it, and also autogenerate the pojo's with it. You're right, the docs are very intimidating...but there are some good beginner articles linked from the hibernate.org site which I found more useful.