From: Gavin K. <ga...@ap...> - 2002-09-12 09:17:50
|
Hi everyone. I've created an experimental ODMG3 API for Hibernate. Unfortunately I don't own a copy of the ODMG spec (you have to *buy* it, unfortunately) so I'm not 100% sure of some semantics. Also, some concepts don't map perfectly to an O/R tool. The main missing thing is an ODMG-style OQL. I don't think Hibernate's query language is very far removed from OQL but there are some differences (particularly collections). I would need some proper OQL documentation before we could start to support the ODMG style syntax because the ODMG implementations I've investigated don't seem agree on some of these points. Another issue is persistence by reachability. Mapping all associations with cascade="save/update" (also a new feature) would come close to the ODMG programming model but perhaps we should allow some setting which forces cascade to *default* to "save/update". Hibernate collection wrappers now implement the ODMG interfaces, ie DCollection, DMap, DList, DSet, etc. To do this, I needed collection-filtering functionality. I saw that this was useful for Hibernate itself, since it lets you take a large, uninitialized collection and load up only the elements you are interested in. Accordingly Ive added filtering methods to the Session interface like: filteredCollection = session.filter(collection, query) A filter is just a query where you can refer to "this", the collection element. So, for example: blackCats = session.filter( cat.getKittens(), "where this.color='black' order by this.name" ); rivals = session.filter( cat.getPotentialMates(), "select this.mate" ); Now, I certainly don't propose to make the ODMG API the recommended way to use Hibernate. Hibernate's own API is much more expressive. It would be nice, though, if we could find someone here with a better knowledge of the ODMG spec to take ownership of this feature and develop it towards fuller compliance. Gavin |
From: Anton v. S. <an...@ap...> - 2002-09-13 05:45:24
|
> Accordingly Ive added filtering > methods to the Session interface like: > > filteredCollection = session.filter(collection, query) > > A filter is just a query where you can refer to "this", the collection > element. So, for example: > > blackCats = session.filter( cat.getKittens(), "where this.color='black' > order by this.name" ); Slightly tangential question about this: how straightforward (or not) would it be to support an object as the filter parameter? I use a Predicate interface in my own code: public interface Predicate { // Apply predicate to a specified object and return boolean result boolean apply(Object o); } This can be used to create arbitrary objects to filter on any condition - I use it for filtering Java collections and arrays. You can also use it inline, e.g.: blackCats = session.filter( cat.getKittens(), new Predicate() { public boolean apply(Object o) { return o.color.equals("black"); } }); I don't know anything about what Hibernate is doing when it's retrieving & filtering a query - if something like this wouldn't require too much internal rearranging, I might take a stab at it, since it would fit in with some of the other code I'm using. In fact it came up in some code which I've just installed for testing, and I ended up building a query string to do it instead. In some cases, I prefer the approach I've described since it's subject to static checking, supports refactoring, etc. Anton |
From: Christoph S. <ch...@mc...> - 2002-09-18 14:01:14
|
Hi Gavin! ----- Original Message ----- From: "Gavin King" <ga...@ap...> To: "hibernate list" <hib...@li...> Sent: Thursday, September 12, 2002 11:16 AM Subject: [Hibernate] New features: Hibernate ODMG + collection filters > only the elements you are interested in. Accordingly Ive added filtering > methods to the Session interface like: > > filteredCollection = session.filter(collection, query) > > A filter is just a query where you can refer to "this", the collection > element. So, for example: > > blackCats = session.filter( cat.getKittens(), "where this.color='black' > order by this.name" ); > rivals = session.filter( cat.getPotentialMates(), "select this.mate" ); > Could you also add a method session.filer(Collection, Query)? regards chris |
From: Gavin K. <ga...@ap...> - 2002-09-19 11:23:00
|
Yeah, I knew this would come up.... but I'm not quite sure of exactly how to structure the API. I was thinking along the lines of: Query q = session.createQuery(queryString, collection); or: Filter f = session.createFilter(queryString); f.setCollection(coll); List results = f.list(); where Filter extends Query. But now you've raised another possibility. I don't think I like your suggestion because it changes the way Queries are called. (ie. you go to the session to create the query and then go back to the session again to call it.) The first option is good because it lets us compile the query from the createFilter method (we know exactly which collection role to use) and doesn't require any new interfaces. The second is good because it would let you reuse the same Filter object multiple times for different collections. I am leaning towards the first option. Theres an implementation issue that comes up here: I intend to eventually have the query be compiled from the createQuery() method. That way you recieve any compilation exception from that call and then any execution exception from list() or iterate(). This would also mean I would factor a bunch of code out of SessionImpl and onto QueryImpl (a good thing). Currently, however, the query is compiled on the first call to list() or iterate(). (Note that Hibernate caches compiled queries in a WeakRefHashMap on the session factory.) > > Could you also add a method session.filer(Collection, Query)? > > regards > chris |