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 >> >>