Re: [OJB-developers] Re: Named Root Objects
Brought to you by:
thma
From: Michael N. <mic...@gm...> - 2002-01-15 21:23:10
|
Hi Thomas! Is there a way to let OJB create and remove tables automatically. In my opinion such a feature could come in quite handy while developing your app. JBoss has such an option. An XSLT Stylesheet that transforms the repository XML into sql statements could look like this: <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="text" omit-xml-declaration="yes" indent="yes"/> <xsl:template match="/"> <xsl:for-each select="MappingRepository/ClassDescriptor"> <!-- generate sql drop table statement--> <xsl:text>drop table </xsl:text><xsl:value-of select="table.name"/><xsl:text>; </xsl:text> <!-- generate sql create table statement--> <xsl:text>create table </xsl:text><xsl:value-of select="table.name"/><xsl:text> ( </xsl:text> <xsl:for-each select="FieldDescriptor"> <xsl:value-of select="column.name"/> <xsl:text> </xsl:text> <xsl:value-of select="jdbc_type"/> <xsl:if test="PrimaryKey='true'"> <xsl:text> NOT NULL PRIMARY KEY</xsl:text> </xsl:if> <xsl:text> </xsl:text> </xsl:for-each> <xsl:text>); </xsl:text> </xsl:for-each> </xsl:template> </xsl:stylesheet> What still remains to be done is inserting switches that indicate whether you want automatic table creation/removal enabled or not. It might be possible to change the repository.dtd accordingly. Another thing I don't know is whether jdbc types are automatically mapped to sql types by the jdbc driver. Greetings, Michael ----- Original Message ----- From: "Mahler Thomas" <tho...@it...> To: "'Michael Nowotny'" <mic...@gm...>; "ojb" <obj...@li...> Sent: Tuesday, January 15, 2002 10:29 AM Subject: AW: [OJB-developers] Re: Named Root Objects > Hi Michael, > > > There will be a lot of people using OJB who do not use named roots. > Just imagine their faces when the GC starts and deletes all their objects > because they where unreferenced >:-() !!! > > Thus Having the GC as a separate tool is a good idea, not to say a MUST! > > Implementing a GC that will reclaim everything that can not be reached from > a named root will not be difficult. > The algorithm you describe is a simple "mark and sweep" algorithm. Would be > fun to implement such a thing! > > cheers, > > Thomas > > > > > > Hi Thomas! > > > > I've been thinking about the GC process over the last few days. > > > > > Currently there is no GC implemented. > > > IMHO it will be VERY difficult to have a real GC as it > > would be possible > > > with an OODBMS. > > > It will be very difficult to decide if objects can safely > > be deleted. > > > > > > BUT: we have been thinking of changing the semantics of > > DList.remove() > > > an similar methods as name roots unbind so that removed objects are > > > deleted from the DB. > > > > A first step towards true persistence by reachability could > > be to offer > > offline GC. This way you don't have the to deal with objects which not > > reachable from any named root object any more but are still > > referenced under > > another transaction that has not yet committed. The algorithm > > could look > > like this: > > > > 1. Make a list of all objects stored in the database > > 2. from every named root object traverse the object graph and mark any > > object you come across as being persistent > > 3. delete all the objects from the database which are > > currently not marked > > as persistent. > > > > The algorithm can be implemented using recursion. In order to avoid > > indefinite loops caused by cyclic references, the algorithm > > has to check > > whether an object under investigation is already marked. > > > > Another advantage is that people who do not want seamless > > persistence the > > "Java Way" but instead want to have a more basic level > > control over their > > data still have the option not to execute the garbage collector. > > > > What do you think about it? > > > > > > Greetings Michael > > ----- Original Message ----- > > From: "Thomas Mahler" <tho...@ho...> > > To: "Michael Nowotny" <mic...@gm...>; "ojb" > > <obj...@li...> > > Sent: Wednesday, January 09, 2002 6:51 PM > > Subject: Re: Named Root Objects > > > > > > > Hi again, > > > > > > > > > Michael Nowotny wrote: > > > > > > > Hi Thomas! > > > > > > > > Thanks for the illustration. Binding collections works > > fine for me now! > > > > The reason why my earlier attempt failed was that I was > > still using > > > > InstantDB.It seems that some transactions got only > > halfway commited due > > to > > > > program termination following db.close(). Now I'm using > > Hypersonic and > > > > everything works. > > > > > > > > > > Fine ! > > > > > > > > > > During the course of setting up a test procedure I came > > across some > > strange > > > > behaviour. The following code snipped throws an > > ObjectNameNotBoundException. > > > > > > > > // fails: > > > > tx = odmg.newTransaction(); > > > > tx.begin(); > > > > db.bind(odmg.newDList(), "MyList"); > > > > db.unbind("MyList"); > > > > db.bind(odmg.newDList(), "MyList"); > > > > // DList list = (DList)db.lookup("MyList"); > > > > tx.commit(); > > > > > > > > tx = odmg.newTransaction(); > > > > tx.begin(); > > > > DList newList = (DList)db.lookup("MyList"); > > > > tx.commit(); > > > > > > > > Binding the same name twice within the same transaction > > seems to cause > > an > > > > error. > > > > > > > > > Oops, This is a bug. I'll add it to my todo list! > > > > > > > > > This is not very important though because usually one wouldn't want > > > > to bind an object to a some name and thereafter unbinding > > that name > > withing > > > > the same transaction. > > > > > > > > Another question arose when I had a look at the contents > > of my database. > > If > > > > I add content to my list which is a named root object > > this content gets > > > > persistent as well. That's part of persistence by > > reachability. But when > > I > > > > unbind the root object and the content is therefore no > > longer reachable, > > it > > > > doesn't get removed from the database but is still > > present. Is there any > > way > > > > of performing some kind of garbage collection? > > > > > > > > > > > > > > > > Currently there is no GC implemented. > > > IMHO it will be VERY difficult to have a real GC as it > > would be possible > > > with an OODBMS. > > > It will be very difficult to decide if objects can safely > > be deleted. > > > > > > BUT: we have been thinking of changing the semantics of > > DList.remove() > > > an similar methods as name roots unbind so that removed objects are > > > deleted from the DB. > > > > > > Any ideas? > > > > > > -- Thomas > > > > > > > > > > > > > > > > Keep up the good work! > > > > > > > > Thanks, Michael > > > > > > > > ----- Original Message ----- > > > > From: "Thomas Mahler" <tho...@ho...> > > > > To: "Michael Nowotny" <mic...@gm...>; "ojb" > > > > <obj...@li...> > > > > Sent: Tuesday, January 08, 2002 8:20 PM > > > > Subject: Re: Named Root Objects > > > > > > > > > > > > > > > >>Hi Michael, > > > >> > > > >>please see the attached Java class. > > > >> > > > >>You can replace the original version of > > test.ojb.odmg.OdmgExamples with > > > >>this new version to have it executed with the OJB JUnit tests. > > > >> > > > >>There is a new testMethod testNrmAndDlists that tests > > your scenario. > > > >>Works great! > > > >> > > > >>HTH, > > > >> > > > >>Thomas > > > >> > > > >>Michael Nowotny wrote: > > > >> > > > >> > > > >>>Hi Thomas! > > > >>> > > > >>>Just found your OJB project on sourceforge. I think it's > > great to have > > > >>> > > > > an > > > > > > > >>>open source ODMG implementation around. > > > >>>Now I've got a question concerning the ODMG implemetation. > > > >>>Is it possible to use a DList for example as a named root object. > > > >>> > > > > Binding > > > > > > > >>>that object to a name works but looking it up again causes an > > > >>>IllegalArgumentException. > > > >>> > > > >>>Have you ever tried to bind a Collection. If so, I would > > be grateful if > > > >>> > > > > you > > > > > > > >>>could drop me some lines of source code. > > > >>> > > > >>>Thanks Michael > > > >>> > > > >>> > > > >>> > > > >>> > > > >>> > > > >>> > > > >> > > > >> > > > > > > > > > > > > > > > > -------------------------------------------------------------- > > ------------ > > -- > > > > ---- > > > > > > > > > > > > > > > >>package test.ojb.odmg; > > > >> > > > >> > > > >>import junit.framework.TestCase; > > > >>import ojb.broker.Identity; > > > >>import ojb.broker.PersistenceBroker; > > > >>import ojb.broker.PersistenceBrokerFactory; > > > >>import ojb.broker.cache.ObjectCacheFactory; > > > >>import ojb.odmg.OJB; > > > >>import ojb.odmg.states.ModificationState; > > > >>import ojb.odmg.states.StateNewClean; > > > >>import ojb.odmg.states.StateNewDirty; > > > >>import org.odmg.*; > > > >> > > > >>import java.util.List; > > > >> > > > >>/** Demo Application that shows basic concepts for > > Applications using > > the > > > >> > > > > OJB ODMG > > > > > > > >> * implementation as an transactional object server. > > > >> */ > > > >>public class OdmgExamples extends TestCase > > > >>{ > > > >> public static void main(String[] args) > > > >> { > > > >> String[] arr = {CLASS.getName()}; > > > >> junit.textui.TestRunner.main(arr); > > > >> } > > > >> > > > >> private static Class CLASS = OdmgExamples.class; > > > >> private String databaseName; > > > >> > > > >> /** > > > >> * Insert the method's description here. > > > >> * Creation date: (24.12.2000 00:33:40) > > > >> */ > > > >> public OdmgExamples(String name) > > > >> { > > > >> super(name); > > > >> } > > > >> > > > >> /** > > > >> * Insert the method's description here. > > > >> * Creation date: (06.12.2000 21:58:53) > > > >> */ > > > >> public void setUp() > > > >> { > > > >> databaseName = > > > >> > > > > > > PersistenceBrokerFactory.getConfiguration().getRepositoryFilename(); > > > > > > > >> > > > >> } > > > >> > > > >> /** > > > >> * Insert the method's description here. > > > >> * Creation date: (06.12.2000 21:59:14) > > > >> */ > > > >> public void tearDown() > > > >> { > > > >> databaseName = null; > > > >> } > > > >> > > > >> /**TestThreadsNLocks state transition of modification states*/ > > > >> public void testModificationStates() > > > >> { > > > >> // get facade instance > > > >> Implementation odmg = OJB.getInstance(); > > > >> Database db = odmg.newDatabase(); > > > >> //open database > > > >> try > > > >> { > > > >> db.open(databaseName, Database.OPEN_READ_WRITE); > > > >> } > > > >> catch (ODMGException ex) > > > >> { > > > >> fail("ODMGException: " + ex.getMessage()); > > > >> } > > > >> ModificationState oldState = StateNewClean.getInstance(); > > > >> ModificationState newState = oldState.markDirty(); > > > >> assertEquals(StateNewDirty.getInstance(), newState); > > > >> > > > >> oldState = newState; > > > >> newState = oldState.markDirty(); > > > >> assertEquals(oldState, newState); > > > >> > > > >> > > > >> // close database > > > >> try > > > >> { > > > >> db.close(); > > > >> } > > > >> catch (ODMGException ex) > > > >> { > > > >> fail("ODMGException: " + ex.getMessage()); > > > >> } > > > >> > > > >> } > > > >> > > > >> public void testOdmgSession() > > > >> { > > > >> // get facade instance > > > >> Implementation odmg = OJB.getInstance(); > > > >> Database db = odmg.newDatabase(); > > > >> //open database > > > >> try > > > >> { > > > >> db.open(databaseName, Database.OPEN_READ_WRITE); > > > >> } > > > >> catch (ODMGException ex) > > > >> { > > > >> fail("ODMGException: " + ex.getMessage()); > > > >> } > > > >> Transaction tx = odmg.newTransaction(); > > > >> > > > >> //perform transaction > > > >> try > > > >> { > > > >> tx.begin(); > > > >> > > > >> Article example = new Article(); > > > >> example.setArticleId(777); > > > >> db.makePersistent(example); > > > >> > > > >> > > > >> > > > >> // modify Object > > > >> example.setStock(333); > > > >> example.addToStock(47); > > > >> example.addToStock(7); > > > >> example.addToStock(4); > > > >> > > > >> > > > >> //System.out.println("now commit all changes..."); > > > >> tx.commit(); > > > >> } > > > >> catch (Exception ex) > > > >> { > > > >> tx.abort(); > > > >> } > > > >> > > > >> // close database > > > >> try > > > >> { > > > >> db.close(); > > > >> } > > > >> catch (ODMGException ex) > > > >> { > > > >> fail("ODMGException: " + ex.getMessage()); > > > >> } > > > >> } > > > >> > > > >> public void testOQLQuery() > > > >> { > > > >> // get facade instance > > > >> Implementation odmg = OJB.getInstance(); > > > >> Database db = odmg.newDatabase(); > > > >> //open database > > > >> try > > > >> { > > > >> db.open(databaseName, Database.OPEN_READ_WRITE); > > > >> } > > > >> catch (ODMGException ex) > > > >> { > > > >> fail("ODMGException: " + ex.getMessage()); > > > >> } > > > >> Transaction tx = odmg.newTransaction(); > > > >> > > > >> //perform transaction > > > >> try > > > >> { > > > >> tx.begin(); > > > >> > > > >> > > > >> OQLQuery query = odmg.newOQLQuery(); > > > >> query.create("select anArticle from " + > > > >> > > > > Article.class.getName() + " where articleId = 7"); > > > > > > > >> List results = (List) query.execute(); > > > >> > > > >> Article a = (Article) results.get(0); > > > >> > > > >> > > > >> // cross check with PersistenceBroker lookup > > > >> // 1. get OID > > > >> Article example = new Article(); > > > >> example.setArticleId(7); > > > >> Identity oid = new Identity(example); > > > >> // 2. lookup object by OID > > > >> PersistenceBroker broker = > > OJB.getInstance().getBroker(); > > > >> broker.clearCache(); > > > >> Article b = (Article) broker.getObjectByIdentity(oid); > > > >> > > > >> assertEquals("should be same object", a, b); > > > >> > > > >> //System.out.println("now commit all changes..."); > > > >> tx.commit(); > > > >> } > > > >> catch (Exception ex) > > > >> { > > > >> tx.abort(); > > > >> fail("ODMGException: " + ex.getMessage()); > > > >> } > > > >> > > > >> // close database > > > >> try > > > >> { > > > >> db.close(); > > > >> } > > > >> catch (ODMGException ex) > > > >> { > > > >> fail("ODMGException: " + ex.getMessage()); > > > >> } > > > >> } > > > >> > > > >> public void testNrmAndDlists() > > > >> { > > > >> // get facade instance > > > >> Implementation odmg = OJB.getInstance(); > > > >> Database db = odmg.newDatabase(); > > > >> //open database > > > >> try > > > >> { > > > >> db.open(databaseName, Database.OPEN_READ_WRITE); > > > >> } > > > >> catch (ODMGException ex) > > > >> { > > > >> fail("ODMGException: " + ex.getMessage()); > > > >> } > > > >> Transaction tx = odmg.newTransaction(); > > > >> > > > >> //perform transaction > > > >> try > > > >> { > > > >> tx.begin(); > > > >> > > > >> > > > >> OQLQuery query = odmg.newOQLQuery(); > > > >> query.create("select x from " + > > Article.class.getName() + " > > > >> > > > > where productGroupId = 7"); > > > > > > > >> DList results = (DList) query.execute(); > > > >> > > > >> > > > >> int originalSize = results.size(); > > > >> > > > >> OJB.getLogger().info(results); > > > >> > > > >> String name = "gimme fruits !"; > > > >> > > > >> db.bind(results, name); > > > >> tx.commit(); > > > >> > > > >> // clear the cache to make sure things are > > loaded from RDBMS > > ! > > > >> OJB.getInstance().getBroker().clearCache(); > > > >> > > > >> tx = odmg.newTransaction(); > > > >> tx.begin(); > > > >> > > > >> // look it up again > > > >> DList newResults = (DList) db.lookup(name); > > > >> > > > >> assertEquals(originalSize,newResults.size()); > > > >> OJB.getLogger().info(results); > > > >> > > > >> tx.commit(); > > > >> > > > >> > > > >> } > > > >> catch (Throwable t) > > > >> { > > > >> tx.abort(); > > > >> fail("ODMGException: " + t.getMessage()); > > > >> } > > > >> > > > >> // close database > > > >> try > > > >> { > > > >> db.close(); > > > >> } > > > >> catch (ODMGException ex) > > > >> { > > > >> fail("ODMGException: " + ex.getMessage()); > > > >> } > > > >> } > > > >> > > > >> > > > >> > > > >> public void testOQLQueryBind() > > > >> { > > > >> // get facade instance > > > >> Implementation odmg = OJB.getInstance(); > > > >> Database db = odmg.newDatabase(); > > > >> //open database > > > >> try > > > >> { > > > >> db.open(databaseName, Database.OPEN_READ_WRITE); > > > >> } > > > >> catch (ODMGException ex) > > > >> { > > > >> fail("ODMGException: " + ex.getMessage()); > > > >> } > > > >> Transaction tx = odmg.newTransaction(); > > > >> > > > >> //perform transaction > > > >> try > > > >> { > > > >> tx.begin(); > > > >> > > > >> > > > >> OQLQuery query = odmg.newOQLQuery(); > > > >> query.create("select anArticle from " + > > > >> > > > > Article.class.getName() + " where articleId = $678"); > > > > > > > >> query.bind(new Integer(7)); > > > >> > > > >> List results = (List) query.execute(); > > > >> > > > >> Article a = (Article) results.get(0); > > > >> > > > >> //crosscheck with PersistenceBroker lookup > > > >> // 1. get OID > > > >> Article example = new Article(); > > > >> example.setArticleId(7); > > > >> Identity oid = new Identity(example); > > > >> > > > >> ObjectCacheFactory.getObjectCache().clear(); > > > >> // 2. lookup object by OID > > > >> PersistenceBroker broker = > > OJB.getInstance().getBroker(); > > > >> broker.clearCache(); > > > >> Article b = (Article) broker.getObjectByIdentity(oid); > > > >> > > > >> assertEquals("should be same object", a, b); > > > >> > > > >> //System.out.println("now commit all changes..."); > > > >> tx.commit(); > > > >> } > > > >> catch (Exception ex) > > > >> { > > > >> tx.abort(); > > > >> fail("ODMGException: " + ex.getMessage()); > > > >> } > > > >> > > > >> // close database > > > >> try > > > >> { > > > >> db.close(); > > > >> } > > > >> catch (ODMGException ex) > > > >> { > > > >> fail("ODMGException: " + ex.getMessage()); > > > >> } > > > >> } > > > >> > > > >> public void tesOQLQueryOnCollections() > > > >> { > > > >> // get facade instance > > > >> Implementation odmg = OJB.getInstance(); > > > >> Database db = odmg.newDatabase(); > > > >> //open database > > > >> try > > > >> { > > > >> db.open(databaseName, Database.OPEN_READ_WRITE); > > > >> } > > > >> catch (ODMGException ex) > > > >> { > > > >> fail("ODMGException: " + ex.getMessage()); > > > >> } > > > >> Transaction tx = odmg.newTransaction(); > > > >> > > > >> //perform transaction > > > >> try > > > >> { > > > >> tx.begin(); > > > >> OQLQuery query = odmg.newOQLQuery(); > > > >> query.create("select aLotOfArticles from " + > > > >> > > > > Article.class.getName() + " where productGroupId = 4"); > > > > > > > >> DCollection results = (DCollection) query.execute(); > > > >> results = results.query("price > 35"); > > > >> > > > >> // now perform control query > > > >> query = odmg.newOQLQuery(); > > > >> query.create("select aLotOfArticles from " + > > > >> > > > > Article.class.getName() + " where productGroupId = 4 and > > price > 35"); > > > > > > > >> DCollection check = (DCollection) query.execute(); > > > >> > > > >> assertEquals(results, check); > > > >> > > > >> > > > >> tx.commit(); > > > >> } > > > >> catch (Exception ex) > > > >> { > > > >> tx.abort(); > > > >> ex.printStackTrace(); > > > >> fail("ODMGException: " + ex.getMessage()); > > > >> } > > > >> > > > >> // close database > > > >> try > > > >> { > > > >> db.close(); > > > >> } > > > >> catch (ODMGException ex) > > > >> { > > > >> fail("ODMGException: " + ex.getMessage()); > > > >> } > > > >> } > > > >> > > > >> > > > >> /**try to open non-existing db*/ > > > >> public void tesWrongDbName() > > > >> { > > > >> // get facade instance > > > >> OJB objectserver = OJB.getInstance(); > > > >> Database db = objectserver.newDatabase(); > > > >> > > > >> //try open database with non existing repository file: > > > >> String wrongDatabaseName = "ThereIsNoSuchFile"; > > > >> try > > > >> { > > > >> db.open(wrongDatabaseName, Database.OPEN_READ_WRITE); > > > >> fail("should not be able to open database " + > > > >> > > > > wrongDatabaseName); > > > > > > > >> } > > > >> catch (ODMGException ex) > > > >> { > > > >> return; > > > >> } > > > >> } > > > >>} > > > >> > > > >> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > _______________________________________________ > > Objectbridge-developers mailing list > > Obj...@li... > > https://lists.sourceforge.net/lists/listinfo/objectbridge-developers > > > |