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

Reply via email to