You can subscribe to this list here.
2002 |
Jan
(2) |
Feb
(157) |
Mar
(111) |
Apr
(61) |
May
(68) |
Jun
(45) |
Jul
(101) |
Aug
(132) |
Sep
(148) |
Oct
(227) |
Nov
(141) |
Dec
(285) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2003 |
Jan
(518) |
Feb
(462) |
Mar
(390) |
Apr
(488) |
May
(321) |
Jun
(336) |
Jul
(268) |
Aug
(374) |
Sep
(211) |
Oct
(246) |
Nov
(239) |
Dec
(173) |
2004 |
Jan
(110) |
Feb
(131) |
Mar
(85) |
Apr
(120) |
May
(82) |
Jun
(101) |
Jul
(54) |
Aug
(65) |
Sep
(94) |
Oct
(51) |
Nov
(56) |
Dec
(168) |
2005 |
Jan
(146) |
Feb
(98) |
Mar
(75) |
Apr
(118) |
May
(85) |
Jun
(75) |
Jul
(44) |
Aug
(94) |
Sep
(70) |
Oct
(84) |
Nov
(115) |
Dec
(52) |
2006 |
Jan
(113) |
Feb
(83) |
Mar
(217) |
Apr
(158) |
May
(219) |
Jun
(218) |
Jul
(189) |
Aug
(39) |
Sep
(3) |
Oct
(7) |
Nov
(4) |
Dec
(2) |
2007 |
Jan
|
Feb
(2) |
Mar
(7) |
Apr
(3) |
May
(3) |
Jun
(8) |
Jul
(1) |
Aug
(1) |
Sep
|
Oct
(4) |
Nov
(7) |
Dec
|
2008 |
Jan
(1) |
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
(2) |
Aug
(4) |
Sep
|
Oct
(2) |
Nov
(1) |
Dec
|
2009 |
Jan
(6) |
Feb
|
Mar
(1) |
Apr
(2) |
May
(1) |
Jun
(1) |
Jul
(10) |
Aug
|
Sep
(1) |
Oct
(1) |
Nov
|
Dec
(3) |
2010 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(2) |
Oct
|
Nov
|
Dec
|
2012 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2015 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Gabe H. <gjh...@ya...> - 2002-02-16 05:03:58
|
The new assert keyword in Java 1.4 causes warnings when compiling Hibernate. I believe that TestCase.assert(boolean, String) should be changed to TestCase.assertTrue(boolean, String). This follows what JUnit has done (http://sourceforge.net/project/shownotes.php?release_id=36181) and removes these warnings. I have changed all references locally so that I can continue to compile with 1.4. Also, why don't you use JUnit as the test harness? Thanks, Gabe Hicks __________________________________________________ Do You Yahoo!? Yahoo! Sports - Coverage of the 2002 Olympic Games http://sports.yahoo.com |
From: Gavin_King/Cirrus%<CI...@ci...> - 2002-02-15 15:02:23
|
To simplify matters just a little bit, think of a Session as a transaction. Open a Session at the start of a transaction, close it at the end. The Session retains a JDBC connection for only as long as your transaction. This is exactly the same as any other common J2EE approach (direct JDBC from a servlet or session bean, CMP entity bean). J2EE applications are characterized by short running transactions. Typically applications retrieve data in one transaction, display it to the user, recieve user input and then modify data in a second transaction. Hibernate is also meant to be used in this way. My *suggested* approach is to use the same kind of architecture recommended for entity beans. Namely, MVC where V=JSP/XSLT/VTL and C=servlet, Session bean facade (perhaps command pattern) and then business objects holding persistent data. Unfortunately, there are numerous well documented problems with Entity beans. You could instead use Hibernate to persist your business objects, which could just be vanilla JavaBeans instead of Entity beans. You may use hibernate-persisted objects in all the ways you can use Entity beans (and more) except for the fact that they are not, by default, remoteable (arguably a very good thing). Or you can use Hibernate to implement BMP entity beans and get support for concepts like (sub)collections, dependent objects, object graph to a single row, etc. This will allow a *much* finer grained object model than what is normally possible when using entity beans. Whatever approach you use, you should not leave the Session open longer than you would keep an open JDBC connection when using some other persistence mechanism. A future version of Hibernate will extend the support for optimistic locking (ie. versioned data) to cover the possibility of retrieving business objects in one transaction (Session), editing them in the UI layer, sending them back to a new Session and updating the datastore. You can already do this kind of thing yourself now, using Session.copy() for the last step, but what you would really like is to be able to update a whole graph of objects with one call to the Session. Note that this kind of approach is NOT a very typical J2EE approach. I happen to like this it very much, even though it increases coupling between application layers. Sorry if this was badly-written; it is very late here :) peace Gavin |
From: Kononen M. <Mat...@no...> - 2002-02-15 12:16:35
|
Hi, I'm evaluating Hibernate. You claim that it performs well and it is very suitable for J2EE-applications. But after I've read the documentation I doubt it. (Maybe I have misunderstood something.) When you need to update some data, you have to keep the Hibernate session alive between reading from DB and modifying Java objects. Then the Hibernate session knows what to update when it is commited. It's OK if you have only few users in your system. Let's consider J2EE case. The problem is that a Hibernate session reserves one DB connection. If it is possible that your system has hundreds of concurrent users updating the database, all connections of the connection pool become reserved. Or have I misunderstood something? Do I actually need to keep the Hibernate session alive or do the sessions reserve connections for long periods at all? Matti Kononen mat...@no... P.S. I'm using Hibernate with Solid Embedded Engine. The attached Java file covers its SQL dialect. For more info see www.solidtech.com. |
From: Gavin_King/Cirrus%<CI...@ci...> - 2002-02-15 05:26:27
|
Ouch! I had hoped not to find more bugs like this at this stage. We _really_ need a test for this. It was a simple mistake that would have been picked up if that code had been covered by the tests. |
From: Gavin_King/Cirrus%<CI...@ci...> - 2002-02-15 05:23:46
|
As per Paul's request, there are now bidirectional associations in the version in CVS. I havn't implemented validation of the associations yet, but I really feel like thats an important feature. Bidirectional associations must be either: Set on one end, single valued the other end OR Set on both ends. The semantics of something more complicated than that (eg. Map one end, array the other are just a bit too questionable.) How it works is you manually map a many-to-one and a nested one-to-many to the same table column, or two nested many-to-manys to the same association table. You mark one end of the association with the "mirror" attribute (an attribute of the "set" element). The end marked as mirror is just a view of the association. Changes made at that end are _not_ persistent. Does anyone know a better name for that attribute? In other news: (1) The latest version in CVS squashes a bunch of bugs that tests were missing. (2) I've almost finished the XML generation functionality for people to have a look at. I'm probably _not_ going to implement XML to objects right now since there is already enough work supporting the existing functionality to keep me plenty busy for a while. I will release a new version as soon as I've finished writing some new tests and removing a hardcoded path from the XML generation stuff. Would people please try out the version in CVS with their code and see if any new bugs exist. |
From: Paul S. <pau...@ne...> - 2002-02-14 14:59:35
|
Hi, I think there's a problem with the deferred loading where we encounter a class that's already been "resolved". Again I'm not 100% sure of the fix but it works for me. A diff below. PaulS :) =================================================================== RCS file: /cvsroot/hibernate/Hibernate/cirrus/hibernate/impl/RelationalDatabaseSession.java,v retrieving revision 1.82 diff -w -r1.82 RelationalDatabaseSession.java 593c593 < if ( !entries.containsKey(deferredKey) ) { --- > if ( !entries.containsKey(p) ) { |
From: Gavin_King/Cirrus%<CI...@ci...> - 2002-02-14 11:47:53
|
Thanks for that Paul. That bug is now fixed in CVS (along with a test). Several problems that have come up are to do with the new map file reading / schema generation code which was introduced in the last release. Hopefully we will have all these problems ironed out soon for the next release. |
From: Paul S. <pau...@ne...> - 2002-02-14 11:10:52
|
Okay, I think we're (almost?) on the same page. I'm *not* advocating a heavy framework that does a whole bunch of magic for you, like maintaining integrity of bidirectional associations. Where a bidirectional association exists simply tweak the relational mapping. For example to avoid "doubling up" on foreign keys to provide visibility from both ends as is done now in a one-to-many. This gives the possibility of integrity checking, which in my experience is very useful once the database gets large and/or complex. No extra API should be needed - it's still non-intrusive. Hibernate shouldn't manage the integrity of the association - the programmer still has to ensure both ends match. The code should be no different if the class is being persisted or not, at least in this respect. PaulS. Gavin_King/Cirrus%CI...@ci... wrote: >>Your statement about such a concept being alien to idiomatic Java to me >>seems to be putting the horse before the cart. While true, I think that >>it loses sight of what we're building - for me at least that's the >>object model. >> > > Hmmmmmmm. Perhaps. I was very keen to stay with the current approach of > just adding persistence to Java, not trying to add any extra semantics, not > trying to build an application framework. If you manage to convince me that > its possible to do bidirectional associations with no xtra API then I'm > sold on it. > > >>There are ways to do this, and all the commercial O/R tools that I've >>used support this. Basically the association is "managed" from one end >>when it comes to persisting the association - and it's straightforward >>to tell when things are screwy. >> > > Interesting. The thing I've used that does bi-directional associations - > namely Visual Age for Java's EJB associations - uses a generated class that > ensures association integrity from _both_ ends. Its arguably not a good > design and is not consistent with the approach in this project. (I think > they have a more difficult problem though, because the ends of the > association might be remote.) > > >>I don't see the problem. Your code (i.e. not Hibernate, the users code) >>is still responsible for making sure all the persistent objects point >>to the right places. This is true without persistence, and I wouldn't >>expect the persistence layer to do this for you - that would be intrusive. >> > (snip) > >>Yep - and that's fine. And if you wanted to you *could* do a consistency >>check quite transparently. There's actually huge advantages in being >>able to do that. >> > > Yeah, I was thinking about this on the way home, after firing off that last > email and thinking "Well, you could just let the users manage integrity > themselves, but validate the state before we persist anything" ... All we > would need to implement this approach is some code to validate the > association somewhere. There wouldn't need to be any other changes to the > runtime engine and there wouldn't need to be any API. This would make me > happy. > > I've been thinking of one-to-many associations while I've been writing > this, but I think much the same thing goes for many-to-manys (where its a > collection on each end - mapped to the one table). |
From: Gavin_King/Cirrus%<CI...@ci...> - 2002-02-14 10:07:25
|
>Your statement about such a concept being alien to idiomatic Java to me >seems to be putting the horse before the cart. While true, I think that >it loses sight of what we're building - for me at least that's the >object model. Hmmmmmmm. Perhaps. I was very keen to stay with the current approach of just adding persistence to Java, not trying to add any extra semantics, not trying to build an application framework. If you manage to convince me that its possible to do bidirectional associations with no xtra API then I'm sold on it. >There are ways to do this, and all the commercial O/R tools that I've >used support this. Basically the association is "managed" from one end >when it comes to persisting the association - and it's straightforward >to tell when things are screwy. Interesting. The thing I've used that does bi-directional associations - namely Visual Age for Java's EJB associations - uses a generated class that ensures association integrity from _both_ ends. Its arguably not a good design and is not consistent with the approach in this project. (I think they have a more difficult problem though, because the ends of the association might be remote.) >I don't see the problem. Your code (i.e. not Hibernate, the users code) >is still responsible for making sure all the persistent objects point >to the right places. This is true without persistence, and I wouldn't >expect the persistence layer to do this for you - that would be intrusive. (snip) >Yep - and that's fine. And if you wanted to you *could* do a consistency >check quite transparently. There's actually huge advantages in being >able to do that. Yeah, I was thinking about this on the way home, after firing off that last email and thinking "Well, you could just let the users manage integrity themselves, but validate the state before we persist anything" ... All we would need to implement this approach is some code to validate the association somewhere. There wouldn't need to be any other changes to the runtime engine and there wouldn't need to be any API. This would make me happy. I've been thinking of one-to-many associations while I've been writing this, but I think much the same thing goes for many-to-manys (where its a collection on each end - mapped to the one table). |
From: Paul S. <pau...@ne...> - 2002-02-14 09:32:28
|
Hi, I found a problem when I had multiple indexes created on the same table, as all the index names are the same. I hacked in a fix that works for me, but I didn't study the code very carefully so I might be way off base. Diff output below. PaulS :) =================================================================== RCS file: /cvsroot/hibernate/Hibernate/cirrus/hibernate/impl/RelationalDatastore.java,v retrieving revision 1.41 diff -w -r1.41 RelationalDatastore.java 221c221,224 < private void initializeOneToManys() throws MappingException { --- > private void initializeOneToManys() throws MappingException > { > int[] tableIndexCounts = new int[ tables.size() ]; > 254c257,260 < indexes.add( collection.createIndex() ); --- > Index idx = collection.createIndex(); > int pos = tables.indexOf( idx.getTable() ); > idx.setName( idx.getName() + tableIndexCounts[pos]++ ); > indexes.add( idx ); |
From: Paul S. <pau...@ne...> - 2002-02-14 09:04:07
|
Hi Gavin, some comments below, but I think the main issues here are (1) the value of associations over just collections, and (2) how you might implement this either in a product or as a work-around. Below are my observations and *opinion*, I'd welcome other input on this. IMO associations are key - the fact that you happen to implement them using collections in Java is a mere detail. We work on an object model, then translate that into code. The kinds of things you mention might be possible, but I cannot see *why* you would want to do them. Your statement about such a concept being alien to idiomatic Java to me seems to be putting the horse before the cart. While true, I think that it loses sight of what we're building - for me at least that's the object model. Anyway, more comments below. PaulS :) Gavin_King/Cirrus%CI...@ci... wrote: > Hi Paul, > > Hibernate's associations are fundamentally uni-directional. The reason for > this is that Java object references and the Java collections framework only > permit navigation in one direction ie. dereferencing an object reference, > or retrieving an object from a collection. There is no way for an object to > determine if it belongs to a collection, or what other objects hold > references to it. It is _possible_ to implement a bidirectional association > in Java as a seperate class. At one (very early) stage there was even > something exactly like this in Hibernate. I threw the concept away because > it is just too alien to idiomatic Java. > > Now, it *would* be possible to do something like you suggest, and have two > seperate associations, which happen to map to the same database column. The > problem with that is that such a solution is very, very bugprone. If your > Master throws away the Set it was holding details in, and creates a new > Set, the details objects will still have references to the same Master. > When we come to persist this broken structure, the results will be > nondeterministic. There are ways to do this, and all the commercial O/R tools that I've used support this. Basically the association is "managed" from one end when it comes to persisting the association - and it's straightforward to tell when things are screwy. > Well, actually I lie. It *is* deterministic. The one-to-many association > always wins over the many-to-one association in the current implementation. > Those semantics are not guaranteed under a future, more efficient, > implementation of collections. > > There is _no_ way to fix this without creating new API classes that intrude > upon the business model. Or otherwise annoy you. For example, you wouldnt I don't see why this would be the case. Could you elaborate? > be able to pass collections seamlessly from one object to another and stuff > like that.... I don't see the problem. Your code (i.e. not Hibernate, the users code) is still responsible for making sure all the persistent objects point to the right places. This is true without persistence, and I wouldn't expect the persistence layer to do this for you - that would be intrusive. > If you really need a bi-directional association (if bi-directional > associations were really that essential then OO languages would have them - I won't touch that one. > and none do) then you can do any of the following > > 1. Detail has a many-to-one association to Master. Master can select its > Details using a query ( perhaps lazily, perhaps from > PersistentLifecycle.load() ) > > FROM detail IN CLASS pkg.Detail WHERE detail.master.id = ? Isn't this what happens anyway? > and then put them in a transient collection. (My favored solution.) > > 2. Master has a one-to-many association to Detail. Detail can get its > Master using a query (not efficient). > 3. Master has a one-to-many association to Detail. Master can set transient > backpointers on each Detail from PersistentLifecycle.load() > > All these solutions run the same risk of bugs as if they would be > implemented in the persistence layer. The difference is: they would be > application bugs - the persistence layer will still behave > deterministically. Yep - and that's fine. And if you wanted to you *could* do a consistency check quite transparently. There's actually huge advantages in being able to do that. > > I _guess_ we could fix the Schema generator to detect and remove duplicated > column names and let you do what you want to do .... It won't *break* > Hibernate, and it _does_ have quite str8forward semantics in this version > (ie. the bit about the collection end wining.) But if we fix it I would > much rather leave that feature undocumented. What do others think? |
From: Gavin_King/Cirrus%<CI...@ci...> - 2002-02-14 07:27:33
|
Hi Paul, Hibernate's associations are fundamentally uni-directional. The reason for this is that Java object references and the Java collections framework only permit navigation in one direction ie. dereferencing an object reference, or retrieving an object from a collection. There is no way for an object to determine if it belongs to a collection, or what other objects hold references to it. It is _possible_ to implement a bidirectional association in Java as a seperate class. At one (very early) stage there was even something exactly like this in Hibernate. I threw the concept away because it is just too alien to idiomatic Java. Now, it *would* be possible to do something like you suggest, and have two seperate associations, which happen to map to the same database column. The problem with that is that such a solution is very, very bugprone. If your Master throws away the Set it was holding details in, and creates a new Set, the details objects will still have references to the same Master. When we come to persist this broken structure, the results will be nondeterministic. Well, actually I lie. It *is* deterministic. The one-to-many association always wins over the many-to-one association in the current implementation. Those semantics are not guaranteed under a future, more efficient, implementation of collections. There is _no_ way to fix this without creating new API classes that intrude upon the business model. Or otherwise annoy you. For example, you wouldnt be able to pass collections seamlessly from one object to another and stuff like that.... If you really need a bi-directional association (if bi-directional associations were really that essential then OO languages would have them - and none do) then you can do any of the following 1. Detail has a many-to-one association to Master. Master can select its Details using a query ( perhaps lazily, perhaps from PersistentLifecycle.load() ) FROM detail IN CLASS pkg.Detail WHERE detail.master.id = ? and then put them in a transient collection. (My favored solution.) 2. Master has a one-to-many association to Detail. Detail can get its Master using a query (not efficient). 3. Master has a one-to-many association to Detail. Master can set transient backpointers on each Detail from PersistentLifecycle.load() All these solutions run the same risk of bugs as if they would be implemented in the persistence layer. The difference is: they would be application bugs - the persistence layer will still behave deterministically. I _guess_ we could fix the Schema generator to detect and remove duplicated column names and let you do what you want to do .... It won't *break* Hibernate, and it _does_ have quite str8forward semantics in this version (ie. the bit about the collection end wining.) But if we fix it I would much rather leave that feature undocumented. What do others think? Gavin |
From: Paul S. <pau...@ne...> - 2002-02-14 05:12:22
|
Hi, When I have a one-to-many in an object model, it usually gets implemented as a collection in the "one" class (e.g. a List) and a simple object reference from the "many" class. For example: public class Master { private List details; } public class Detail { private Master master; } I want to map this onto the database with just a foreign key in the detail table, plus an index field to maintain the ordering. How can I do this? I seemed to be able to manage this with 0.9.4, but with 0.9.5 I'm not so sure. If I do something like this: <?xml version="1.0"?> <!DOCTYPE hibernate-mapping SYSTEM "hibernate-mapping.dtd"> <hibernate-mapping> <class name="Master"> <id name="oid"> <generator class="hilo.long"/> </id> <list role="details"> <key column="master_oid"/> <index column="master_seq"/> <one-to-many class="Detail"/> </list> </class> <class name="Detail"> <id name="oid"> <generator class="hilo.long"/> </id> <many-to-one name="master"/> </class> </hibernate-mapping> ...then I end up with two foreign key references in the DETAIL table: 'master_oid' and 'master'. If I try to force the many-to-one to use the same column the schema generator tries to build a table with two columns of the same name: <many-to-one name="master" column="master_oid"/> Is this possible? How does the code work internally? Does it have the concept of "two ends of the same association", or does it just treat this is two totally independant associations. PaulS :( |
From: Phillip B. <phi...@cl...> - 2002-02-13 11:14:03
|
Gavin_King/Cirrus%CI...@ci... wrote: >The hardcoded value is a default. You can specify your own table/column >name for the HiLoGenerator. But, of course, the table generation tool >doesn't know about any others. What we would really want is for Datastore >to have a list of all the HiLoGenerators that were created while reading in >the mapping. I hadn't got up to this yet. > >(1) could you please put it in as a feature request >(2) any volunteers? > I've submitted both this and support for schemas as feature requests. In my battle with SF I seem to have submitted a duplicate of schema support - maybe some kind project admin could kill one of them for me? >That's not such a bad solution. A better one might be if we have some >schema="" attribute everywhere table="" appears and then have >getQualifiedTableName() as well as getTableName() on things.... its more >work though.....your suggestion is probably cool for now. > I like your idea of adding the schema attribute, that's why I've added it as a feature request. > >Just a guess ..... It kind of *looks* like this bug has to do with reusing >prepared statements for this JDBC driver. Hibernate keeps any prepared >statements it uses in a cache on RelationalDatabaseSession. You could >disable this cache by defacing >RelationalDatabaseSession.getPreparedStatement() and see if the error still >occurs. If it doesn't, perhaps some System property to disable cacheing is >in order.... > Haven't had enough time to look at this yet but I suspect you're right. Thanks for the help. Phillip B. |
From: Gavin_King/Cirrus%<CI...@ci...> - 2002-02-12 14:26:29
|
>Problem #1: Progress requires you to either always prefix table names >with a schema, or, alternatively use SET SCHEMA 'xxx' to set a default >schema for your session. Actually this issue really *should* have been addressed much earlier. I'm very happy you're looking at it now. Plenty of applications will need to access data in two diff schemas. I had sort of assumed it would just _work_ ... but at the very least the index generation is broken, as you point out below. Still, it looks like all these issues are to do with the table generation tool, and not the main persistence engine. >The next thing to break was the table name used for unique ids, >"hibernate_unique_key". This string is hardcoded into >RelationalDataStore and HiLoGenerator and needed the schema prefix. My >feeling is this table name should be part of the mapping rather than >hardcoded. Another idea was to make the table name an attribute of >Dialect. RelationDataStore looks reasaonbly easy to modify but I'm not >so sure about HiLoGenerator. Any comments? The hardcoded value is a default. You can specify your own table/column name for the HiLoGenerator. But, of course, the table generation tool doesn't know about any others. What we would really want is for Datastore to have a list of all the HiLoGenerators that were created while reading in the mapping. I hadn't got up to this yet. (1) could you please put it in as a feature request (2) any volunteers? >The last obstacle with the schema prefix was Collection.createIndex() >forms index names by added IDX to the table name. With a schema >prepended to the table name this resulted in index names which caused >SQL syntax errors. My quick fix for this was to get the createIndex >method to stip off the schema prefix when it created the index name. >I'm open to ideas for a better solution. That's not such a bad solution. A better one might be if we have some schema="" attribute everywhere table="" appears and then have getQualifiedTableName() as well as getTableName() on things.... its more work though.....your suggestion is probably cool for now. >Problem #2: testFind is throwing an exception during >RelationalDatabaseSession.flush(). Haven't been able to figure this >one out yet so will willingly accept any advice as to what may be the >cause. Below is the output trace when debug is set to 4. Just a guess ..... It kind of *looks* like this bug has to do with reusing prepared statements for this JDBC driver. Hibernate keeps any prepared statements it uses in a cache on RelationalDatabaseSession. You could disable this cache by defacing RelationalDatabaseSession.getPreparedStatement() and see if the error still occurs. If it doesn't, perhaps some System property to disable cacheing is in order.... |
From: Georg S. <ge...@sc...> - 2002-02-12 12:41:16
|
cirrus.hibernate.impl.RelationalDatabaseSession.find() recurse indefinitely, if the id of the object can't be found (resulting in a StackOverflowException). The check, if the object is succesfully retrieved, is performed _after_ the recursion and so is never executed. To fix this, line 559 ("if (!success) throw new...") has to be moved to 553 (after "deferLoads--;" and _before_ "if (deferLoads==0 ..."), resulting in the folowing: 551 deferLoads--; 552 553 if (!success) throw new HibernateException("id not found or provided object was wrong class"); 554 555 // now actually load the state into all the waiting objects... 556 // this code is _not_ executed recursively 557 if (deferLoads==0) doDeferredLoads(); 558 559 doLoadCallbacks(results, cols); Here is a test for the code above, I think it only works with mysql, because other dbms have support for foreign key constraints and will delete Glarch g if I delete Glarch g2. I am right? protected void testIdNotFound(SessionFactory sessions) throws Exception { //The following test is only enabled for MySQL which has no foreign key constraints. if (db.equals("mysql")) { Session s = sessions.openSession(); Glarch g = (Glarch) s.create(Glarch.class); Glarch g2 = (Glarch) s.create(Glarch.class); g.setNext(g2); Serializable gid = s.getID(g); Serializable g2id = s.getID(g2); s.commit(); s = sessions.openSession(); g2 = (Glarch) s.load( Glarch.class, g2id ); s.delete(g2); s.commit(); s = sessions.openSession(); boolean ok = false; try { g = (Glarch) s.load( Glarch.class, gid ); } catch (HibernateException e) { ok = "id not found or provided object was wrong class".equals(e.getMessage()); } catch (java.lang.StackOverflowError soe) { ok = false; } assert( ok, "id not found"); s.commit(); } } P.S.: build.xml lacks the exclusion of the build directory and the build.xml file. If you are lazy and build without doing "ant clean" before, the build-directory is recursively copied in the build-directory ... The two exclude Tags fix it: 32 <patternset id="support.files"> 33 <include name="**/*.properties"/> 34 <include name="**/*.dtd"/> 35 <include name="**/*.xml"/> 36 <exclude name="build/**/*"/> 37 <exclude name="build.xml"/> 38 </patternset> |
From: Phillip B. <phi...@cl...> - 2002-02-12 10:07:03
|
Had some spare time at work today and tried to create a dialect for the Progress database (from www.progress.com). While doing so I struck various obstacles which I'm hoping someone might be able to suggest some solutions. Problem #1: Progress requires you to either always prefix table names with a schema, or, alternatively use SET SCHEMA 'xxx' to set a default schema for your session. To work around this I started by changing the mappings used in the cirrus.hibernate.test package by adding a schema prefix to the various table names. This of course only worked where there was an explicit table mapping. So additional table mappings were required. Cool this got rid of a bunch of errors. The next thing to break was the table name used for unique ids, "hibernate_unique_key". This string is hardcoded into RelationalDataStore and HiLoGenerator and needed the schema prefix. My feeling is this table name should be part of the mapping rather than hardcoded. Another idea was to make the table name an attribute of Dialect. RelationDataStore looks reasaonbly easy to modify but I'm not so sure about HiLoGenerator. Any comments? The last obstacle with the schema prefix was Collection.createIndex() forms index names by added IDX to the table name. With a schema prepended to the table name this resulted in index names which caused SQL syntax errors. My quick fix for this was to get the createIndex method to stip off the schema prefix when it created the index name. I'm open to ideas for a better solution. Problem #2: testFind is throwing an exception during RelationalDatabaseSession.flush(). Haven't been able to figure this one out yet so will willingly accept any advice as to what may be the cause. Below is the output trace when debug is set to 4. testFind... Flushing: cirrus.hibernate.test.Foo 0a01003c:ebf8db1b:00eb:f8dbd778:0008 LOADED cirrus.hibernate.test.Foo: custom changed Generated new collection ID 65544 for table pub.foobytes [snipped repeated lines for 3 other objects] Flushing 4 insertions, 4 updates, 0 deletions to 4 objects and updating 12 collections.... cirrus.hibernate.collections.ArrayHolder@4980c9:null-->cirrus.hibernate.impl.CollectionPersister@32e13d [snipped 10 similar lines] cirrus.hibernate.collections.ArrayHolder@b76fa:null-->cirrus.hibernate.impl.CollectionPersister@32e13d [1] insert into pub.foos ( bar_string, bar_count, name, importantDates, the_time, foo, long_, integer_, float_, double_, bytes, date_, timestamp_, boolean_, bool_, null_, short_, zero_, int_, string_, byte_, yesno, blobb_, nullBlob, status_, bin_, first_name, surname, count_, name_, subcount, subname, foo_id, class ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'cirrus.hibernate.test.Bar' ) [2] insert into pub.foos ( foo, long_, integer_, float_, double_, bytes, date_, timestamp_, boolean_, bool_, null_, short_, zero_, int_, string_, byte_, yesno, blobb_, nullBlob, status_, bin_, first_name, surname, count_, name_, subcount, subname, foo_id, class ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'cirrus.hibernate.test.Foo' ) [3] insert into pub.foos ( foo, long_, integer_, float_, double_, bytes, date_, timestamp_, boolean_, bool_, null_, short_, zero_, int_, string_, byte_, yesno, blobb_, nullBlob, status_, bin_, first_name, surname, count_, name_, subcount, subname, foo_id, class ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'cirrus.hibernate.test.Foo' ) [4] insert into pub.foos ( bar_string, bar_count, name, importantDates, the_time, foo, long_, integer_, float_, double_, bytes, date_, timestamp_, boolean_, bool_, null_, short_, zero_, int_, string_, byte_, yesno, blobb_, nullBlob, status_, bin_, first_name, surname, count_, name_, subcount, subname, foo_id, class ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'cirrus.hibernate.test.Bar' ) [5] update pub.foos set foo = ?, long_ = ?, integer_ = ?, float_ = ?, double_ = ?, bytes = ?, date_ = ?, timestamp_ = ?, boolean_ = ?, bool_ = ?, null_ = ?, short_ = ?, zero_ = ?, int_ = ?, string_ = ?, byte_ = ?, yesno = ?, blobb_ = ?, nullBlob = ?, status_ = ?, bin_ = ?, first_name = ?, surname = ?, count_ = ?, name_ = ?, subcount = ?, subname = ? where foo_id = ? [6] update pub.foos set foo = ?, long_ = ?, integer_ = ?, float_ = ?, double_ = ?, bytes = ?, date_ = ?, timestamp_ = ?, boolean_ = ?, bool_ = ?, null_ = ?, short_ = ?, zero_ = ?, int_ = ?, string_ = ?, byte_ = ?, yesno = ?, blobb_ = ?, nullBlob = ?, status_ = ?, bin_ = ?, first_name = ?, surname = ?, count_ = ?, name_ = ?, subcount = ?, subname = ? where foo_id = ? [7] update pub.foos set bar_string = ?, bar_count = ?, name = ?, importantDates = ?, the_time = ?, foo = ?, long_ = ?, integer_ = ?, float_ = ?, double_ = ?, bytes = ?, date_ = ?, timestamp_ = ?, boolean_ = ?, bool_ = ?, null_ = ?, short_ = ?, zero_ = ?, int_ = ?, string_ = ?, byte_ = ?, yesno = ?, blobb_ = ?, nullBlob = ?, status_ = ?, bin_ = ?, first_name = ?, surname = ?, count_ = ?, name_ = ?, subcount = ?, subname = ? where foo_id = ? java.lang.reflect.InvocationTargetException: java.sql.SQLException: [JDBC Progress Driver]:Data type for parameter 1 has changed since first SQLExecute call. at com.progress.sql.jdbc.JdbcProgress.createSQLException(JdbcProgress.java:6501) at com.progress.sql.jdbc.JdbcProgress.standardError(JdbcProgress.java:6675) at com.progress.sql.jdbc.JdbcProgress.SQLExecute(JdbcProgress.java:2789) at com.progress.sql.jdbc.JdbcProgressPreparedStatement.execute(JdbcProgressPreparedStatement.java:238) at com.progress.sql.jdbc.JdbcProgressPreparedStatement.executeUpdate(JdbcProgressPreparedStatement.java:144) at cirrus.hibernate.impl.ClassPersister.update(ClassPersister.java:574) at cirrus.hibernate.impl.ScheduledUpdate.execute(ScheduledUpdate.java:25) at cirrus.hibernate.impl.RelationalDatabaseSession.executeAll(RelationalDatabaseSession.java:894) at cirrus.hibernate.impl.RelationalDatabaseSession.flush(RelationalDatabaseSession.java:880) at cirrus.hibernate.impl.RelationalDatabaseSession.find(RelationalDatabaseSession.java:400) at cirrus.hibernate.impl.RelationalDatabaseSession.find(RelationalDatabaseSession.java:331) at cirrus.hibernate.test.FooBarTest.testFind(FooBarTest.java:118) at java.lang.reflect.Method.invoke(Native Method) at cirrus.hibernate.test.TestCase.run(TestCase.java:46) at cirrus.hibernate.test.FooBarTest.main(FooBarTest.java:648) Exception in thread "main" [8] update pub.foos set bar_string = ?, bar_count = ?, name = ?, importantDates = ?, the_time = ?, foo = ?, long_ = ?, integer_ = ?, float_ = ?, double_ = ?, bytes = ?, date_ = ?, timestamp_ = ?, boolean_ = ?, bool_ = ?, null_ = ?, short_ = ?, zero_ = ?, int_ = ?, string_ = ?, byte_ = ?, yesno = ?, blobb_ = ?, nullBlob = ?, status_ = ?, bin_ = ?, first_name = ?, surname = ?, count_ = ?, name_ = ?, subcount = ?, subname = ? where foo_id = ? Regards, Phillip B. |
From: Georg S. <ge...@sc...> - 2002-02-12 09:02:02
|
On Tuesday 12 February 2002 00:19, you wrote: > I'm guessing, if you spotted this bug, you know how to write a test > for it ... ? I spotted it because I thought 6 seconds for retrieving a single object from the database isn't what one can call good performance... (but I think 6 seconds are very ok to load the whole database ;-). But you can't test this, so my solution for an automated test looks like this: protected void testLazyCollections(SessionFactory sessions) throws Exception { Session s = sessions.openSession(); Qux q = (Qux) s.create(Qux.class); s.commit(); s = sessions.openSession(); q = (Qux) s.load( Qux.class, new Long( q.getKey() ) ); s.commit(); boolean ok = false; try { q.getMoreFums().isEmpty(); } catch (RuntimeException e) { ok = "Hibernate failed trying to load a collection".equals(e.getMessage()); } assert( ok, "lazy collection with one-to-many" ); ok = false; try { q.getFums().isEmpty(); } catch (RuntimeException e) { ok = "Hibernate failed trying to load a collection".equals(e.getMessage()); } assert( ok, "lazy collection with many-to-many" ); s = sessions.openSession(); q = (Qux) s.load( Qux.class, new Long( q.getKey() ) ); s.delete(q); s.commit(); } |
From: Gavin_King/Cirrus%<CI...@ci...> - 2002-02-12 01:32:14
|
Heres my suggested approach to databinding. Everyone feel free to tear it to shreds :) First of all, what I'm proposing here is nothing like sun's JAXB standard which is more of a parser compiler like yacc or ANTLR than an automated binding of XML to business model classes. I can see where JAXB would be really really nice (for example in cirrus.hibernate.map) but I can also see where it isn't really that useful. There are basically two approaches to databinding: 1. Write an XML schema and generate Java classes from the schema 2. Write your Java classes and generate XML from them JAXB takes the first approach. I am talking about the second here. Both approaches usually require a little bit of extra information (a binding document) to do the translation. Fortunately, Hibernate's persistence mappings contain *almost* everything we need to generate an XML document containing the class' persistent state. Many applications will need the XML delivered in a very particular format. Rather than trying to anticipate every way of mapping classes to XML schemas, I propose we initially generate the XML in a very generic format (that we can write down in a DTD). Then applications can specify (for each class) an XSLT stylesheet to transform to their chosen format. We can even provide a "default" stylesheet that will transform to format that would be useful for many applications. I've started an experimental branch in CVS called "DATABIND" with some very rudimentary code along these lines. An example of the generic format is generated by the test suite: ++++++++++++++++++++++++++++++ <?xml version="1.0" encoding="UTF-8"?> <hibernate-generic> <object class="cirrus.hibernate.test.Bar"> <id name="key" type="string">caa3862a:ebf7ca43:00eb:f7ca4d65:0000</id> <property name="barString" type="string" /> <property name="barComponent" type="component">FooComponent: bar=69</property> <property name="time" type="time" /> <property name="foo" type="collection" /> <property name="long" type="long">696969696969696969</property> <property name="integer" type="integer">-666</property> <property name="float" type="float">6666.66</property> <property name="double" type="double">1.33E-69</property> <property name="bytes" type="collection">[B@3e3d318b</property> <property name="date" type="date">01 January 1970</property> <property name="timestamp" type="timestamp">12 February 2002 11:42:24</property> <property name="boolean" type="boolean">true</property> <property name="bool" type="boolean">false</property> <property name="null" type="integer" /> <property name="short" type="short">42</property> <property name="zero" type="float">0.0</property> <property name="int" type="integer">2</property> <property name="string" type="string">a string</property> <property name="byte" type="byte">127</property> <property name="yesno" type="yes_no">false</property> <property name="blob" type ="serializable">cirrus.hibernate.test.Foo$Struct@3e3bf18b</property> <property name="nullBlob" type="serializable" /> <property name="status" type ="enum">cirrus.hibernate.test.FooStatus@1a42b188</property> <property name="binary" type="binary">[B@3ec2b18b</property> <property name="custom" type ="cirrus.hibernate.test.DoubleStringType">foo,bar</property> <property name="component" type="component">FooComponent: foo=12, Thu Jan 01 11:00:00 GMT+11:00 1970, Tue Feb 12 11:42:24 GMT+11:00 2002, null, Tue Feb 12 11:42:24 GMT+11:00 2002 (FooComponent: bar=666, Thu Jan 01 11:02:03 GMT+11:00 1970, null)</property> </object> </hibernate-generic> +++++++++++++++++++++++++++ Clearly that needs some work. Now a default stylesheet could take that and transform it to: <Bar> <key>caa3862a:ebf7ca43:00eb:f7ca4d65:0000</key> <barString/> ... <long>696969696969696969</long> ... <date>01 January 1970</date> </Bar> Which is a much more readable format. If that werent good enough, the user could provide their own stylesheet. Going backwards (XML->Java object) probably has some extra issues but I think essentially the same approach could work. Provide a stylesheet to map to the generic format. Then read Java objects from the generic format. What does everyone think? |
From: Gavin_King/Cirrus%<CI...@ci...> - 2002-02-11 23:30:55
|
Thanks for that Georg :) That is indeed what was intended. I'm guessing, if you spotted this bug, you know how to write a test for it ... ? At present the tests check that lazy init doesn't *break* collections. They don't actually check that lazy init is actually lazy... |
From: Georg S. <ge...@gm...> - 2002-02-11 20:08:17
|
I looked again at the source code from cirrus.hibernate.map.Collection and I think the only change needed to make it work is moving lines 73 to 77 out of the if-else-block, resulting in the following: 57 if (isOneToMany) { 58 //we have to set up the table later!! yuck 59 } 60 else { 61 //TABLE ... 73 } 74 //LAZINESS 75 Node lazyNode = atts.getNamedItem("lazy"); 76 if (lazyNode!=null) { 77 lazy = lazyNode.getNodeValue().equals("true"); 78 } For my usage of Hibernate this works just fine, but I don't know if this breaks something else?! Georg |
From: Georg S. <ge...@gm...> - 2002-02-11 19:17:48
|
Is Hibernate intended to support lazy collections with one-to-many associations? There is an example in cirrus/hibernate/test/qux_map.xml which made me think that Hibernate supports lazy collections with one-to-many associations, but it doesn't work and I can't find any code in cirrus.hibernate.map.Collection implementing this. Are there any reasons, that lazy collections with one-to-many associations doesn't work, or is it just not implemented? Georg |
From: Gavin_King/Cirrus%<CI...@ci...> - 2002-02-11 07:20:41
|
Is anyone interested in messing with the collection package? There are a couple of ways it could be improved: 1. We could support sorted collections like TreeSet, TreeMap. 2. At present when a collection changes, its marked as dirty and all its database rows are deleted and then recreated when the Session flushes. This is efficient if more than half its elements changed. But if we just added or removed a couple of elements, its very inefficient. Is anyone interested in optimising this behaviour (at least for Maps, Lists and arrays where its easy to know which elements changed)? |
From: Doug C. <de...@fl...> - 2002-02-09 23:17:09
|
[snip] > As I'm not a fan of coding XML by hand, I'd still like to find a mapping > generation mechanism that fits into an automated build environment. I > have reservations about layering explicit mapping details over to the > top of MappingByRefection. One of the best things about MappingByRefection is that it will (when it's tested) only produce mappings that will work... at least on the Java side, and with newly created databases. In other words, you can't have a property in the xml that doesn't exist in the class, and they always have a good type. I hope that when adding information in an automated way, by whatever means (gui, javadoc, config file), that this feature is maintained. e |
From: Doug C. <de...@fl...> - 2002-02-09 23:09:17
|
A MappingByReflection update is available. There are new arguments to MappingByReflection.main() to - send the xml output to a file - turn off dumping the xml to the console - set candidate UIDs, set select mode, and set component depth; these can be interleaved with class names to change the settings on a class by class basis public setter for replacing or adding candidate UIDs lazy="true" is now in correct spot nicer xml output, including shorter type name and smarter indentation e |