From: Gavin_King/Cirrus%<CI...@ci...> - 2002-05-29 08:13:32
|
Now that 1.0 is functionally complete, i'll just outline the kind of things I'm thinking will go into 1.1. * Serializable Session * Referenceable SessionFactory * normalized table per subclass relational model * smarter fetching We need serializable sessions to support a nice programming model when using hibernate long transactions in - servlets configured for http session failover or - stateful session beans. Unfortunately this will be quite tricky to implement because we need to reconstruct all the Session's references to instances of ClassPersister, CollectionPersister at deserialization. *yick* We need a referenceable SessionFactory to support the kosher J2EE programming model. (ie. the application obtains the SessionFactory from JNDI.) I AM LOOKING FOR A VOLUNTEER TO START IMPLEMENTING THIS...... The last two items should fall out fairly easily from a general refactor / remodel of the various bits of code that render SQL SELECTs. There are four places this is done at present - directly on cirrus.hibernate.impl.ClassPersister - directly on cirrus.hibernate.impl.CollectionPersister - on cirrus.hibernate.query.Query - on cirrus.hibernate.impl.ByIDQuery By default hibernate "fetches" one object in each row of a ResultSet. If you happen to be using a database which supports ANSI-style outerjoins, you may force hibernate to fetch a one-level-deep object graph in a single fetch (by setting hibernate.use_outer_join). But not from a query. Urrrghhh. Did that make any sense? Consider: s.find("select foo.bar.baz.qux from foo in class Foo where foo.count=1") if there were 5 instances of Foo with count==1, this query would require 1 SELECT statement. However: s.find("select foo from foo in class Foo where foo.count=1") would require 1 + 5 + 5 = 11 SELECT statements! The first select would fetch the root instances of Foo. The next five selects would fetch instances of Bar and Baz (ie. children one and two levels deep). The next five selects would fetch instances of Qux (which have no children). On the other hand, if hibernate.use_outer_join=false, 1 + 5 + 5 + 5 = 16 SELECTs would be required. I can quite easily implement arbitrarily-deep fetching so that we reduce this to 1 + 5 = 6 SELECTs. (And I might do this tonight, actually.) Optimally we could do it in a single select. That would require some refactoring (unifying Query and ByIDQuery). Now, if all this sounds like a mess ... well .... it _is_ ..... but its not as bad as it sounds. The way Hibernate is structured its a simple matter of rendering the right SQL, which is a fairly easy problem. The actual code that loads objects from ResultSets is quite capable of accepting more complicated fetches. In my defence, I would like to point out that my aims for performance (in the early stages of the project) where only to compare favorably with the performance of CMP entity beans or handcoded JDBC. Clever fetching algorithms were a little beyond scope. There are advantages to this approach. Currently people have a nice API and programming model to develop applications with - and they can expect performance similar to what they are used to from other common approaches. As the Hibernate develops, they can expect their applications to get faster, with no extra work on their part! (A couple of people already saw this happen in the last release.) Still, this is probably the messiest part of the project at present and the time is ripe for improvements. Anyone want to sign up for either of the first two tasks? Gavin |