objectbridge-developers Mailing List for ObJectRelationalBridge (Page 30)
Brought to you by:
thma
You can subscribe to this list here.
2000 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(14) |
Dec
(20) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2001 |
Jan
(33) |
Feb
(8) |
Mar
(3) |
Apr
(1) |
May
(18) |
Jun
(6) |
Jul
(15) |
Aug
(71) |
Sep
(29) |
Oct
(43) |
Nov
(77) |
Dec
(54) |
2002 |
Jan
(54) |
Feb
(147) |
Mar
(144) |
Apr
(163) |
May
(307) |
Jun
(240) |
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
From: Florian B. <bf...@fl...> - 2002-03-26 08:17:59
|
Hi Thomas, <snip> > > > <snip ObjectCache based solution for IdentityFactory> > > That is my intention, as the ObjectCache itself also has a memory leak > > problem that would be fixed by this. For each object in the > > HashTable a > > SoftReference is created that wraps the object. When the gc > > collects the > > object, the SoftReference object itself stays in memory. > > > > Oops, are you sure about that? Can't SoftReference objects be collected in > general, or is their collection simply deferred to the next run of the > garbage collector? I'm quite sure about the memory leak. SoftReference objects behave like all other objects, i.e. they are collected when there are no references to the objects left. Lets look at ObjectCacheImpl: public void cache(Identity oid, Object obj) { if ((obj != null)) { SoftReference ref = new SoftReference(obj); objectTable.put(oid.toString(), ref); } } This creates a new SoftReference with the object to cache being the referent of the SoftReference. The referent is subject to special handling by the GC, i.e. it can be collected if there are not other references to obj. The following code (in lookup) removes entries of the Hashtable where the values have been collected: if (ref != null) { obj = ref.get(); if (obj == null) { gcCount++; objectTable.remove(oid); } } If the entry is processed by this code the SoftReference will be gc'd because there is no reference left to it (normal gc behaviour). The problem is, when you have entries in the Hashtable that, at some point in time, get collected, but there is never ever again a lookup of the object. In this case the entry in the Hashtable remains and therefore a couple of objects (Identity, Map.Entry, SoftReference) remain in memory. Other implementations of such caches or WeakHashMap/SoftHashMaps work differently. They maintain an instance of java.lang.ref.ReferenceQueue and pass this instance to all created SoftReference/WeakReference objects. Whenever the referent of a Soft/WeakReference is collected, the SoftReference/WeakReference is added to the ReferenceQueue. Now, whenever you modify the map (by put, remove etc.) the ReferenceQueue is processed and the entries are removed. This leads to another typical issue in such implementations: Usually the KEY of the map is encapsulated in a Soft/WeakReference. This is done to make cleaning up efficient, because you can only access a map by keys, but has the disadvantage that not the objects that might be larger in size (usually the value) are collected if memory is running low. There are some other disadvantages with this approach (like entries never get thrown out when you do not modify a map over some time, unpredictable processing time of modification operations), and in general the more I look into these implementations the more I get the feeling that all of them contain somewhat ugly hacks that prevent them from being a reliable and calculable solution for a cache (i.e. efficient lookup, efficient in modification and retrieval of the cache, calculable and constant time of lookup and modification, ...) best regards, Florian |
From: Chris G. <CGr...@de...> - 2002-03-26 02:39:13
|
I modified the db-setup.sql file this weekend to add support for Microsoft SQL Server. If there aren't any problems, could it be included in the next release? It also works with the modified build script I submitted -- those scripts will replace $JDBCDRIVER$ and $JDBCURL$ with the values from the build.properties file, before using the ScriptTool. Regards, Chris Greenlee |
From: Chris G. <CGr...@de...> - 2002-03-26 02:34:31
|
I made a few changes to the build.xml file this weekend: 1. I moved global properties out into a build.properties file so that they can be modified without having to change the build.xml file. 2. I replaced the classpath and runtime_classpath properties with <path/> elements, and then used those via refid where appropriate. Using a <property/> tag for classpath didn't work too well on Windows machines, since "d:/foo.jar" includes a ":". 3. I moved the target descriptions from the "targets" target into the "description" attribute of each target. Instead of ant targets, you can do ant -projecthelp, which will give you roughly the same results. I've attached the revised build.xml, and a sample build.properties file. I hope you like the changes! Regards, Chris Greenlee |
From: <Joa...@tp...> - 2002-03-25 18:09:38
|
Hy, I just wanted to point out that hsqldb 1.7.0rc2 is out with a fixed CodeSwitcher. Seems we're pretty close to a final release. regarding the automated nightly compiles and the regression tests that I wanted to set up: Our server crashed really bad on Friday (hardware fault, probably the motherboard). Now it move to an old p200 with 64mb RAM, unfortunately this machine is not quite up to the task I want it to handle, so I've got to move the nighlies back on the timeline, 'till we get a real replacement for that server. regards Joachim Sauer |
From: Mahler T. <tho...@it...> - 2002-03-25 14:24:25
|
Hi Florian, > Hi Thomas, > <snip ObjectCache based solution for IdentityFactory> > That is my intention, as the ObjectCache itself also has a memory leak > problem that would be fixed by this. For each object in the > HashTable a > SoftReference is created that wraps the object. When the gc > collects the > object, the SoftReference object itself stays in memory. > Oops, are you sure about that? Can't SoftReference objects be collected in general, or is their collection simply deferred to the next run of the garbage collector? cu, Thomas |
From: Mahler T. <tho...@it...> - 2002-03-25 14:23:58
|
Hi Cristoph, > Hi All! > > I am evaluation ojb for a simple content management system > that supports > multiple article types. Each article will be saved in a > separate table, > but i want to search across all of them. I think the > <extends> feature > of ojb enables that. Right! > But I also have a categories table with a n:m relation to article. > now my questions: > Is it possible to have a n:m relationship to a base class? Yes! > I assume that ojb joins all involved tables when doing a query on an > interface or baseclass. Will that still work if I have really lots of > different article types? No, we are not joining accross all involved tables. Thus there should be no problems for your scenario. > > Some other questions relating to my cms efforts: > Is there support planned for automatic updating of the > database scheme? > (ie create table or alter table) OJB does have a reverse engineering feature (you can read in RDBMS tables an have Java classes and an XML repository generated). But currently there is no forward engineering (from Java Object model to XML repositoty and RDBMS table) implemented. IMHO automatic schema generation is possible but to define a semantics that fits all needs will be difficult. We have no plans in this directions yet. > How hard would it be to use ojb without generating a class for every > table? Depends on your ER model. > I'd just like to use ojb for generating a query, but i want to > get my data back in a map instead of a bean. OJB provides Report queries, that allow exactly this. > Then I could > just define an > article as a ojb mapping, and dont need to generate and compile java > code if a new articletype is generated. > Dynamic generation of classes and respective mappings is somewhat problematic in languages like Java. IMO Using Smalltalk would be much simpler for such problems. HTH, Thomas |
From: Havemeister, T. <Tho...@gf...> - 2002-03-25 12:04:41
|
Howdy *.*! There must be a bug with autoincrements on MS Access databases through jdbc:odbc driver. Everything seems to run fine but now I played with m:n associations and run in trouble with this error: The list of available products: [DEFAULT] WARN: problems with platform ojb.broker.platforms.PlatformMsAccessImpl: ojb.broker.platforms.PlatformMsAccessImpl [DEFAULT] WARN: OJB will use PlatformDefaultImpl instead [DEFAULT] ERROR: OJB ERROR: Dont know how to autoincrement field class test.ojb.tutorial1.PC._id What can I do? Is Access not supported by OJB? I'm currently using ojb-0.8.361-src archive .. my XML Repository: <!-- Mapping of User defined classes starts here --> <!-- Please keep user defined mappings in this file only, to avoid mixing user defined and system mappings. --> <!-- Definitions BObject for test.ojb.tutorial1.PC --> <ClassDescriptor id="1001"> <class.name>test.ojb.tutorial1.PC</class.name> <table.name>PC</table.name> <FieldDescriptor id="1"> <field.name>_id</field.name> <column.name>ID_PC</column.name> <jdbc_type>INTEGER</jdbc_type> <PrimaryKey>true</PrimaryKey> <autoincrement>true</autoincrement> </FieldDescriptor> <FieldDescriptor id="2"> <field.name>name</field.name> <column.name>NAME</column.name> <jdbc_type>VARCHAR</jdbc_type> </FieldDescriptor> <FieldDescriptor id="3"> <field.name>status</field.name> <column.name>STATUS</column.name> <jdbc_type>INTEGER</jdbc_type> </FieldDescriptor> <FieldDescriptor id="4"> <field.name>lastUpdate</field.name> <column.name>LAST_UPDATE</column.name> <jdbc_type>DATE</jdbc_type> </FieldDescriptor> <FieldDescriptor id="5"> <field.name>deleted</field.name> <column.name>DELETED</column.name> <jdbc_type>INTEGER</jdbc_type> </FieldDescriptor> <FieldDescriptor id="6"> <field.name>empl</field.name> <column.name>ID_EMPLOYEE</column.name> <jdbc_type>INTEGER</jdbc_type> </FieldDescriptor> <CollectionDescriptor id="1"> <cdfield.name>allSoftware</cdfield.name> <items.class>test.ojb.tutorial1.PCxSoftware</items.class> <inverse_fk_descriptor_ids>1</inverse_fk_descriptor_ids> </CollectionDescriptor> </ClassDescriptor> <!-- Definitions for Role test.ojb.tutorial1.PCxSoftware --> <ClassDescriptor id="1002"> <class.name>test.ojb.tutorial1.PCxSoftware</class.name> <table.name>PC_SOFTWARE</table.name> <FieldDescriptor id="1"> <field.name>_id_pc</field.name> <column.name>ID_PC</column.name> <jdbc_type>INTEGER</jdbc_type> <PrimaryKey>true</PrimaryKey> </FieldDescriptor> <FieldDescriptor id="2"> <field.name>_id_software</field.name> <column.name>ID_SOFTWARE</column.name> <jdbc_type>INTEGER</jdbc_type> <PrimaryKey>true</PrimaryKey> </FieldDescriptor> <ReferenceDescriptor id="1"> <rdfield.name>pc</rdfield.name> <referenced.class>test.ojb.tutorial1.PC</referenced.class> <fk_descriptor_ids>1</fk_descriptor_ids> </ReferenceDescriptor> <ReferenceDescriptor id="2"> <rdfield.name>software</rdfield.name> <referenced.class>test.ojb.tutorial1.Software</referenced.class> <fk_descriptor_ids>2</fk_descriptor_ids> </ReferenceDescriptor> </ClassDescriptor> <!-- Definitions for BObject test.ojb.tutorial1.Software --> <ClassDescriptor id="1003"> <class.name>test.ojb.tutorial1.Software</class.name> <table.name>SOFTWARE</table.name> <FieldDescriptor id="1"> <field.name>_id</field.name> <column.name>ID_SOFTWARE</column.name> <jdbc_type>INTEGER</jdbc_type> <PrimaryKey>true</PrimaryKey> <autoincrement>true</autoincrement> </FieldDescriptor> <FieldDescriptor id="2"> <field.name>name</field.name> <column.name>NAME</column.name> <jdbc_type>VARCHAR</jdbc_type> </FieldDescriptor> <FieldDescriptor id="3"> <field.name>maxLicences</field.name> <column.name>MAXLICENSES</column.name> <jdbc_type>INTEGER</jdbc_type> </FieldDescriptor> <FieldDescriptor id="4"> <field.name>lastUpdate</field.name> <column.name>LAST_UPDATE</column.name> <jdbc_type>DATE</jdbc_type> </FieldDescriptor> <FieldDescriptor id="5"> <field.name>deleted</field.name> <column.name>DELETED</column.name> <jdbc_type>INTEGER</jdbc_type> </FieldDescriptor> <CollectionDescriptor id="1"> <cdfield.name>toPC</cdfield.name> <items.class>test.ojb.tutorial1.PCxSoftware</items.class> <inverse_fk_descriptor_ids>2</inverse_fk_descriptor_ids> </CollectionDescriptor> </ClassDescriptor> <!-- Mapping of User defined classes ends here --> -- Thomas Havemeister Software Developer GFT Systems GmbH Ehrenbergstrasse 11 D-98693 Ilmenau T +49-36 77-64 29-0 D +49-36 77-66 33-77 tho...@gf... www.gft.com |
From: Mahler T. <tho...@it...> - 2002-03-25 11:09:39
|
Hi Michael, > > Persistence "borker" ... most beautiful Freudian slip in a > long time ;-) Persistence is futile -- we are bork :-) > > > > It won't be difficult to implement such a mechanism. > > > But ODMG wants the implemtor to throw exceptions if Locking fails. > > > We simply stick to the rules here. > > > > I didn't bring the ODMG standard with me, but are you > > sure, that having to wait for a lock constitutes a failure > to obtain a > > lock (as opposed to let's say a timeout, where a > LockNotGrantedException > > would make sense to me). > > From "The Object Data Standard: ODMG 3.0", > 2.9: Locking and Concurrency Control > > "The ODMG Object Model supports traditional pessimistic > concurrency control as its default policy, but does > not preclude > an ODMS from supporting a wider range of concurrency control > policies." > > and the ODMG Java Binding says in 7.1.4.10: Exception Handling: > > "LockNotGrantedException ... > > Thrown if a lock could not be granted. (Note that time-outs and > deadlock detection are implementation-defined.)" > > Combining these statements with a definition of pessimistic > locking, e.g. > <http://www.ambysoft.com/ooGlossary.pdf>, I am led to > conclude that the > implementation is free to immediately signal an error _or_ deferr the > locking decision to a later point, given that other > concurrency guarantees > are not violated. Timeouts and deadlock detection are even explicitly > mentioned ... > The ODMG spec is not precise in many respects. Implementors have to fill many undefined or unclear spots while implementing the API. It is not always easy to grasp the general intention of the ODMG designers. For instance some time ago we had an in depth discussion about implicit lock acquisition. (Please refer to the ODMG mailinglist archive). You came to a conclusion about ODMG Locking behaviour by referring to external sources (Amby's OO Glossary). IMHO your conclusion is plausible. But does it fit to the general idea of the ODMG designers? I really don't know! There is a method org.odmg.Transaction.tryLock(Object obj, int lockmode): /** * Upgrade the lock on the given object to the given lock mode. * Method <code>tryLock</code> is the same as <code>lock</code> except it returns * a boolean indicating whether the lock was granted instead of generating an exception. * @param obj The object to acquire a lock on. * @param lockMode The lock mode to acquire. The lock modes are <code>READ</code>, * <code>UPGRADE</code>, and <code>WRITE</code>. * @return True if the lock has been acquired, otherwise false. */ public boolean tryLock(Object obj, int lockMode); It will be very easy for ODMG users to build their specific timeout semantics with this methods. That's why I believe it is OK to immediately throw an exception in .lock(...). There are also other ODMG implemtations (e.g. for the Objectivity ODBMS) that work like this. But as always with OJB: If you or others volunteer to implement a timeout scheme for the OJB ODMG locks I'll be most grateful and promise to integrate it into our codebase ! cu, Thomas |
From: Michael W. <mi...@ra...> - 2002-03-25 07:35:29
|
Hi, On Sun, 24 Mar 2002, Georg Schneider wrote: > from the database that are old, before borker.comitTransaction actually > writes them to the database Persistence "borker" ... most beautiful Freudian slip in a long time ;-) > > It won't be difficult to implement such a mechanism. > > But ODMG wants the implemtor to throw exceptions if Locking fails. > > We simply stick to the rules here. > > I didn't bring the ODMG standard with me, but are you > sure, that having to wait for a lock constitutes a failure to obtain a > lock (as opposed to let's say a timeout, where a LockNotGrantedException > would make sense to me). From "The Object Data Standard: ODMG 3.0", 2.9: Locking and Concurrency Control "The ODMG Object Model supports traditional pessimistic concurrency control as its default policy, but does not preclude an ODMS from supporting a wider range of concurrency control policies." and the ODMG Java Binding says in 7.1.4.10: Exception Handling: "LockNotGrantedException ... Thrown if a lock could not be granted. (Note that time-outs and deadlock detection are implementation-defined.)" Combining these statements with a definition of pessimistic locking, e.g. <http://www.ambysoft.com/ooGlossary.pdf>, I am led to conclude that the implementation is free to immediately signal an error _or_ deferr the locking decision to a later point, given that other concurrency guarantees are not violated. Timeouts and deadlock detection are even explicitly mentioned ... Best wishes, Mike -- Don't feed. DI Michael Wildpaner Don't provoke. Ph.D. Student Don't enter the cage. |
From: Christoph S. <ch...@sc...> - 2002-03-25 01:20:12
|
Hi All! I am evaluation ojb for a simple content management system that supports multiple article types. Each article will be saved in a separate table, but i want to search across all of them. I think the <extends> feature of ojb enables that. But I also have a categories table with a n:m relation to article. now my questions: Is it possible to have a n:m relationship to a base class? I assume that ojb joins all involved tables when doing a query on an interface or baseclass. Will that still work if I have really lots of different article types? Some other questions relating to my cms efforts: Is there support planned for automatic updating of the database scheme? (ie create table or alter table) How hard would it be to use ojb without generating a class for every table? I'd just like to use ojb for generating a query, but i want to get my data back in a map instead of a bean. Then I could just define an article as a ojb mapping, and dont need to generate and compile java code if a new articletype is generated. TIA chris |
From: Georg S. <ge...@me...> - 2002-03-24 22:34:23
|
Hi Thomas, Thanks for your prompt reply. Please excuse if I can't go into full detail or take up some of your suggestions yet, but my problem is that since yesterday I am about 600 km west of Buenos Aires in the Argentinean Pampa visiting my parents in law (normally I work in Vienna). This means I have an awfully slow Internet connection, no access to my development environment and the not so remote possibility of getting hit on my head by mey wife with an Argentinean Steak ( which are quite big) if I spend too much time of my vacation of working matters. Taking that risk, I would still like to discuss a few things On Fri, 22 Mar 2002, Thomas Mahler wrote: > > public boolean readLock(TransactionImpl tx, Object obj) > > { > > > > LockEntry writer = getWriter(obj); > > > > ====> race condition, another thread could put a writer > > > > if (writer == null) > > { > > > > ------------------------------------------------------- > > > > maybe synchronization happens somewhere else, but to make sure, I put > > synchronized to all the methods in LockManagerDefaultImpl.java > > > > > This strange thing has been "detected" by others before and there have > been some discussions on this topic. > > Here is the management summary: > The OJB Lockmanagement does not rely on Java Locking mechanisms! > The reason. Java locks only works within a single JVM. > But OJB Lockmanagement must properly work accross multiple JVMs. > Thus relying on Java's "synchronized" could result in severe data > corruption. > The C/S mode PersistentLockMapImpl is backed by a database table that > may be accessed from any number of clients residing in different JVMs. > > The SingleVM mode InMemoryLockMapImpl is meant for use for singlevm mode > only! But it also does not rely on "synchronized" & co. > > The double lock checking is done in the Methods of the LockMapImpl > classes (getWriter() & co.). I have tried both the InMemory and database-based locking mechanism and both showed the same behaviour. Taking an (admittedly) quick look at the LockMapImpl classes, I haven't found anything that would prevent one thread of adding a writer, after the first thread had already passed the if (writter == null) condition check Please tell me, if I am understanding something wrong there. > > > > > > I have to mention that Object A is a dynamic Proxy. > > > Mh. This may be somewhat problematic in your scenario. Using (dynamic) > Proxies in OJB/ODMG uses a "lazy locking". That is the lock is not > placed immediately but only when the proxy materializes the "real" > object. Please try your scneario without dynamic proxies. > Sorry, but my location (as mentioned above) prevents me from checking that out at the moment (I'll be back in 3 weeks, maybe I'll somehow manage to start things from here, then I'll try -:)). Am I right, that you are saying, one shouldn't be using dynamic proxies in a multithreaded environment? > > Mh, on commiting objects a PB.invalidate(obj) is performed that should > avoid this behaviour ??? > I think the problem is that in ObjectEnvelopeTable.java broker.invalidate(new Identity(mod.getObject())); } broker.commitTransaction(); the call to broker.invalidate and broker.comitTransaction aren't atomic which gives another thread the chance of filling up the cache with values from the database that are old, before borker.comitTransaction actually writes them to the database > > > > > e) I just put throw new LockNotGrantedException() to stop obj from > > materializing. This reduced the incident of the aforementioned > > problem, but it didn't stop it completly, so I assume there are > > other parts of the code which show a similar effect. > > > > > The best thing to get clearity about your analysis is to provide a JUnit > testcase that reproduces this behaviour! > Without such a testcase it's really difficult to verify your report. The steak-on-the-head problem will probably prevent me from doing that in the next weeks, but I'll try. Nevertheless it is going to be difficult to put this in a JUnit test case, since it is virtually impossible to make it reproducible in a predictable way. In our system, it happens during high load and in a massively multithreaded environment (and then not all of the time). One would have to put code into ojb to make certain threads sleep at different points. (if I have time I'll try) > > It seems that read-locks associated with the 1 result are not > > being released (the ObjectEnvelopeTable doesn't have any entries) > > > > My only solution is to actually materialize the queried subject > > by doing the following: > > > > SomeClass A = (SomeClass) l.get(0); > > > > and then calling a method on it > > > > => object is materialized and is in the ObjectEnvelopeTable and > > read-locks are release when calling tx.abort(); > > > > > This is a again the "lazy-locking" effect mentioned above. Works as > designed ! The problem in the case mentioned above is that the read lock stays with the object forever. Is that really what is intended? > > It won't be difficult to implement such a mechanism. > But ODMG wants the implemtor to throw exceptions if Locking fails. > We simply stick to the rules here. I didn't bring the ODMG standard with me, but are you sure, that having to wait for a lock constitutes a failure to obtain a lock (as opposed to let's say a timeout, where a LockNotGrantedException would make sense to me). Thanks again for your info Georg |
From: Thomas M. <tho...@ho...> - 2002-03-22 18:50:17
|
Hi Jakob Jakob Braeuchi wrote: > hi, > > i just added additional capabilities for report queries to the cvs. > ojb now supports groupBy and functions on columns for report queries. > > crit = new Criteria(); > crit.groupBy("id"); > query = QueryFactory.newReportQuery(Person.class, crit); > query.setColumns(new String[]{"id","name","vorname","sum(konti.saldo)"}); > broker.getReportQueryIteratorByQuery(query); > // sum(konti.saldo) now handled correctly > > this will execute the following sql: > > SELECT tabPerson.id,tabPerson.name,tabPerson.vorname,sum(tabKonto.saldo) > FROM tabPerson INNER JOIN tabKonto ON tabKonto.idPerson = tabPerson.id GROUP > BY tabPerson.id > cool ! > i need some help/input in the following issue: > the query will only return id, name etc. for persons having at least one > account. to retrieve data from persons without an account > the join clause should be changed to "LEFT OUTER JOIN". > > i'm now looking for a way to define the join type: > > - should it be defined for criteria or query ? IMO on the criteria level. The Query is mainly a container. > - is there are way to automagically detect th join type ? I'm not an expert in this area. But in all tools I have seen so far the user is responsible for setting the Join type. > - is join type only an issue for report queries ? I think this is also relevant for "normal" queries too. Users will perform all kind of possible queries with full object materialization. I'm well aware that it will be *very* difficult to provide Criteria based implementations for the complete SQL92 range ! cu, Thomas |
From: Thomas M. <tho...@ho...> - 2002-03-22 18:41:19
|
Hi Georg, Georg Schneider wrote: > Hi, > > I am experiencing a very serious locking problem, and I have expanded > quite a bit of effort to look into it, I haven't solved it yet, but I have > found a few interesting things, which I would like to discuss: > > 1.) How do you make sure that 2 threads are synchronized when locking? > e.g. I am using repeatable-read strategy and in > RepeatableReadStragegy.java: > > public boolean readLock(TransactionImpl tx, Object obj) > { > > LockEntry writer = getWriter(obj); > > ====> race condition, another thread could put a writer > > if (writer == null) > { > > ------------------------------------------------------- > > maybe synchronization happens somewhere else, but to make sure, I put > synchronized to all the methods in LockManagerDefaultImpl.java > This strange thing has been "detected" by others before and there have been some discussions on this topic. Here is the management summary: The OJB Lockmanagement does not rely on Java Locking mechanisms! The reason. Java locks only works within a single JVM. But OJB Lockmanagement must properly work accross multiple JVMs. Thus relying on Java's "synchronized" could result in severe data corruption. The C/S mode PersistentLockMapImpl is backed by a database table that may be accessed from any number of clients residing in different JVMs. The SingleVM mode InMemoryLockMapImpl is meant for use for singlevm mode only! But it also does not rely on "synchronized" & co. The double lock checking is done in the Methods of the LockMapImpl classes (getWriter() & co.). > 2.) Let me explain what problem I am experiencing: > I have an object A which references an Object B (1:1), > > Thread-1 Thread-2 > > oqlquery for A > > tx.lock(A,tx.upgrade) > > oqlquery for A > (LockNotGrantedException) > (since I use RepeatableRead > this should happen) > A.setFieldB(B) > > tx.commit() > > > oqlquery for A > > !!!!!FieldB is null > (should be B) > > > > I have to mention that Object A is a dynamic Proxy. Mh. This may be somewhat problematic in your scenario. Using (dynamic) Proxies in OJB/ODMG uses a "lazy locking". That is the lock is not placed immediately but only when the proxy materializes the "real" object. Please try your scneario without dynamic proxies. [side node on (dynamic) class proxies: The <class.proxy> concept is not optimal. Jakob contributed a much better proxy concept for Reference- and Collection-attributes. These concepts are not documented in the current release, but we will provide documentation on this feature in the next release. For the time beeing you should not use class.proxy setting under ODMG. ] As I looked into the > internals of ojb I came across the following explanation for the > abovementioned behaviour: > > > a) Thread-1 obtains a Write lock > b) FieldB is changed to B, update statement prepared (but not yet > commited in database (==> in database FieldB [actually the > Fk-Field, but for the rest of this I will just say > FieldB] is still null) ==> On changing fieldB the proxy *must* materialize the real object if not done before. > c) Thread-2 tries to obtain a read lock which rightly > (repeatable-read) is not granted => in TransactionImpl.java the > following happens: > throw new LockNotGrantedException("Can not lock " + obj + > " for READ"); > > + obj + means that java will call obj.toString(), which means that > since obj is a proxy it gets delegated to the IndirectionHandler, > which (if realSubject hasn't been materialized yet) will > materialize the realSubject. This is done by loading it from the > database (Thread-1 removed it from the cache before). BUT, in > the database there is still the old value of FieldB, because > Thread1 hasn't commited the database-transaction yet. The loaded > object is then put into the cache. > > d) The database-transaction in Thread-1 commits the new value for > fieldB, but since it was just put into the cache with the old > values subsequent queries to it, still have the old value. Mh, on commiting objects a PB.invalidate(obj) is performed that should avoid this behaviour ??? > > e) I just put throw new LockNotGrantedException() to stop obj from > materializing. This reduced the incident of the aforementioned > problem, but it didn't stop it completly, so I assume there are > other parts of the code which show a similar effect. > The best thing to get clearity about your analysis is to provide a JUnit testcase that reproduces this behaviour! Without such a testcase it's really difficult to verify your report. > > 3.) On debugging the just mentioned problem I stumbled across the > following: > > In LockStrategyFactory.java getStrategyFor(Object obj) a > LockStrategy is assigned by looking up obj.getClass(), which for > a dynamic Proxy is not the actual class ==> the default > ReadUncommitedStrategy is assigned for every proxy. The following > lines will change this: > > Instead of using: > int isolationLevel = getIsolationLevel(obj.getClass()); > > do: > if (obj instanceof Proxy) { > InvocationHandler ih = Proxy.getInvocationHandler(obj); > > if ((ih != null) && (ih instanceof IndirectionHandler)) { > c = ((IndirectionHandler) ih).getIdentity().getObjectsClass(); > } else { > //System.err.println("UPGRADING PROXY FAILED: " + c); > //TODO: handle this error case > } > > } > > if (c == null) { > c = obj.getClass(); > } > > int isolationLevel = getIsolationLevel(c); > This seems to be a bug. Thanks for your patch ! > > 4.) The following observation is just anecdotal, It seems that when > querying for an object which is a proxy with e.g.: > > DList l = (DList) query.execute(); > > if (l.size() == 1) { > > tx.abort; > return; > } > > > It seems that read-locks associated with the 1 result are not > being released (the ObjectEnvelopeTable doesn't have any entries) > > My only solution is to actually materialize the queried subject > by doing the following: > > SomeClass A = (SomeClass) l.get(0); > > and then calling a method on it > > => object is materialized and is in the ObjectEnvelopeTable and > read-locks are release when calling tx.abort(); > This is a again the "lazy-locking" effect mentioned above. Works as designed ! > > 5.) A general question about locking. Is there any possibility you are > going to implement some kind of blocked locking (i.e. a thread simply > waits for a lock to become available), instead of throwing a > LockNotGrantedException? > It won't be difficult to implement such a mechanism. But ODMG wants the implemtor to throw exceptions if Locking fails. We simply stick to the rules here. HTH, thanks for your observance to details, Thomas |
From: Thomas M. <tho...@ho...> - 2002-03-22 17:53:54
|
Hi again, Leandro Rodrigo Saad Cruz wrote: > Sorry man, in fact the problem was in another line at repository.xml > I defined a ReferenceDescriptor that pointed to the wrong class field. >=20 >=20 > By the way. If I have a association like this A 1 ----- N B >=20 > Do I have to defined CollectionDescriptors(from A to B) and > ReferenceDescriptos( from B to A) or just one of them ?? >=20 Depends. If you want to navigate from A to the Bs only you'll need a=20 CollectionDescriptor in ClassDescriptor A. If you want to navigate from a B to its A only you'll need a=20 ReferenceDescriptor in ClassDescriptor B. If you want to navigate in both directions you'll need both. HTH, Thomas >=20 > On Fri, 2002-03-22 at 12:20, Mahler Thomas wrote: >=20 >>Hi Leandro, >> >>I'll try to explain the 1-n section from the tutorial3. >>Say you have a class ProductGroup with a Vector attribute allArticlesIn= Group >> that holds all Article objects belonging to this group. >> >>That is: *one* ProductGroup holds *n* Articles. >> >>You must tell OJB how to load the allArticlesInGroup attribute on loadi= ng a >>ProductGroup object. >>This is done by the following CollectionDescriptor: >><ClassDescriptor id=3D"2"> >> <class.name>test.ojb.broker.ProductGroup</class.name> >> ... >> <CollectionDescriptor id=3D"1"> >> <cdfield.name>allArticlesInGroup</cdfield.name> >> <items.class>test.ojb.broker.Article</items.class> >> <inverse_fk_descriptor_ids>4</inverse_fk_descriptor_ids> >> </CollectionDescriptor> >> ... >> >>This descriptor contains the following info: >>- The class ProductGroup has a container attribute allArticlesInGroup.=20 >> The Java-type of this attribute is not declared. It maybe of type >>SomeType[],=20 >> Collection, or ManageableCollection. >>- The Items in this Container are of type Article >>- The Mapping of class Article has a attribute with id=3D"4" that holds= a=20 >> foreign key value idetifying the associated ProductGroup >> >>HTH, >> >>Thomas >> >> >>>-----Urspr=FCngliche Nachricht----- >>>Von: Leandro Rodrigo Saad Cruz [mailto:le...@ib...] >>>Gesendet: Freitag, 22. M=E4rz 2002 15:30 >>>An: obj...@li... >>>Betreff: [OJB-developers] Using CollectionDescriptor in repository.xml >>> >>> >>>Hi all. There is one thing I didn't understand from the docs about >>>association mapping >>>http://objectbridge.sourceforge.net/tutorial3.html#1-n >>> >>><CollectionDescriptor id=3D"1"> >>> <cdfield.name>collection</cdfield.name>=20 >>> ******* -> does this field must be present in repository.xml in >>>SomeCLASS ClassDescriptor ? or just be a field in SomeCLASS impl ? >>> >>> <items.class>SomeCLASS</items.class> >>> <inverse_fk_descriptor_ids>2</inverse_fk_descriptor_ids> >>></CollectionDescriptor> >>> >>>I keep getting exceptions like this : >>>Expcetion : java.util.NoSuchElementException >>>StackTrace: java.util.NoSuchElementException at >>>ojb.broker.accesslayer.RsIterator.next(RsIterator.java) at >>>ojb.broker.singlevm.PersistenceBrokerImpl.getCollectionByQuery >>>(PersistenceBrokerImpl.java:931)at=20 >>>ojb.broker.singlevm.PersistenceBrokerImpl.getCollectionByQuery >>>(PersistenceBrokerImpl.java:1000)at=20 >>>ojb.broker.singlevm.PersistenceBrokerImpl.getCollectionByQuery >>>(PersistenceBrokerImpl.java:1093)at=20 >>>ojb.broker.singlevm.PersistenceBrokerImpl.getCollectionByQuery >>>(PersistenceBrokerImpl.java:1080)at >>>.... >>> >>>that doesn't help me so much. >>> >>> >>>--=20 >>>Leandro Rodrigo Saad Cruz >>>IT - Inter Business Tecnologia e Servicos (IB) >>>http://www.ibnetwork.com.br >>> >>> >>>_______________________________________________ >>>Objectbridge-developers mailing list >>>Obj...@li... >>>https://lists.sourceforge.net/lists/listinfo/objectbridge-developers >>> >>> |
From: Mahler T. <tho...@it...> - 2002-03-22 15:55:43
|
Hi Florian, > Hi! > > I'm currently investigating how to improve the object cache and how to > create a "factory" for Identity objects. > > The object cache already stores identities and objects in a > HashMap, but > unfortunately you cannot retrieve the key of a value from a HashMap > reasonably. The idea is now to create a "DoubleHashMap" that > maps keys to > values and values to keys in an efficient way using SoftReferences. If I get you right, you want to use the already existing ObjectCache to serve also a Identity cache. That's a cool idea ! <snip> > > Now the questions: > > - Do you think this approach is valid and is it worth to pursue it > Yes !!! > - Does anybody know of an implementation of this concept (I known the > jakarta project has a somewhat related class, but it is a > DoubleTreeMap and > we do not need the overhead of sorting the objects). > in class ObjectEnvelopeTable we have somewhat similar problem that requires to maintain a HashMap and a List to have two independend views on the Table of ObjectEnvelopes registered to a transaction. Maybe you find some inspiration there. My general suggestion: Keep it simple. Better to waste some memory by maintaining two hashtables than building a too difficult solution. Thomas |
From: Leandro R. S. C. <le...@ib...> - 2002-03-22 15:55:15
|
Sorry man, in fact the problem was in another line at repository.xml I defined a ReferenceDescriptor that pointed to the wrong class field. By the way. If I have a association like this A 1 ----- N B Do I have to defined CollectionDescriptors(from A to B) and ReferenceDescriptos( from B to A) or just one of them ?? On Fri, 2002-03-22 at 12:20, Mahler Thomas wrote: > Hi Leandro, >=20 > I'll try to explain the 1-n section from the tutorial3. > Say you have a class ProductGroup with a Vector attribute allArticlesInGr= oup > that holds all Article objects belonging to this group. >=20 > That is: *one* ProductGroup holds *n* Articles. >=20 > You must tell OJB how to load the allArticlesInGroup attribute on loading= a > ProductGroup object. > This is done by the following CollectionDescriptor: > <ClassDescriptor id=3D"2"> > <class.name>test.ojb.broker.ProductGroup</class.name> > ... > <CollectionDescriptor id=3D"1"> > <cdfield.name>allArticlesInGroup</cdfield.name> > <items.class>test.ojb.broker.Article</items.class> > <inverse_fk_descriptor_ids>4</inverse_fk_descriptor_ids> > </CollectionDescriptor> > ... >=20 > This descriptor contains the following info: > - The class ProductGroup has a container attribute allArticlesInGroup.=20 > The Java-type of this attribute is not declared. It maybe of type > SomeType[],=20 > Collection, or ManageableCollection. > - The Items in this Container are of type Article > - The Mapping of class Article has a attribute with id=3D"4" that holds a= =20 > foreign key value idetifying the associated ProductGroup >=20 > HTH, >=20 > Thomas >=20 > > -----Urspr=FCngliche Nachricht----- > > Von: Leandro Rodrigo Saad Cruz [mailto:le...@ib...] > > Gesendet: Freitag, 22. M=E4rz 2002 15:30 > > An: obj...@li... > > Betreff: [OJB-developers] Using CollectionDescriptor in repository.xml > >=20 > >=20 > > Hi all. There is one thing I didn't understand from the docs about > > association mapping > > http://objectbridge.sourceforge.net/tutorial3.html#1-n > >=20 > > <CollectionDescriptor id=3D"1"> > > <cdfield.name>collection</cdfield.name>=20 > > ******* -> does this field must be present in repository.xml in > > SomeCLASS ClassDescriptor ? or just be a field in SomeCLASS impl ? > >=20 > > <items.class>SomeCLASS</items.class> > > <inverse_fk_descriptor_ids>2</inverse_fk_descriptor_ids> > > </CollectionDescriptor> > >=20 > > I keep getting exceptions like this : > > Expcetion : java.util.NoSuchElementException > > StackTrace: java.util.NoSuchElementException at > > ojb.broker.accesslayer.RsIterator.next(RsIterator.java) at > > ojb.broker.singlevm.PersistenceBrokerImpl.getCollectionByQuery > > (PersistenceBrokerImpl.java:931)at=20 > > ojb.broker.singlevm.PersistenceBrokerImpl.getCollectionByQuery > > (PersistenceBrokerImpl.java:1000)at=20 > > ojb.broker.singlevm.PersistenceBrokerImpl.getCollectionByQuery > > (PersistenceBrokerImpl.java:1093)at=20 > > ojb.broker.singlevm.PersistenceBrokerImpl.getCollectionByQuery > > (PersistenceBrokerImpl.java:1080)at > > .... > >=20 > > that doesn't help me so much. > >=20 > >=20 > > --=20 > > Leandro Rodrigo Saad Cruz > > IT - Inter Business Tecnologia e Servicos (IB) > > http://www.ibnetwork.com.br > >=20 > >=20 > > _______________________________________________ > > Objectbridge-developers mailing list > > Obj...@li... > > https://lists.sourceforge.net/lists/listinfo/objectbridge-developers > >=20 --=20 Leandro Rodrigo Saad Cruz IT - Inter Business Tecnologia e Servicos (IB) http://www.ibnetwork.com.br |
From: Mahler T. <tho...@it...> - 2002-03-22 15:21:05
|
Hi Leandro, I'll try to explain the 1-n section from the tutorial3. Say you have a class ProductGroup with a Vector attribute = allArticlesInGroup that holds all Article objects belonging to this group. That is: *one* ProductGroup holds *n* Articles. You must tell OJB how to load the allArticlesInGroup attribute on = loading a ProductGroup object. This is done by the following CollectionDescriptor: <ClassDescriptor id=3D"2"> <class.name>test.ojb.broker.ProductGroup</class.name> ... <CollectionDescriptor id=3D"1"> <cdfield.name>allArticlesInGroup</cdfield.name> <items.class>test.ojb.broker.Article</items.class> <inverse_fk_descriptor_ids>4</inverse_fk_descriptor_ids> </CollectionDescriptor> ... This descriptor contains the following info: - The class ProductGroup has a container attribute allArticlesInGroup.=20 The Java-type of this attribute is not declared. It maybe of type SomeType[],=20 Collection, or ManageableCollection. - The Items in this Container are of type Article - The Mapping of class Article has a attribute with id=3D"4" that holds = a=20 foreign key value idetifying the associated ProductGroup. HTH, Thomas > -----Urspr=FCngliche Nachricht----- > Von: Leandro Rodrigo Saad Cruz [mailto:le...@ib...] > Gesendet: Freitag, 22. M=E4rz 2002 15:30 > An: obj...@li... > Betreff: [OJB-developers] Using CollectionDescriptor in = repository.xml >=20 >=20 > Hi all. There is one thing I didn't understand from the docs about > association mapping > http://objectbridge.sourceforge.net/tutorial3.html#1-n >=20 > <CollectionDescriptor id=3D"1"> > <cdfield.name>collection</cdfield.name>=20 > ******* -> does this field must be present in repository.xml in > SomeCLASS ClassDescriptor ? or just be a field in SomeCLASS impl ? >=20 > <items.class>SomeCLASS</items.class> > <inverse_fk_descriptor_ids>2</inverse_fk_descriptor_ids> > </CollectionDescriptor> >=20 > I keep getting exceptions like this : > Expcetion : java.util.NoSuchElementException > StackTrace: java.util.NoSuchElementException at > ojb.broker.accesslayer.RsIterator.next(RsIterator.java) at > ojb.broker.singlevm.PersistenceBrokerImpl.getCollectionByQuery > (PersistenceBrokerImpl.java:931)at=20 > ojb.broker.singlevm.PersistenceBrokerImpl.getCollectionByQuery > (PersistenceBrokerImpl.java:1000)at=20 > ojb.broker.singlevm.PersistenceBrokerImpl.getCollectionByQuery > (PersistenceBrokerImpl.java:1093)at=20 > ojb.broker.singlevm.PersistenceBrokerImpl.getCollectionByQuery > (PersistenceBrokerImpl.java:1080)at > .... >=20 > that doesn't help me so much. >=20 >=20 > --=20 > Leandro Rodrigo Saad Cruz > IT - Inter Business Tecnologia e Servicos (IB) > http://www.ibnetwork.com.br >=20 >=20 > _______________________________________________ > Objectbridge-developers mailing list > Obj...@li... > https://lists.sourceforge.net/lists/listinfo/objectbridge-developers >=20 |
From: Leandro R. S. C. <le...@ib...> - 2002-03-22 15:14:16
|
Some files are messed up, please, could you, the cvs admin correct the problem using `cvs admin -kkv FILE` quote from http://cvsbook.red-bean.com/cvsbook.html#CVS_is_not_doing_line-end_conversion_correctly "CVS is not doing line-end conversion correctly If you're running the CVS client on a non-Unix platform and are not getting the line-end conventions that you want in some working copy files, it's usually because they were accidentally added with -kb when they shouldn't have been. This can be fixed in the repository with, believe it or not, the command: floss$ cvs admin -kkv FILE The -kkv means to do normal keyword substitution and implies normal line-end conversions as well. (Internally, CVS is a bit confused about the difference between keyword substitution and line-end conversion. This confusion is reflected in the way the -k options can control both parameters.) Unfortunately, that admin command only fixes the file in the repository - your working copy still thinks the file is binary. You can hand edit the CVS/Entries line for that file, removing the -kb, but that won't solve the problem for any other working copies out there." -- Leandro Rodrigo Saad Cruz IT - Inter Business Tecnologia e Servicos (IB) http://www.ibnetwork.com.br |
From: Leandro R. S. C. <le...@ib...> - 2002-03-22 14:29:39
|
Hi all. There is one thing I didn't understand from the docs about association mapping http://objectbridge.sourceforge.net/tutorial3.html#1-n <CollectionDescriptor id="1"> <cdfield.name>collection</cdfield.name> ******* -> does this field must be present in repository.xml in SomeCLASS ClassDescriptor ? or just be a field in SomeCLASS impl ? <items.class>SomeCLASS</items.class> <inverse_fk_descriptor_ids>2</inverse_fk_descriptor_ids> </CollectionDescriptor> I keep getting exceptions like this : Expcetion : java.util.NoSuchElementException StackTrace: java.util.NoSuchElementException at ojb.broker.accesslayer.RsIterator.next(RsIterator.java) at ojb.broker.singlevm.PersistenceBrokerImpl.getCollectionByQuery(PersistenceBrokerImpl.java:931)at ojb.broker.singlevm.PersistenceBrokerImpl.getCollectionByQuery(PersistenceBrokerImpl.java:1000)at ojb.broker.singlevm.PersistenceBrokerImpl.getCollectionByQuery(PersistenceBrokerImpl.java:1093)at ojb.broker.singlevm.PersistenceBrokerImpl.getCollectionByQuery(PersistenceBrokerImpl.java:1080)at .... that doesn't help me so much. -- Leandro Rodrigo Saad Cruz IT - Inter Business Tecnologia e Servicos (IB) http://www.ibnetwork.com.br |
From: Mahler T. <tho...@it...> - 2002-03-22 14:12:15
|
Hi Leandro, You can only use Datatypes for PK fields that can be mapped on single = RDBMS table columns. OJB provide compound PKs. SO if you want to use standard OJB mapping techniques you are bound to JDBC types. If you *must* use Identity Objects as PKs you might have a look how I = am doing this in ojb.odmg.collections.DMapIml or DListImpl. HTH, Thomas > -----Urspr=FCngliche Nachricht----- > Von: Leandro Rodrigo Saad Cruz [mailto:le...@ib...] > Gesendet: Donnerstag, 21. M=E4rz 2002 18:13 > An: obj...@li... > Betreff: [OJB-developers] Using Objects as primary keys >=20 >=20 > Hi all.How can use Objects as primary keys ? is there anyway I can > config a field descriptor to handle this ? or am I limited to=20 > JDBC types > ? >=20 > --=20 > Leandro Rodrigo Saad Cruz > IT - Inter Business Tecnologia e Servicos (IB) > http://www.ibnetwork.com.br >=20 >=20 > _______________________________________________ > Objectbridge-developers mailing list > Obj...@li... > https://lists.sourceforge.net/lists/listinfo/objectbridge-developers >=20 |
From: Georg S. <ge...@me...> - 2002-03-22 12:52:33
|
Hi, I am experiencing a very serious locking problem, and I have expanded quite a bit of effort to look into it, I haven't solved it yet, but I have found a few interesting things, which I would like to discuss: 1.) How do you make sure that 2 threads are synchronized when locking? e.g. I am using repeatable-read strategy and in RepeatableReadStragegy.java: public boolean readLock(TransactionImpl tx, Object obj) { LockEntry writer = getWriter(obj); ====> race condition, another thread could put a writer if (writer == null) { ------------------------------------------------------- maybe synchronization happens somewhere else, but to make sure, I put synchronized to all the methods in LockManagerDefaultImpl.java 2.) Let me explain what problem I am experiencing: I have an object A which references an Object B (1:1), Thread-1 Thread-2 oqlquery for A tx.lock(A,tx.upgrade) oqlquery for A (LockNotGrantedException) (since I use RepeatableRead this should happen) A.setFieldB(B) tx.commit() oqlquery for A !!!!!FieldB is null (should be B) I have to mention that Object A is a dynamic Proxy. As I looked into the internals of ojb I came across the following explanation for the abovementioned behaviour: a) Thread-1 obtains a Write lock b) FieldB is changed to B, update statement prepared (but not yet commited in database (==> in database FieldB [actually the Fk-Field, but for the rest of this I will just say FieldB] is still null) c) Thread-2 tries to obtain a read lock which rightly (repeatable-read) is not granted => in TransactionImpl.java the following happens: throw new LockNotGrantedException("Can not lock " + obj + " for READ"); + obj + means that java will call obj.toString(), which means that since obj is a proxy it gets delegated to the IndirectionHandler, which (if realSubject hasn't been materialized yet) will materialize the realSubject. This is done by loading it from the database (Thread-1 removed it from the cache before). BUT, in the database there is still the old value of FieldB, because Thread1 hasn't commited the database-transaction yet. The loaded object is then put into the cache. d) The database-transaction in Thread-1 commits the new value for fieldB, but since it was just put into the cache with the old values subsequent queries to it, still have the old value. e) I just put throw new LockNotGrantedException() to stop obj from materializing. This reduced the incident of the aforementioned problem, but it didn't stop it completly, so I assume there are other parts of the code which show a similar effect. 3.) On debugging the just mentioned problem I stumbled across the following: In LockStrategyFactory.java getStrategyFor(Object obj) a LockStrategy is assigned by looking up obj.getClass(), which for a dynamic Proxy is not the actual class ==> the default ReadUncommitedStrategy is assigned for every proxy. The following lines will change this: Instead of using: int isolationLevel = getIsolationLevel(obj.getClass()); do: if (obj instanceof Proxy) { InvocationHandler ih = Proxy.getInvocationHandler(obj); if ((ih != null) && (ih instanceof IndirectionHandler)) { c = ((IndirectionHandler) ih).getIdentity().getObjectsClass(); } else { //System.err.println("UPGRADING PROXY FAILED: " + c); //TODO: handle this error case } } if (c == null) { c = obj.getClass(); } int isolationLevel = getIsolationLevel(c); 4.) The following observation is just anecdotal, It seems that when querying for an object which is a proxy with e.g.: DList l = (DList) query.execute(); if (l.size() == 1) { tx.abort; return; } It seems that read-locks associated with the 1 result are not being released (the ObjectEnvelopeTable doesn't have any entries) My only solution is to actually materialize the queried subject by doing the following: SomeClass A = (SomeClass) l.get(0); and then calling a method on it => object is materialized and is in the ObjectEnvelopeTable and read-locks are release when calling tx.abort(); 5.) A general question about locking. Is there any possibility you are going to implement some kind of blocked locking (i.e. a thread simply waits for a lock to become available), instead of throwing a LockNotGrantedException? Regards Georg |
From: Jakob B. <jbr...@ho...> - 2002-03-22 07:02:34
|
hi, i just added additional capabilities for report queries to the cvs. ojb now supports groupBy and functions on columns for report queries. crit = new Criteria(); crit.groupBy("id"); query = QueryFactory.newReportQuery(Person.class, crit); query.setColumns(new String[]{"id","name","vorname","sum(konti.saldo)"}); broker.getReportQueryIteratorByQuery(query); // sum(konti.saldo) now handled correctly this will execute the following sql: SELECT tabPerson.id,tabPerson.name,tabPerson.vorname,sum(tabKonto.saldo) FROM tabPerson INNER JOIN tabKonto ON tabKonto.idPerson = tabPerson.id GROUP BY tabPerson.id i need some help/input in the following issue: the query will only return id, name etc. for persons having at least one account. to retrieve data from persons without an account the join clause should be changed to "LEFT OUTER JOIN". i'm now looking for a way to define the join type: - should it be defined for criteria or query ? - is there are way to automagically detect th join type ? - is join type only an issue for report queries ? any input and help will be appreciated. jakob |
From: Thomas M. <tho...@ho...> - 2002-03-22 06:57:56
|
hy ! Joa...@tp... wrote: <snip> > > do we also need JUnit Tests for such configureable features as the global > High/Low ID Generator? The Problem here is the same as with JUnit tests for > the C/S-mode. We'd need to modify OJB.properties to test these features. > We either make a general system for changeing specific configuration > entries for specific tests or rewrite the build.xml to re-run the tests > with several alternate configurations. This may raise an interesting discussion of our testing strategy. The JUnit evangelists will tell you that it is best practise to test *everything*. Even getter and setter methods ! They generally also recommend to perform whitebox tests. Using this approach you can achieve 100% code coverage for your tests. The Approach I choose is not that strict: - Most tests are highlevel blackbox tests that run against the public OJB APIs. There are very little whitebox tests (e.g. ODMG lifecycle). - The tests are usually coarse grained. coherent blocks of functionality ("use cases") are tested together. Here are my reasons for going this way: - The main aim is to assure that the API works properly for end-users. - This is done by checking typical use case scenarios. - I don't see realistic reasons why a getter or setter might fail. Following this principle I suggest: 1. provide TestCases for the HighLow ID Generator, 2. don't write Testcases for the configuration stuff, write more TestCases for 1. ;-) > Does Sourceforge allow running > automated regression tests on their system? I don't think so. But afaik they provide nightly builds. But I don't know if they support ANT builds. This way we'd be able to run > regression tests against several databases every day. If sourceforge > doesn't allow such things, we could do this on our internal system (we have > similar regression tests, along with auto-generated documentation for our > internal project) as soon as our server is back to live (right now he is in > a rather bad condition). > As I see it the Junit tests are a thing each developer *must* do individually before checking in code. Project managers (like me) who assemble releases *must* run the complete Junit testsuite before publishing new releases. I don't think it's essential to have complete nightly builds. But of course I appreciate your offer! > [snip] > >>5. We currently don't have a proper change management system. But >>there is a excel file (todo.xls) in the base dir of the OJB-1-0 >>project. Please add your changes to this file. This file is used to >>assemble the change log for new releases. Thus it is important to >>register all changes here ! (If you have an idea how to provide a >>better change management please contact me.) >> > > I suggest we don't use and excel file, for several reasons, some of which > are just my personal taste and might therefore not be inportant: > > - many people don't run Windows & those who do might not have Excel > (fortunately I (have to) use Windows and work and do have Excel installed). > - cvs can't give you a meaningfull diff of any Office document. > - security implications (cut & paste from/to office documents might copy > more than is visible) > - i don't like Excel ;-) > I don't have Excel on my Linux box. But use StarOffice instead. It's free, cross-plattform, and can handle all MS-Office formats. In fact the todo.xls was written from my StarOffice ! > a simple text-format TODO might be an alternative. Granted, handling this > would be a bit more complicated, but at least everyone can do it. Another > idea for a changelog might be something along the lines of cvs2pl (to be > found at http://www.red-bean.com/cvs2cl/), I just recently found it and > haven't tried it, but it looks interesting. > > (I'll just update my changes there nevertheless, until we find an > alternative) > IMO The best thing would be to have a live database hosted at SOurceForge. cu, Thomas |
From: Leandro R. S. C. <le...@ib...> - 2002-03-21 17:13:48
|
Hi all.How can use Objects as primary keys ? is there anyway I can config a field descriptor to handle this ? or am I limited to JDBC types ? -- Leandro Rodrigo Saad Cruz IT - Inter Business Tecnologia e Servicos (IB) http://www.ibnetwork.com.br |
From: Mahler T. <tho...@it...> - 2002-03-21 17:04:23
|
Hi Joachim, <snip> > Ok, now it's done. It's configurable by setting > SequenceManagerGlobalIDs to > true/false. The default-setting (old-style, per-class IDs) will stay, > unless explicitely reconfigured. > Fine ! > It got a little bit of documentation in OJB.properties. I > think I'll add > some more documentation in the "true" documentation (as soon > as I find the > correct place for it). > there is a document on the OJB.properties file in src/doc/system/ojb-properties.html > >>> The function is not yet configurable (except for setting > >>> globalSequence = true in the constructor and recompiling), as I > >>> don't to wait for the rewrite of BaseConfiguration (which I would > >>> volunteer to do, if no-one has started work on it yet, maybe if > >>> anyone has any design ideas. If not, I'll just do it how I see fit > >>> ;-) > >> > >> > >> I think that no one has started on the refactoring of the > >> Configuration stuff. So you can just give it a try. > > > > OK, I'll try this. My idea is to unite Type-Conversion and > > Default-Values so that an incorrect entry could result in a good > > log-entry and the default value beeing used. something like > > getBoolean("someConfiguration", true) and > > getInteger("someConfiguration", 42) and so on. > > Done & checked in. Basically you now have the ability to do a > getString, > getBoolean, getInteger with default values. Additionally there's a > getClass-Function, that can even check, wether the specified class > implements/extends the correct Interface/Baseclass. And > getStrings() is > just the next-generation parseSeperatedString(). Right now only > PersitenceBrokerFactoryConfiguration and > SequenceManagerHighLowImpl use > these functions. I'm pretty sure that some of > PersistenceBrokerFactoryConfigurations getter-methods can be > made obsolete > by doing direct get<type>-access in the plugabble classes (like > getSequenceManagerGrabSize()). > I will have a look at this issue ! Thanks for your efforts, Thomas > regards > Joachim Sauer > > > _______________________________________________ > Objectbridge-developers mailing list > Obj...@li... > https://lists.sourceforge.net/lists/listinfo/objectbridge-developers > |