I just had a look at the Modeler and at the DomainNode's JDBC Configuration (in the Main tab). I saw that 'Max Connections' was set to '1'. So perhaps I wasn't giving Cayenne much to play with in terms of connection pooling! I have now set it to '2'. (I imagine the default was a bit higher than these numbers).
In the program at the moment there ought to be at most two DataContexts. And one connection each is enough. So two should suffice until I go for the recommended approach with multiple users of having a DataContext per user. In that case I imagine 'Max Connections' will be related to the expected maximum number of concurrent users. But multi-user configuration is for another day... So far this server program hasn't fallen over... And I don't think there's any reason why I would need more than 2 connections is there? I like to keep everything as tight as possible - 3 connections would actually be an error that I would like to know about. Thank you ~ Chris Murphy On 12 December 2011 16:15, Robert Zeigler <robert.zeig...@roxanemy.com>wrote: > Hm. Cayenne is usually pretty good about managing the connection pooling > for you. > How many concurrent connections is your mysql db configured to allow? > > Robert > > On Dec 11, 2011, at 12/119:58 PM , Chris Murphy (www.strandz.org) wrote: > > > Thanks Robert, > > > > That was the answer. The memory leak disappeared. I now create a > > DataContext with 'method scope' that gets gc-ed when the method has > > finished. That brought up what must be another problem with my code which > > I'm investigating now: > > > > Caused by: org.apache.cayenne.CayenneRuntimeException: [v.3.0 Apr 26 2010 > > 09:59:17] Error detecting database type: Data source rejected > establishment > > of connection message from server: "Too many connections" > > at > org.apache.cayenne.dba.AutoAdapter.loadAdapter(AutoAdapter.java:185) > > at org.apache.cayenne.dba.AutoAdapter.getAdapter(AutoAdapter.java:155) > > at > > org.apache.cayenne.dba.AutoAdapter.getExtendedTypes(AutoAdapter.java:263) > > at > org.apache.cayenne.access.DataNode.performQueries(DataNode.java:243) > > at > > > org.apache.cayenne.access.DataDomainQueryAction.runQuery(DataDomainQueryAction.java:422) > > at > > > org.apache.cayenne.access.DataDomainQueryAction.access$000(DataDomainQueryAction.java:69) > > at > > > org.apache.cayenne.access.DataDomainQueryAction$2.transform(DataDomainQueryAction.java:395) > > at > > > org.apache.cayenne.access.DataDomain.runInTransaction(DataDomain.java:850) > > at > > > org.apache.cayenne.access.DataDomainQueryAction.runQueryInTransaction(DataDomainQueryAction.java:392) > > at > > > org.apache.cayenne.access.DataDomainQueryAction.execute(DataDomainQueryAction.java:121) > > at org.apache.cayenne.access.DataDomain.onQuery(DataDomain.java:743) > > at > > > org.apache.cayenne.util.ObjectContextQueryAction.runQuery(ObjectContextQueryAction.java:333) > > at > > > org.apache.cayenne.util.ObjectContextQueryAction.execute(ObjectContextQueryAction.java:96) > > at > org.apache.cayenne.access.DataContext.onQuery(DataContext.java:1278) > > at > > org.apache.cayenne.access.DataContext.performQuery(DataContext.java:1267) > > at > > > com.seasoft.store.orm.CayenneInterpretedQuery.execute(CayenneInterpretedQuery.java:265) > > at com.seasoft.store.DomainQuery.execute(DomainQuery.java:43) > > at > > > com.seasoft.store.DomainQueries.executeRetCollection(DomainQueries.java:56) > > at > > > com.cmts.business.orm.DOActivity.storeRealtimeReadings(DOActivity.java:113) > > at > > > com.cmts.business.SenderGasReceiver.storeRealtimeSamplesIntoSummaryReadings(SenderGasReceiver.java:266) > > at com.cmts.business.StoreRealtimeIntoDBJob.execut > > e(StoreRealtimeIntoDBJob.java:20) > > at org.quartz.core.JobRunShell.run(JobRunShell.java:216) > > > > Maybe I need to recycle connections or something?? In the Cayenne > > documentation I found this: "Cayenne will also periodically close unused > > database connections if it determines there are too many that are open > and > > idle." Is there some way to hint to Cayenne that you've finished with a > > DataContext's connection pool, something like 'dataContext.close()'? > > > > Here is the exception at a lower level: > > > > Caused by: java.sql.SQLException: Data source rejected establishment of > > connection message from server: "Too many connections" > > at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:1997) > > at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:1906) > > at com.mysql.jdbc.MysqlIO.secureAuth411(MysqlIO.java:2520) > > at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:817) > > at com.mysql.jdbc.Connection.createNewIO(Connection.java:1782) > > at com.mysql.jdbc.Connection.<init>(Connection.java:450) > > at > > > com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:411) > > at > > > org.apache.cayenne.conn.DriverDataSource.getConnection(DriverDataSource.java:156) > > at > > > org.apache.cayenne.conn.PooledConnectionImpl.reconnect(PooledConnectionImpl.java:83) > > at > > > org.apache.cayenne.conn.PooledConnectionImpl.getConnection(PooledConnectionImpl.java:120) > > at > > > org.apache.cayenne.conn.PoolManager.uncheckConnection(PoolManager.java:369) > > at > > org.apache.cayenne.conn.PoolManager.getConnection(PoolManager.java:353) > > at > > org.apache.cayenne.conn.PoolManager.getConnection(PoolManager.java:330) > > at > > > org.apache.cayenne.access.DataNode$TransactionDataSource.getConnection(DataNode.java:364) > > at > > > org.apache.cayenne.conf.NodeDataSource.getConnection(NodeDataSource.java:46) > > at > org.apache.cayenne.dba.AutoAdapter.loadAdapter(AutoAdapter.java:170) > > > > Thanks ~ Chris Murphy > > > > On 11 December 2011 17:57, Robert Zeigler <robert.zeig...@roxanemy.com > >wrote: > > > >> Note that DataContext creation is cheap. What I typically do in > situations > >> like this is to periodically create a new data context that you can > throw > >> away. When it's gone, the associated objects will be gc'ed. Eg: you > could > >> periodically dump the "reading" data context and create a fresh one > after > >> every 1,000 Reading objects or whatever makes sense for your use-case. > If > >> the frequency of readings transactions is low, it probably makes sense > to > >> create a new DataContext, import whatever objects you need into it (via > >> localObject), create your readings, commit, then discard the > DataContext. > >> If the readings are very frequent, then it makes sense to have a > dedicated > >> "readings" DataContext that you can periodically swap out. > >> > >> HTH, > >> > >> Robert > >> > >> On Dec 11, 2011, at 12/1112:51 AM , Chris Murphy (www.strandz.org) > wrote: > >> > >>> I have a server application that continually reads data from sensors. > At > >>> set intervals the data is summarized. This summary data is used to > create > >>> Cayenne data objects of type Reading. A short transaction commits these > >>> Reading objects to the database, after which it is not important that > >> they > >>> are held in memory - they were created only to be stored. After a long > >>> period of time their continual collection results in an 'OutOfMemory' > JVM > >>> condition. > >>> > >>> There are many objects of type Reading for another Cayenne data object > >>> called SubstancePoint. And there's a whole object graph going back from > >>> there. I basically want to keep the whole of the object graph in > memory, > >>> except for these Reading objects. > >>> > >>> Is there a way to 'disappear' data objects from the DataContext? For > that > >>> is what I think would solve my problem. I have tried calling > >>> DataContext.unregisterObjects() post-commit on the Reading data > objects I > >>> want evacuated from memory, but I can see that the leak is still going > >> on. > >>> > >>> Thank you ~ Chris Murphy > >> > >> > >