Re: security
Hi Carl, To be honest a few ROP projects that I've done used all-or-nothing security (if you are authenticated, you can do anything). Still I've been also thinking about more fine-grained approach. My solution would be to set up a custom 'org.apache.cayenne.DataChannel' decorator, adding custom security checks to 'onQuery()' and 'onSync' methods. In the simplest case, you can have the following security levels: 1. Restricted: only NamedQuery requests are honored, 'onSync' is denied. 2. Read-only: onQuery() allows all but SQLTemplate queries, 'onSync' is denied. 3. Full 4. Custom - check custom rules. Also I haven't yet explored the use of the new 3.0 callbacks as a security mechanism, probably there are some opportunities there: http://cayenne.apache.org/preview/CAYDOC/lifecycle-callbacks.html Andrus On Jan 31, 2007, at 4:23 PM, Carl Mosca wrote: I am wondering about security (user, query, role level). What approaches have been taken by those using ROP for a some time? TIA, -- Carl J. Mosca
Re: New user PK id question
Yes, until 3.0 the logic in Cayenne worked like this: 1. if you don't map PK as an object property, Cayenne will generate the PK. 2. if you do map it, you must provide it yourself. (3.0 relaxed this restriction, but 3.0 is not officially released yet) Do not add the id to the properties exposed by the autogenerated object. Just add the id property to the class extending your autogenerated class and use DataObjectUtils.pkForObject(this); That's my preferred approach too. It is an extended version of #1 above. To expand on Christian's example, here is a full class: public class MyClass extends _MyClass { public int getId() { return DataObjectUtils.intPKForObject(this); } } Andrus On Feb 1, 2007, at 5:00 PM, Christian Mittendorf wrote: Hi! Do not add the id to the properties exposed by the autogenerated object. Just add the id property to the class extending your autogenerated class and use DataObjectUtils.pkForObject(this); to return the pk for the object (may or may not work, I'm not sure how auto_increment is handled by Cayenne in this case). As an alternative, you may want to define another key for accessing the object. In that case you have to make sure that this reference to the object is a) unique and b) that the property is set if the object is newly created: public void setPersistenceState(int state) { super.setPersistenceState(state); // if the object was just created, set initial values if (state == PersistenceState.NEW) { // Set all initial values here Timestamp now = new Timestamp(System.currentTimeMillis()); String digest = + this.hashCode() + now.getTime(); this.setRecordCreated(now); this.setExternalReference(MD5.getDigestAsHex(digest)); } } Make the property external_reference a unique key. This does also secure your application as the user cannot increment the id to see some other objects that he may not be allowed to see, if this kind of security is of interest. Christian Am 01.02.2007 um 15:38 schrieb Frank: Yes, I get this error: Validation failure for stemc.cayenne.Employees.id: id is required. Frank - Original Message - From: Peter Schröder [EMAIL PROTECTED] To: user@cayenne.apache.org Sent: Thursday, February 01, 2007 9:31 AM Subject: AW: New user PK id question did you set the pk-generation properly (database-generated) in the modeler? -Ursprüngliche Nachricht- Von: Frank [mailto:[EMAIL PROTECTED] Gesendet: Donnerstag, 1. Februar 2007 15:23 An: user@cayenne.apache.org Betreff: New user PK id question Hello, I have a mysql table with a PK of id that is auto incremented. The getter is not generated for this pk. I need to use the pk id in a table as a link to allow the user to edit. If I add the pk id to the objEntity, whenever I try to add a record, cayenne complains that the pk id field cannot be blank I assign a value of 1 to the pk id and I can save the record. When I look at the record just added, the pk id show the correct value assigned by mysql(not 1) What am I doing wrong? I need theh id to add to the link. Thanks Frank
Re: security
On Jan 31, 2007, at 7:50 PM, Carl Mosca wrote: Is there a published timetable for 3.0? We are preparing the first milestone (alpha) of 3.0. It should go out pretty soon. Otherwise - no, there's no timetable (standard open source disclaimer about volunteer labour goes here), but there is a good idea of the scope. BTW, I am using trunk builds of 3.0 in production on a very active site since September. Runs rather smoothly, but of course I am responsible for fixing references to the new evolving API with every build upgrade. Andrus
Re: can't find procedure without a parameter on Postgres
Bryan, this is a bug, I can confirm that: https://issues.apache.org/cayenne/browse/CAY-750 I fixed it on trunk (Cayenne 3.0). Will apply it to 2.0 and 1.2 branches shortly. Andrus On Feb 6, 2007, at 1:35 PM, Bryan Lewis wrote: I had this code working on an Oracle8 database: ProcedureQuery procQuery = new ProcedureQuery(proc_eu_update_begin); dc.performQuery(procQuery); The procedure is only a few sql statements to create a temporary table and takes no parameters. When I ported to Postgres 8.2, Cayenne says it can't find the procedure. The log shows: {call proc_eu_update_begin} org.postgresql.util.PSQLException: ERROR: relation proc_eu_update_begin does not exist I could execute the procedure manually with select proc_eu_update_begin(). Note that the empty parentheses were required. I had other working procedures so I suspected it was the absence of parameters causing the problem. Adding a dummy parameter made things work: {call proc_eu_update_begin(?)} [bind: 'xx'] So I have a work-around, but... maybe Cayenne could generate a call that Postgres would handle better, something like the empty parentheses in the manual command. P.S. The definition of the procedure (now a function in Postgres) looks like: CREATE OR REPLACE function proc_eu_update_begin() RETURNS void AS ...
Re: Version 2 doc linking
Hi Ari, On Feb 9, 2007, at 8:29 PM, Aristedes Maniatis wrote: Just a heads up that I've finished linking together all the children in the version 2 docs. It is a little time consuming, so I don't think I'll do version 1.2, since the pages are identical to version 2.0 almost everywhere. Thanks a lot for this work!! I think we are ok with just 2.0 and 3.0 docs being fully linked on Wiki. For the future, perhaps we should think of ways to not have to maintain multiple versions of documentation. Documentation branches are a necessary evil, just like code branches (e.g. similarly we often have to apply identical bug fixes to 1.2, 2.0, and 3.0 at the same time), and in fact they correspond to the *maintained* code branches. Going forward we can reduce the number of versions maintained at any given moment to just two (1.2 vs. 2.0 vs. 3.0 is a unique situation caused by us joining Apache). I.e. when 3.0 becomes STABLE and 4.0 becomes development release, we will pull 1.2 and 2.0 doc sets from the site entirely. Perhaps a tag we attach to the page or part of a page which indicates the version in which that feature was introduced. This is a good idea to do for the current releases. At the same time including the docs for the not-yet-existing features with an old release can be confusing. Even worse, some framework concepts change over time, with old concepts/API being removed from the docs, so stable release users can get the wrong picture. Andrus
Re: cayenne with jetty6
Hi Peter, [I stripped message that you quote, since it has no relation to the topic you started.] perhaps someone could add the docs http://cayenne.apache.org/doc/ tutorial-webapp.html with some usefull information about jetty6. I don't think this is Jetty6-related at all. even with including all dependencies to the jetty-plugin i failed to use the jndi-backup-mechanism, wich i use successfully witch the jetty-launcher. Anything is printed on the console during startup that can shed the light on the problem? A few things can go wrong: * cayenne-modeler.jar and hsqldb.jar can be missing from dependencies (although your message implies they are not) * Sometimes local preferences database gets corrupted (it is a long- standing issue that requires some serious modeler rework, switching from HSQLDB to Derby or something else more reliable). The workaround is to delete the preferences directory ($HOME/.cayenne/prefs), and recreate the data sources from scratch. Andrus On Feb 13, 2007, at 6:10 AM, Peter Schröder wrote: hi there, i was trying to run the cayenne-filter with jetty6-maven-plugin, but it did not work out for me... even with including all dependencies to the jetty-plugin i failed to use the jndi-backup-mechanism, wich i use successfully witch the jetty-launcher. perhaps someone could add the docs http://cayenne.apache.org/doc/ tutorial-webapp.html with some usefull information about jetty6. kind regards, peter
Re: cayenne with jetty6
On Feb 13, 2007, at 10:48 AM, Andrus Adamchik wrote: perhaps someone could add the docs http://cayenne.apache.org/doc/ tutorial-webapp.html with some usefull information about jetty6. I don't think this is Jetty6-related at all. Although providing a sample Jetty JNDI DataSource configuration that is NOT using Cayenne preferences is probably a good idea. A similar configuration for Tomcat is available here: http://cayenne.apache.org/doc/using-jndi.html I don't have a sample handy. Anyone can fill it in? Andrus
Re: How do you deal with AS400 schemas
Frank, I put a patched version of Cayenne 1.2 here: http://people.apache.org/~aadamchik/patched/cayenne-1.2-dev- win-02132007.zip Could you please give it a try and report how it worked? If it does, I'll commit the fix, and it will be available officially in the future versions of Cayenne. Thanks Andrus On Feb 13, 2007, at 11:51 AM, Frank wrote: Hi Andrus, I have submitted this as a open a bug report. Frank - Original Message - From: Andrus Adamchik [EMAIL PROTECTED] To: user@cayenne.apache.org Sent: Tuesday, February 13, 2007 11:40 AM Subject: Re: How do you deal with AS400 schemas Hmm... I'd say this is a bug in Cayenne class generator. We need to replace non-java chars with something more appropriate. Could you please open a bug report: https://issues.apache.org/cayenne/ Thanks Andrus On Feb 13, 2007, at 11:37 AM, Frank wrote: Hello, Cayenne is generating code that has # because our AS400 database tables use these as field names. Severity and Description Path Resource Location Creation Time Id Syntax error on token Invalid Character, , expected jcdsurvey/ src/ stemc/cayenne/as400/auto _Bsypemp.java line 199 117138437 13668 public static final String EMEMP#_PK_COLUMN = EMEMP#; public static final String EMHSP#_PK_COLUMN = EMHSP#; Should I just use a Raw Sql? I had to remove the # from the objEntity as Cayenne complained. Thanks Frank
Re: Cayenne and Daylight Savings Time Change?
I second that - Cayenne relies on the JDK, JDBC driver and the database to do the right thing. Those three can of course give you lots of headache... http://www.objectstyle.org/cayenne/lists/cayenne-user/2006/12/0107.html Andrus On Feb 15, 2007, at 11:14 PM, Michael Gentry wrote: I'm pretty certain Cayenne only cares about and relies upon the JDK, but I'm not prepared to sign a legal document to that effect. :-) If I get really bored tomorrow, I can play with my clock. :-) /dev/mrg On 2/15/07, Dov Rosenberg [EMAIL PROTECTED] wrote: Is Cayenne affected by the upcoming DST change going into effect in March? Or will a simple JDK upgrade fix the issue? -- Dov Rosenberg Inquira Knowledge Management Experts http://www.inquira.com
Re: AW: Getting primary key of object after save
That's an old piece of docs. It still works though, but it is much easier to use DataObjectUtils: http://cayenne.apache.org/doc12/dataobjectutils.html Andrus On Feb 26, 2007, at 10:33 AM, Peter Schröder wrote: hi sam, i think that you can get the pk through the snapshot of the object after it has been committed to the context: http://cayenne.apache.org/doc12/accessing-pk-and-fk-values.html -Ursprüngliche Nachricht- Von: Sam Shah [mailto:[EMAIL PROTECTED] Gesendet: Montag, 26. Februar 2007 06:57 An: user@cayenne.apache.org Betreff: Getting primary key of object after save Is there any way to get the primary key of the object immediately after you save it in cayenne on the client side in 3 tier. We need this to refetch the object after it has been saved
Re: security - revisited
Well, think of it this way - Cayenne ROP provides the data model and a way to add hooks to the runtime. These are the two pieces that can be used to implement a custom security mechanism. None of the security features are built in Cayenne, but it allows adding them. So answering Carl's question, I don't think you'll find anything prepackaged, but this doesn't mean you can't build it. Andrus On Feb 27, 2007, at 4:23 PM, Michael Gentry wrote: These pages may help you: http://cayenne.apache.org/doc/remote-object-persistence-security.html http://cayenne.apache.org/doc/remote-object-persistence- limitations.html In a nutshell, I think you get basic security at the moment, but nothing too advanced (such as role-based, etc.). Hope that helps some. /dev/mrg On 2/27/07, Carl Mosca [EMAIL PROTECTED] wrote: Yes, I am looking for user/role security for Cayenne's Remote Object Persistence. On 2/27/07, Michael Gentry [EMAIL PROTECTED] wrote: I hadn't heard of JOSSO before. Are you looking for user/role security for Cayenne's Remote Object Persistence features or something different? /dev/mrg On 2/24/07, Carl Mosca [EMAIL PROTECTED] wrote: I asked about security a little while back and I came up short of finding a solution that will allow me to use cayenne (I want user/role security on the server). I see where the josso project http://www.josso.org has released 1.5. I am wondering if anyone has looked into utilizing josso with cayenne. -- Carl J. Mosca -- Carl J. Mosca
Re: PK Generation Strategy: Database-Generated doesn't work
Hi Manuel, Per http://cayenne.apache.org/doc/generated-columns.html DB-generated pk depends on support of this feature by the underlying JDBC driver. Our testing showed that it only works in MySQL, Derby and SQLServer. For HSQLDB this feature is turned off (I just tried it on HSQL 1.8.0.4 - the driver support isn't there), so Cayenne behavior is to fail over to the AUTO_PK_SUPPORT lookup table. As auto-increment feature makes it to other JDBC drivers (including HSQL), we'll turn it on in Cayenne accordingly. Andrus On Mar 1, 2007, at 11:53 AM, Manuel Thiemann wrote: Hello, I just started playing a bit with Cayenne to find out how things work. Therefore I created a database (HSQL) with a single table and in the CayenneModeler set Primary Key Generation Strategy to Database-Generated and the Auto Increment field to ID (INTEGER) which is the column defined as Primary Key at the attributes tab. However when I try to insert a row in my test program I get an exception because I don't have an AUTO_PK_SUPPORT table in my database. But as far as I understand I don't not need this table if primary keys are generated by the database itself. Is there something else I have to configure to not need to have that table (It works fine if I create that table via Generate Database Schema but I would prefer to have the database doing that primary key stuff. Or is there any reason that it is better to use AUTO_PK_SUPPORT)? Thanx for help. Manuel
Re: expression to find out null relationship
On Mar 3, 2007, at 7:47 AM, Marcin Skladaniec wrote: - [v.3.0-SNAPSHOT Jan 19 2007 05:26:38] [v.3.0-SNAPSHOT Jan 19 2007 05:26:38] Exception processing message org.apache.cayenne.remote.QueryMessage. Root cause: [v.3.0-SNAPSHOT Jan 19 2007 05:26:38] Null value for 'id'. Marcin, can you print the actual DataRow before converting it to object - this may give you hints as to why the exception is thrown. Mike already mentioned that - the column naming in the response may be the key. Andrus
Re: Importing an EOModel with single table inheritance
Hi Simon, Looking at the code, it fails not because of single-table inheritance, but still I think this is a bug in Cayenne. Could you please open a bug report and attach your EOModel to it - I'd like to investigate more. http://issues.apache.org/cayenne/ Thanks Andrus On Mar 4, 2007, at 8:10 PM, Simon wrote: Hi - I'm trying to import an EOModel with cayenne Modeler and i'm getting the exception pasted below. ABSTRACT_FOP is a table that has a super entity and 2 sub entities mapped to it. Is it not possible to import an EOModel that has single-table inheritance ? Thanks, Simon CayenneModeler Info Version: 2.0.2 Build Date: January 14 2007 Exception: = org.apache.cayenne.CayenneRuntimeException: [v.2.0.2 January 14 2007] One and only one entity should be mapped to ABSTRACT_FOP. Instead found : 3 at org.apache.cayenne.wocompat.EOModelProcessor.makeFlatRelationships (EOModelProcessor.java:661) at org.apache.cayenne.wocompat.EOModelProcessor.loadEOModel (EOModelProcessor.java:171) at org.apache.cayenne.wocompat.EOModelProcessor.loadEOModel (EOModelProcessor.java:117) at org.apache.cayenne.modeler.action.ImportEOModelAction.importEOModel (ImportEOModelAction.java:125) at org.apache.cayenne.modeler.action.ImportEOModelAction.performAction (ImportEOModelAction.java:89) at org.apache.cayenne.modeler.util.CayenneAction.actionPerformed (CayenneAction.java:163) at javax.swing.AbstractButton.fireActionPerformed (AbstractButton.java:1882) at javax.swing.AbstractButton$Handler.actionPerformed (AbstractButton.java:2202) at javax.swing.DefaultButtonModel.fireActionPerformed (DefaultButtonModel.java:420) at javax.swing.DefaultButtonModel.setPressed (DefaultButtonModel.java:258) at javax.swing.AbstractButton.doClick(AbstractButton.java:334) at apple.laf.ScreenMenuItem.actionPerformed(ScreenMenuItem.java:104) at java.awt.MenuItem.processActionEvent(MenuItem.java:597) at java.awt.MenuItem.processEvent(MenuItem.java:556) at java.awt.MenuComponent.dispatchEventImpl(MenuComponent.java:298) at java.awt.MenuComponent.dispatchEvent(MenuComponent.java:286) at java.awt.EventQueue.dispatchEvent(EventQueue.java:466) at java.awt.EventDispatchThread.pumpOneEventForHierarchy (EventDispatchThread.java:269) at java.awt.EventDispatchThread.pumpEventsForHierarchy (EventDispatchThread.java:190) at java.awt.EventDispatchThread.pumpEvents (EventDispatchThread.java:184) at java.awt.EventDispatchThread.pumpEvents (EventDispatchThread.java:176) at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)
Re: Calling commitChanges() from inside postPersist()
Sam, this could be a bug in the lifecycle (I haven't looked, I am in a time crunch now). Could you open a bug report documenting your findings. Thanks Andrus On Mar 6, 2007, at 2:59 AM, Sam Shah wrote: Hi, in a postPersist() callback method I'm trying to get a local copy of the committed object into a new context. The object is already in the database, I've checked the raw data but cayenne is returning an object with a temporary id. The error I'm getting is - org.apache.cayenne.CayenneRuntimeException: [v.3.0-SNAPSHOT Jan 19 2007 05:26:38] Exception processing message org.apache.cayenne.remote.SyncMessage. Root cause: [v.3.0-SNAPSHOT Jan 19 2007 05:26:38] Error resolving fault for ObjectId: ObjectId:PaymentIn, TEMP:04BBD0643E95 and state (hollow). Possible cause - matching row is missing from the database. What am I doing wrong?
Re: Cayenne Classic vs. Cayenne JPA
(This thread has been duplicated on the dev list, see Ari's reply [1]. Also Randy doesn't seem to be a user list subscriber, so I am cc'ying to him) - Are there Cayenne functionalities available to Classic, but not JPA version? Both will be using the same stack. The principal difference is the level of access to that stack. JPA hides it completely. Cayenne allows stack access from Java code. Actually Cayenne JPA will have a non-standard way to expose the stack to the apps. Also I hope we'll provide access to most classic features in a JPA-compliant manner - via provider extensions (see below). - Could JPA modelling tools (e.g. Eclipse Dali, etc.) be used in place of Cayenne Modeller? Generally yes, as JPA mapping is presumably provider-agnostic. One issue with third party tools (I haven't looked at any yet, so that's purely my speculation), is that there won't be UI support for provider-specific features. E.g. Cayenne provider allows to map a non- JTA DataSource, kind of like Cayenne Classic does, same for SQLTemplate and SelectQuery. You'll be able to map these extensions via provider properties, but you'll have to know the right property names. Andrus [1] http://objectstyle.org/cayenne/lists/cayenne-devel/2007/03/0022.html On Mar 6, 2007, at 9:35 PM, Randy Leonard wrote: I've read some earlier threads on Cayenne 3.0, and have a few questions: - Is Cayenne 3.0 Classic significantly different from Cayenne 2.x? - Could JPA modelling tools (e.g. Eclipse Dali, etc.) be used in place of Cayenne Modeller? - Are there Cayenne functionalities available to Classic, but not JPA version? Also, I posted a thread last July concerning multiple models in one application: http://mail-archives.apache.org/mod_mbox/cayenne-dev/200607.mbox/% [EMAIL PROTECTED] Two questions on this: - Curious if Cayenne 3 would support this? - If not, would the custom solution described still apply to Cayenne 3? Thanks, Randy
Re: Cayenne Classic vs. Cayenne JPA
On Mar 7, 2007, at 3:04 PM, Randy Leonard wrote: But note JPA tools likely store all model data in annotations Not necessarily. JPA supports any combination of XML and annotations. It is up to the user how to do the mapping. Andrus
Re: Cayenne Classic vs. Cayenne JPA
On Mar 7, 2007, at 3:04 PM, Randy Leonard wrote: I would hope the industry provides vanilla JPA modelling tools, with the possibilty of provider-specific tool-extensions I would hope so. to add provider-specific annotations. JPA deals with some of that already: * Query extensions can be passed using JPA annotation QueryHint. * Provider properties can be passed in the code using javax.persistence.Persistence.createEntityManagerFactory(String, Map). Andrus
Re: Improvement ? code generation (templates)
Hi Jerome, Could you give specific examples of the code you want to see generated? From your message I don't quite understand why we need to change the *default* template? Cheers, Andrus On Mar 7, 2007, at 5:50 PM, jerome moliere wrote: Hi all, rather than using custom templates could we imagine to change current templates while adding something like the Commons Lang EqualsBuilder/HashCodeBuilder/ToStringBuilder in order to get self explanatory logs and quick sorts on Java Collections filled with Cayenne objects ? It may also avoid some clever bugs in client code (not in Cayenne).. If help required I may find some time to do that... Regards Jerome -- Jerome Moliere - Mentor/J http://romjethoughts.blogspot.com/ auteur Eyrolles
Re: Importing an EOModel with single table inheritance
Fixed - check out the snapshot build of 2.0 that I posted here: http://people.apache.org/~aadamchik/nightly/03092007/ Andrus On Mar 5, 2007, at 2:10 PM, Simon McLean wrote: Hi Andrus - It's on there: CAY-764 Simon On 5 Mar 2007, at 11:15, Andrus Adamchik wrote: Hi Simon, Looking at the code, it fails not because of single-table inheritance, but still I think this is a bug in Cayenne. Could you please open a bug report and attach your EOModel to it - I'd like to investigate more. http://issues.apache.org/cayenne/ Thanks Andrus On Mar 4, 2007, at 8:10 PM, Simon wrote: Hi - I'm trying to import an EOModel with cayenne Modeler and i'm getting the exception pasted below. ABSTRACT_FOP is a table that has a super entity and 2 sub entities mapped to it. Is it not possible to import an EOModel that has single-table inheritance ? Thanks, Simon CayenneModeler Info Version: 2.0.2 Build Date: January 14 2007 Exception: = org.apache.cayenne.CayenneRuntimeException: [v.2.0.2 January 14 2007] One and only one entity should be mapped to ABSTRACT_FOP. Instead found : 3 at org.apache.cayenne.wocompat.EOModelProcessor.makeFlatRelationships (EOModelProcessor.java:661) at org.apache.cayenne.wocompat.EOModelProcessor.loadEOModel (EOModelProcessor.java:171) at org.apache.cayenne.wocompat.EOModelProcessor.loadEOModel (EOModelProcessor.java:117) at org.apache.cayenne.modeler.action.ImportEOModelAction.importEOModel( ImportEOModelAction.java:125) at org.apache.cayenne.modeler.action.ImportEOModelAction.performAction( ImportEOModelAction.java:89) at org.apache.cayenne.modeler.util.CayenneAction.actionPerformed (CayenneAction.java:163) at javax.swing.AbstractButton.fireActionPerformed (AbstractButton.java:1882) at javax.swing.AbstractButton$Handler.actionPerformed (AbstractButton.java:2202) at javax.swing.DefaultButtonModel.fireActionPerformed (DefaultButtonModel.java:420) at javax.swing.DefaultButtonModel.setPressed (DefaultButtonModel.java:258) at javax.swing.AbstractButton.doClick(AbstractButton.java:334) at apple.laf.ScreenMenuItem.actionPerformed(ScreenMenuItem.java: 104) at java.awt.MenuItem.processActionEvent(MenuItem.java:597) at java.awt.MenuItem.processEvent(MenuItem.java:556) at java.awt.MenuComponent.dispatchEventImpl(MenuComponent.java:298) at java.awt.MenuComponent.dispatchEvent(MenuComponent.java:286) at java.awt.EventQueue.dispatchEvent(EventQueue.java:466) at java.awt.EventDispatchThread.pumpOneEventForHierarchy (EventDispatchThread.java:269) at java.awt.EventDispatchThread.pumpEventsForHierarchy (EventDispatchThread.java:190) at java.awt.EventDispatchThread.pumpEvents (EventDispatchThread.java:184) at java.awt.EventDispatchThread.pumpEvents (EventDispatchThread.java:176) at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)
Re: lifecycle callbacks and ROP
On Mar 10, 2007, at 2:15 AM, Aristedes Maniatis wrote: On 10/03/2007, at 10:13 AM, Tore Halset wrote: Hello. I am a lifecycle callbacks newbie trying to understand http:// cwiki.apache.org/CAYDOC/lifecycle-callbacks.html in a ROP context. Can the callback methods be defined in the client PersistentObject or only in the server CayenneDataObject? I believe that they will only operate on the server side. At least that's how we've been able to use them. True. Let's put it this way - no decision has been made on the client callbacks yet. Can a ROP client perform non-lifecycle callbacks on the server? If not, are there any other standard way for a ROP client to call a method on the server not related to the persistence lifecycle? We use Jetty as the transport for Hessian between client/server ROP. So we can define special servlet calls as we need in order to perform code on the server or return values. For instance, when a client logs into the server we wanted the server to maintain a list of client sessions. So, because we aren't committing an object through Cayenne to the server we couldn't use a lifecycle event and we wrote a special servlet call which is used instead. IIRC, Tore mentioned this before, that it would be nice to define some arbitrary RPC-like calls to the server-side peer objects, kind of like EOF does. So that you can do clientObject.doX() and it will proxy the call to the serverObject.doX(). I'd say this can be a new feature in 3.0, and it would be nice if somebody volunteers to do it. Andrus
Re: Cayenne v3.x and OSX
On Mar 12, 2007, at 2:29 AM, Randy Leonard wrote: I've downloaded the Cayenne 3.0 snapshot as referenced from the cayenne web site, and also built the latest code found in svn (including the 'mvn -P mac install' command), but still don't see a CayenneModeler application instance for OSX. - Am I missing something? - Is there a command to build an OSX .app? It is there, it is just hard to find: cayenne/modeler/cayenne-modeler-mac/target/modeler/CayenneModeler.app/ - Is it possible for the snapshot builds to include an OSX distribution? We don't have an automated procedure yet. Theoretically yes. - Or is the Cayenne 2.x modeler valid for Cayenne 3.x? IIRC yes, but this is about to change. Andrus
Re: Wanted: performance tuning hints
What I found was that in Insert operations, it is best to use Cayenne data objects (as opposed to raw SQL queries) Cayenne adapters for Oracle, Derby, FrontBase, Postgres and SQLServer use JDBC-level batching that sometimes speeds things up significantly. SQLTemplate doesn't use JDBC batching. There are other possible reasons too, such as pk caching. while for Update and Delete the case is the opposite. Here you are not comparing apples to apples. A single update (or delete) query that matches some condition will certainly be faster than a series of update queries (or a batched update query for multiple objects), but the two are different logical operations. I guess you should choose which one to use depending on circumstances. Andrus On Mar 12, 2007, at 4:40 PM, Török Péter wrote: Sorry for the previous mail, I inadvertently sent it half-ready :-( Hello, I made a small performance test comparing different Cayenne solutions with JDBC solutions. What I found was that in Insert operations, it is best to use Cayenne data objects (as opposed to raw SQL queries), while for Update and Delete the case is the opposite. I guess this may not surprise you :-) So for Insert, this worked best for me: public void insertRecords(int count) { Date date = new Date(); for (int index = 1; index = count; index++) { TestData testData = (TestData) context.newObject (TestData.class); testData.setName(nextName()); testData.setDescription(nextDescription()); testData.setCount(new Integer(count - index)); testData.setCreated(date); if (index % 1000 == 0) { context.commitChanges(); } } context.commitChanges(); } while for Update and Delete, something like this: public void updateRecords(int lowerLimit, int upperLimit) { final SQLTemplate query = new SQLTemplate(TestData.class, update test_data set description = '$desc' where count $lower and count $upper); Map params = new HashMap(); params.put(desc, nextDescription()); params.put(lower, new Integer(lowerLimit)); params.put(upper, new Integer(upperLimit)); context.performNonSelectingQuery(query.createQuery(params)); } Any hints on how to make these methods faster? Thanks in advance, Péter
Re: Cayenne v3.x and OSX
On Mar 13, 2007, at 1:35 AM, Randy Leonard wrote: svn co https://svn.apache.org/repos/asf/cayenne/main/trunk/ cayenne cd cayenne mvn install mvn -P mac install cd cayenne/assembly ./build-mac.sh Skip the last step (not sure why it didn't work... every day Maven brings new surprises :-/, but the last step is not relevant). You can also skip the unit tests, so step #3 would look like this: mvn -Dmaven.test.skip=true -P mac install After this, the Mac Modeler should be under modeler/cayenne-modeler- mac/target/modeler/CayenneModeler.app/ . This is relative to the root of Cayenne checkout). Andrus
Re: lifecycle callbacks not always fired
Is it an update that resulted from another callback by any chance? Andrus On Mar 14, 2007, at 8:51 AM, Lachlan Deck wrote: Hi Andrus (in particular), (Note: 3 tier Cayenne) we're finding that the postUpdate method is not being called if an operation is commenced on the server-side (like a data upgrade service). However, if the operation is triggered from the client- side then it is called. Any ideas? Thanks. with regards, -- Lachlan Deck
Re: Does SelectQuery.addCustomDbAttribute[s] work?
On Mar 14, 2007, at 8:46 AM, Lachlan Deck wrote: Hi Andrus, On 14/03/2007, at 4:53 AM, Andrus Adamchik wrote: IIRC no work has been done since the issue was opened. So it only works for the DbAttributes of the root table. From the first glance it shouldn't be too hard to add what Tore requested (some tweaking of SelectTranslator.appendCustomColumns() is needed). I guess nobody was motivated enough to do it :-) Would it end up (internally perhaps) being an abstraction for SQLTemplate? Probably not, as SelectQuery is still a higher level abstraction. Andrus
Re: lifecycle callbacks not always fired
One last try at guessing it. On the server you have to do some magic to enable callbacks (hopefully eventually this will be more transparent). See Enabling Callbacks chapter at the bottom of this page: http://cayenne.apache.org/doc/lifecycle-callbacks.html if this doesn't help, please file a bug with code samples. Andrus On Mar 14, 2007, at 2:40 PM, Marcin Skladaniec wrote: We are upgrading the data, and we are just touching objects (setting new modifiedOn value) to make them run the postUpdate(). All happens on server. All objects are committed together. New modifiedOn value is saved to db, but postUpdate never runs. Regards Marcin On 14/03/2007, at 8:59 PM, Andrus Adamchik wrote: Is it an update that resulted from another callback by any chance? Andrus On Mar 14, 2007, at 8:51 AM, Lachlan Deck wrote: Hi Andrus (in particular), (Note: 3 tier Cayenne) we're finding that the postUpdate method is not being called if an operation is commenced on the server-side (like a data upgrade service). However, if the operation is triggered from the client- side then it is called. Any ideas? Thanks. with regards, -- Lachlan Deck Marcin
Re: Cayenne -- Apache re-deploy problem -- NullPointerException
Hi Marc, I'm using Cayenne (2.0.2) with the apache web server (5.5.20) and I'm facing to the following problem. You mean Tomcat, not apache web server (which would be httpd)? When apache does an automatic deploy, all objects are serialized / deserialized without any error. But after that, when the code accesses a cayenne persistent object (member variable of a jsf backing bean), the following problem occurs: Does it also happen on clean redeploy? I.e. you shut down Tomcat, replace the war, and start Tomcat. Or is this a symptom of hot deploy on the running server? Andrus On Mar 14, 2007, at 2:21 PM, Marc Gabriel-Willem wrote: Hi, I'm using Cayenne (2.0.2) with the apache web server (5.5.20) and I'm facing to the following problem. When apache does an automatic deploy, all objects are serialized / deserialized without any error. But after that, when the code accesses a cayenne persistent object (member variable of a jsf backing bean), the following problem occurs: Caused by: java.lang.NullPointerException at org.apache.cayenne.access.DataContextQueryAction.interceptPaginatedQue ry (DataContextQueryAction.java:91) at org.apache.cayenne.access.DataContextQueryAction.execute (DataContextQuer yAction.java:50) at org.apache.cayenne.access.DataContext.onQuery(DataContext.java:1387) at org.apache.cayenne.access.DataContext.performQuery(DataContext.java: 1376 ) at org.apache.cayenne.access.ToManyList.resolvedObjectList (ToManyList.java: 307) at org.apache.cayenne.access.ToManyList.size(ToManyList.java:260) at com.sideinternational.web.profiling.group.GroupEditor.save (GroupEditor.j ava:246) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.jav a:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessor Impl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at org.apache.myfaces.el.MethodBindingImpl.invoke (MethodBindingImpl.java:13 2) For information, the following code throws that exception (the call to the size() method) : List itemsToRemove = m_editableGroup.getGroupContentArray(); for (int i=0; i itemsToRemove.size(); i++) ... Note: Child data context and ObjectEntities are stored in a serializable jsf backing bean. Thank you for your help. Marc Gabriel
Re: [OT] Maven in Cayenne
On Mar 15, 2007, at 12:59 PM, jerome moliere wrote: In fact I just want to warn a big problem (like the cocoon members wrote in their build notes) it seems that Maven has some strange behaviours, very dispappointing when using continuus integration you may see several alerts (by mail) then one report telling that everything is ok..you changed nothing in your code and a test stops failing... Problem is clearly not about philosophy, because the idea is very interesting, convention over configuration is an evident idea...Everybody prefers convention over tons from xml code isn't it ? Right - to summarize my main complaint about Maven in two words, those would be unstable and unpredictable. It was also obscure initially, but now after a year of poking through the sources and writing a few plugins, it is mostly the first two. Andrus
Re: svn checkout error
IIRC there were some problems with long paths and Subversion on Windows. I had to check out the code straight to C:\cayenne to shorten the path. Try it - if it works, we'll put a note in the developer guide. Andrus On Mar 14, 2007, at 10:36 PM, Borut Bolčina wrote: Hi all, checking out with svn co https://svn.apache.org/repos/asf/cayenne/main/trunk/ cayenne gives me: ... Acayenne\docs\doc\src\main\resources\doc\Documentation\Remote Object Persistence Guide\Remote Object Persi stence Quick Start\Remote Object Persistence Tutorial Client Project svn: Your .svn/tmp directory may be missing or corrupt; run 'svn cleanup' and try again svn: Can't open file 'cayenne\docs\doc\src\main\resources\doc\Documentation\Remote Object Persistence Guide\Re mote Object Persistence Quick Start\Remote Object Persistence Tutorial Client Project\.svn\tmp\text-base\clien t-class-generator.jpg.svn-base': The system cannot find the path specified. -Borut
Re: AW: AW: AW: possible bug / memory leak in DispatchQueue and EventManager?
I didn't. I'd appreciate if you could do that, as you have all the details. http://issues.apache.org/cayenne/ Thanks Andrus On Mar 15, 2007, at 3:45 PM, Ayhan Kondoz wrote: Hi Andrus, did you log this as a bug? And do you need anything else from me? At the moment I added a cronjob to restart the WebService every night which prevents this bug from causing any harm but I really would like to fix it properly and remove the cronjob. Thanx Ayhan Kondoz -Ursprüngliche Nachricht- Von: Andrus Adamchik [mailto:[EMAIL PROTECTED] Gesendet: Mittwoch, 21. Februar 2007 15:20 An: user@cayenne.apache.org Betreff: Re: AW: AW: possible bug / memory leak in DispatchQueue and EventManager? 30 is good. If you had a retained DataContext somewhere you'd get the same number as the number of stuck invocations. 1 million of Invocations is bad. I guess this needs to be logged as a possible bug to investigate, with as many details as possible on the JVM version, etc. Andrus On Feb 21, 2007, at 4:07 PM, Ayhan Kondoz wrote: Yes seems live there are DataContext instances. http://img73.imageshack.us/img73/3068/memta6.jpg I started the GC a few times before I took this screenshot. As you can see there are still 30 DataContext instances. No idea why thought... -Ursprüngliche Nachricht- Von: Andrus Adamchik [mailto:[EMAIL PROTECTED] Gesendet: Mittwoch, 21. Februar 2007 14:49 An: user@cayenne.apache.org Betreff: Re: AW: possible bug / memory leak in DispatchQueue and EventManager? Do you see DataContext instances in the memory profile? I wonder how many of those do you have, as those are the only Cayenne objects that have hard reference to the listeners. Andrus On Feb 21, 2007, at 3:37 PM, Ayhan Kondoz wrote: Hi, the JVM has 1 GB of memory and i already tried to run the GC manually but it doesn't make a difference. I can start the GC from the profiler tool but the number of instances does not change. I guess that there are some other references to this objects so that the weak ref. does not expire. And there are no EventManager exception in the log files. ayhan -Ursprüngliche Nachricht- Von: Andrus Adamchik [mailto:[EMAIL PROTECTED] Gesendet: Mittwoch, 21. Februar 2007 14:17 An: user@cayenne.apache.org Betreff: Re: possible bug / memory leak in DispatchQueue and EventManager? Seems like your assessment of the EventManager leaking is correct. Now the cause is not that clear. A shot in the dark - this is due to a combination of lots of spare memory in JVM (so weak references are not collected fast enough) and slow custom 'equals' and 'hashCode' methods in invocation. How much heap size do you have in your server? Also can you try to add a request filter that would do 'System.gc()' on every few thousands requests, and see if it makes any difference. Also - do you see any EventManager exceptions in the logs? Andrus On Feb 21, 2007, at 10:55 AM, Ayhan Kondoz wrote: Hi, i think i found a possible bug / memory leak within the DispatchQueue and EventManager. First a little bit about my setup: I have 3 servers. Each server runs an axis service. The service uses cayenne 1.2.1 to connect to a database. It reads customer and account information from the DB etc.. The servers are using cayenne's shared caching with javagroups as the messaging service so that changes made from one server are dispatched to the other servers. The avarage connections per second is somewhere around 4-5. However I have a very strange problem with this setup so I startet to search for the reason. The problem is that with nearly constant and unchanging usage the load of each server increases over time. To further test this I created a test server with a similar setup. There I created a test program that creates totally constant usage. But even with the unchanging usage the load of the server is increasing until the cpu load is so high that the requests can not be processed anymore. I installed a java profiler to trying to pinpoint the location of this error and this is what I found out. I let the server run for 24 hours and then stopped the program which creates the test usage. But even while the server was idle there where still a lot of instances in the java heap after the GC run. http://img206.imageshack.us/img206/9769/memorysy5.jpg Please note the HashMap, WeakReference and Invocation counts. I pressume that the $ObjectProvider_*** is cayenne aswell but I am not sure. Now the following image shows the cpu profile with incoming connections. http://img339.imageshack.us/img339/2441/cpuci0.jpg As you can see 58% of the cpu time is used within HashSet.add(). So when I consider the two facts i think that there might be a possible problem with the EventManager. The first table tells us that there are over 1 million instances of HashSet's and cayenne Invocations. So it seems like the set's within the DispatchQueue are not recycled
Re: lifecycle callbacks not always fired
Yeah, migrating to ObjectContext is now a prerequisite. Won't comment on the specifics now, but the design direction with this was to minimize the number of methods in the ObjectContext interface, so a few DataContext methods didn't make it there. I guess we need to pull to DataObjectUtils any remaining derived DataContext methods that can be executed on a generic ObjectContext. Andrus On Mar 16, 2007, at 2:27 AM, Lachlan Deck wrote: Hello again, On 15/03/2007, at 12:15 AM, Andrus Adamchik wrote: One last try at guessing it. On the server you have to do some magic to enable callbacks (hopefully eventually this will be more transparent). See Enabling Callbacks chapter at the bottom of this page: http://cayenne.apache.org/doc/lifecycle-callbacks.html if this doesn't help, please file a bug with code samples. You were right. I'd not read far enough down the page. It is somewhat convoluted to implement I must say. I'm now subclassing ObjectContextCallbackInterceptor to add a couple of methods to it (e.g., like hasChanges() etc from DataContext). There's one other problem that this now imposes: previously using a DataContext we could do: Object someInstance = dc.objectFromDataRow( entityClass, someDataRow, refreshes ); Would this now be the best solution? public class ObjectContext extends ObjectContextCallbackInterceptor { private DataContext _dataContext; ... public DataObject objectFromDataRow( Class entityClass, DataRow paymentRow, boolean refresh ) { DataObject anObject; anObject = _dataContext.objectFromDataRow( entityClass, paymentRow, refresh ); if ( anObject != null ) return ( DataObject )localObject( anObject.getObjectId(), anObject ); return null; } } Otherwise it seems to return an object that seems to be in the wrong context so far as addToOneRelationship etc is concerned... Be nice if ObjectContext, DataContext et al were better unified. Or that DataObjectUtils could return an object for a DataRow to abstract all this. with regards, -- Lachlan Deck
Re: Running a query over multiple Databases?
Doing a join across DB's generally doesn't work (although it may *appear* to work in simpler cases of matching of FK), as it will require Cayenne to do in memory cartesian product processing. So you'll have to do it manually. (actually sounds like an interesting improvement ... although probably low priority to me at least) Andrus On Mar 16, 2007, at 5:26 PM, Christian Mittendorf wrote: Hi! I've found the mutiple database example on cayennes homepage: http://cwiki.apache.org/CAY/multiple-databases-example.html That example is a pretty good resemblance of our current problem. What we would like to do is to run a single query over both databases, like i.e. SelectQuery select = new SelectQuery(Person.class); Expression expression = ExpressionFactory.matchExp (Person.DEPARTMENT_PROPERTY + . + Department.NAME_PROPERTY, IT Department); But such a query runs into an exception with the following error message: Base table or view not found, message from server: Table 'foo.bar' doesn't exist Are such queries supported by Cayenne or do we have to split the task into two single queries? Christian
Re: Non persistent attributes
BTW, JPA spec defines a concept of a transient attribute, so this will be coming to Cayenne as well. Although as others noticed this is primarily a non-functional (although useful) convenience. Andrus On Mar 18, 2007, at 2:33 PM, Juergen Saar wrote: The actual way for cayenne is the defintion of getter/setter pairs an so a non persistent attribute is born. So far so good, but it would be fine if I could see them in the modeler/map-definition. It would be very helpful for the project-informations within the project-team. We have the separation between DbEntity and ObjEntity. One of the benefits of this kind of structure is that you can have attributes in the ObjEntity that are not part of the DbEntity. This attributes are non persistent. With these attributes an ObjEntity is improved to a BusinessObject. --- Juergen --- 2007/3/18, Aristedes Maniatis [EMAIL PROTECTED]: On 17/03/2007, at 5:17 AM, syrinx wrote: I am looking for a way to declare non persistent attributes using the cayenne modeler? I know that I can add my own attributes manually in the subclasses generated by the modeler, but it would be nice if these attributes could be included in the auto-generated entity class instead. Is this possible? If these attributes are the same for every entity, you can do this by editing the templates which are used to create the entity classes. Otherwise, I don't understand why editing the subclass isn't the easiest approach. Ari -- Aristedes Maniatis phone +61 2 9660 9700 PGP fingerprint 08 57 20 4B 80 69 59 E2 A9 BF 2D 48 C2 20 0C C8
Re: Cayenne Question
Hi Prashant, Note that Cayenne user support is done via the mailing list, as it allows us to better share the community knowledge. I am ccy'ing the question to the list. Please feel free to continue this discussion on the list: http://cayenne.apache.org/mailing-lists.html On Mar 23, 2007, at 1:23 PM, Prashant J wrote: Hi Andrew, It's Andrus, not Andrew :-) I am new to Cayenne. I am researching various OR mapping layers and have been pretty impressed with the design and ease of use of Cayenne. My question to you is, is it possible to store the ORMappings in the database and load it into Cayenne? In other words, can I write my own Configuration to load the the meta data from another source rather than from the XML file structure? If so, please tell me how. If not, please tell me what the philosophy is. Yes you can - this is just XML. Here is one possible scenario that uses Cayenne to bootstrap Cayenne: * Create a separate Cayenne project to map you bootstrap tables that store the Cayenne metadata. * Create your own Configuration subclass that internally instantiates a temporary throwaway Configuration just to read the metadata. Feel free to ask if you get stuck with the API. Cheers, Andrus
Summer of Code 2007
I overlooked the start of the Google Summer of Code program this year, but it is not too late yet for the students and mentors to sign up. See the details here: http://wiki.apache.org/general/SummerOfCode2007 Interested Students: Summer of Code is a program sponsored by Google that allows students to make money while working on open source projects. Cayenne participated last year - we mentored three projects. Please read the instructions and submit your proposal if you are interested and able to contribute to Cayenne. It is a good idea to introduce and sell your proposal on Cayenne dev list, if you want to find a dedicated mentor. I won't speak for other potential mentors, only for myself, but from the last year experience, I will only sign to mentor a proposal that helps us to advance features we are currently working on, such as JPA support. I would really hate to see any more wasted effort and abandoned code. But again, that's me :-) Please feel free to ask questions. Cayenne Committers: If anybody wants to (and thinks he realistically can) mentor a project this year, please sign up asap following the instructions above. Andrus
Re: 1.2.2 fetchFinished broken?
No, it is not a known bug. While 'fetchFinished' is deprecated in 3.0 in favor of lifecycle callbacks, it should work in 1.2.x. Could you open a bug report with some sample code that demonstrates the problem? http://issues.apache.org/cayenne/ Thanks Andrus On Mar 30, 2007, at 12:44 AM, Arturo Perez wrote: Hi all, I just upgraded my jars from 1.2 to 1.2.2. I now find that a fetchFinished that used to work is no longer called. Is this a known bug? -arturo
Re: Too many EventManager's?
Interesting. Didn't know it was a known problem with java 1.4. Lazy initialization was used exactly because we don't want dispatch threads to start unless they are needed. So ... per Wikipedia article this is a legacy JDK problem and going forward we should simply be using volatile keyword, which I think we should. Andrus On Mar 30, 2007, at 1:10 AM, Peter Karich wrote: Hello! I profile my application with netbeans profiler. And I figured out that there are 12 (!) EventManager's DispatchThreads started. All are in the 'waiting' state. I have no problems with that :-) But could it be that this code is problematic: public static EventManager getDefaultManager() { if (defaultManager == null) { synchronized (EventManager.class) { if (defaultManager == null) { defaultManager = new EventManager(2); } } } return defaultManager; } See the problems with double checked locking here: http://en.wikipedia.org/wiki/Double-checked_locking Particularly the section: One of the dangers of using double-checked locking in J2SE 1.4 ... A simple solution can be: private static EventManager defaultManager = new EventManager(2); public static EventManager getDefaultManager() { return defaultManager; } OR a full synchronized method. Peter.
Re: Cayenne -- Apache automatic deploy problem
Hi, See my original reply asking for more information here: http://objectstyle.org/cayenne/lists/cayenne-user/2007/03/0101.html BTW, it would be much easier to communicate if you subscribe to the list :-) Andrus On Mar 30, 2007, at 4:46 PM, Marc Gabriel-Willem wrote: Hi, Sorry to repost that question, but I was not properly register to the mailing list, so I was unable to reply properly. I'm using Cayenne (2.0.2) with the apache web server (5.5.20) and I'm facing to the following problem. When apache does an automatic deploy, all objects are serialized / deserialized without any error. But after that, when the code accesses a cayenne persistent object (member variable of a jsf backing bean), the following problem occurs: Caused by: java.lang.NullPointerException at org.apache.cayenne.access.DataContextQueryAction.interceptPaginatedQue ry (DataContextQueryAction.java:91) at org.apache.cayenne.access.DataContextQueryAction.execute (DataContextQuer yAction.java:50) at org.apache.cayenne.access.DataContext.onQuery(DataContext.java:1387) at org.apache.cayenne.access.DataContext.performQuery(DataContext.java: 1376 ) at org.apache.cayenne.access.ToManyList.resolvedObjectList (ToManyList.java: 307) at org.apache.cayenne.access.ToManyList.size(ToManyList.java:260) at com.sideinternational.web.profiling.group.GroupEditor.save (GroupEditor.j ava:246) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.jav a:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessor Impl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at org.apache.myfaces.el.MethodBindingImpl.invoke (MethodBindingImpl.java:13 2) For information, the following code throws that exception (the call to the size() method) : List itemsToRemove = m_editableGroup.getGroupContentArray(); for (int i=0; i itemsToRemove.size(); i++) ... Note: Child data context and ObjectEntities are stored in a serializable jsf backing bean. Thank you for your help. Marc Gabriel
Re: Cayenne -- Apache automatic deploy problem
This likely means that 'awakeFromDeserialization' [1] failed to attach DataContext to Cayenne stack. Is it possible that the code in question called before Cayenne stack is loaded? Where is it called anyways? Andrus [1] http://svn.apache.org/repos/asf/cayenne/main/branches/STABLE-2.0/ cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/ DataContext.java On Mar 30, 2007, at 10:55 AM, Marc Gabriel-Willem wrote: Hello, I checked the entity resolver value. Indeed, in this situation the value is 'null'. Marc -Original Message- From: Andrus Adamchik [mailto:[EMAIL PROTECTED] Sent: Friday, March 30, 2007 4:16 PM To: user@cayenne.apache.org Subject: Re: Cayenne -- Apache automatic deploy problem I can't reproduce this error in a test case. I am out of ideas what might have caused it. Can you possibly debug this condition to figure out why the 'metadata' field in DataContextQueryAction is null? First thing to check: m_editableGroup.getObjectContext().getEntityResolver() != null Andrus On Mar 30, 2007, at 5:24 PM, Marc Gabriel-Willem wrote: Hello, Sorry, it is the first time I'm using a list like this one. So, I'm doing some crazy error with it :) For example, I hope my reply all is a correct action to do in this case. I saw your first reply. I have exactly the same error when I stop and restart properly the Tomcat server. In fact, stoping and restarting the server simulate the serialization / deserialization operation that an application server can do at any time it wants (isn't it ?) Marc -Original Message- From: Andrus Adamchik [mailto:[EMAIL PROTECTED] Sent: Friday, March 30, 2007 3:09 PM To: user@cayenne.apache.org Cc: Marc Gabriel-Willem Subject: Re: Cayenne -- Apache automatic deploy problem Hi, See my original reply asking for more information here: http://objectstyle.org/cayenne/lists/cayenne-user/2007/03/0101.html BTW, it would be much easier to communicate if you subscribe to the list :-) Andrus On Mar 30, 2007, at 4:46 PM, Marc Gabriel-Willem wrote: Hi, Sorry to repost that question, but I was not properly register to the mailing list, so I was unable to reply properly. I'm using Cayenne (2.0.2) with the apache web server (5.5.20) and I'm facing to the following problem. When apache does an automatic deploy, all objects are serialized / deserialized without any error. But after that, when the code accesses a cayenne persistent object (member variable of a jsf backing bean), the following problem occurs: Caused by: java.lang.NullPointerException at org.apache.cayenne.access.DataContextQueryAction.interceptPaginatedQ u e ry (DataContextQueryAction.java:91) at org.apache.cayenne.access.DataContextQueryAction.execute (DataContextQuer yAction.java:50) at org.apache.cayenne.access.DataContext.onQuery(DataContext.java:1387) at org.apache.cayenne.access.DataContext.performQuery(DataContext.java: 1376 ) at org.apache.cayenne.access.ToManyList.resolvedObjectList (ToManyList.java: 307) at org.apache.cayenne.access.ToManyList.size(ToManyList.java:260) at com.sideinternational.web.profiling.group.GroupEditor.save (GroupEditor.j ava:246) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.jav a:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessor Impl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at org.apache.myfaces.el.MethodBindingImpl.invoke (MethodBindingImpl.java:13 2) For information, the following code throws that exception (the call to the size() method) : List itemsToRemove = m_editableGroup.getGroupContentArray(); for (int i=0; i itemsToRemove.size(); i) ... Note: Child data context and ObjectEntities are stored in a serializable jsf backing bean. Thank you for your help. Marc Gabriel
Re: BUG: Sql server Database pk generation ?
Hi, I don't think there was a change between 1.2.x and 2.0.x in this code. The error either means that the database schema in question is not setup to support autoincrement, or the driver doesn't support autoincremented keys. Are you using the same database and the same JDBC driver as before? Andrus On Mar 31, 2007, at 12:31 PM, Emre YILMAZ wrote: Hi, I set the primary key generation from database(Database generated) by modeller. But I got exception from some tables on Pk generation. This is working well with cayenne 1.2. However cayenne 2.0.2 throws below exception. Can you have any suggestion? Sql server 2005 express edition,Win xp, 1 GB ram, Core due 3 GHz, cayenne 2.0.2 Thank you.. Exception : 31.03.2007 19:08:53,968 ERROR [AWT-EventQueue-4] (MainFrameController.java: 143) - [v.2.0.2 January 14 2007] One and only one PK row is expected, instead got 0 org.apache.cayenne.CayenneRuntimeException: [v.2.0.2 January 14 2007] One and only one PK row is expected, instead got 0 at org.apache.cayenne.access.DataDomainFlushObserver.nextGeneratedDataRow s( DataDomainFlushObserver.java:87) at org.apache.cayenne.access.DataNodeQueryAction.nextGeneratedDataRows( DataNodeQueryAction.java:79) at org.apache.cayenne.access.jdbc.BatchAction.processGeneratedKeys( BatchAction.java:265) at org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries( BatchAction.java:208) at org.apache.cayenne.access.jdbc.BatchAction.performAction( BatchAction.java:81) at org.apache.cayenne.dba.sqlserver.SQLServerBatchAction.performAction( SQLServerBatchAction.java:59) at org.apache.cayenne.access.DataNodeQueryAction.runQuery( DataNodeQueryAction.java:59) at org.apache.cayenne.access.DataNode.performQueries (DataNode.java:273) at org.apache.cayenne.access.DataDomainFlushAction.runQueries( DataDomainFlushAction.java:219) at org.apache.cayenne.access.DataDomainFlushAction.flush( DataDomainFlushAction.java:141) at org.apache.cayenne.access.DataDomain.onSyncFlush (DataDomain.java:794) at org.apache.cayenne.access.DataDomain$2.transform (DataDomain.java:765) at org.apache.cayenne.access.DataDomain.runInTransaction (DataDomain.java :820) at org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:762) at org.apache.cayenne.access.DataContext.flushToParent (DataContext.java :1226) at org.apache.cayenne.access.DataContext.commitChanges (DataContext.java :1130) at tr.com.htr.hgys.db.base.DbObject.commitChanges(DbObject.java: 249) at tr.com.htr.hgys.db.Title.setName(Title.java:87) at tr.com.htr.hgys.ui.AdditionsModel.saveToDb (AdditionsModel.java:51) at tr.com.htr.hgys.ui.AdditionsPanel.doSave(AdditionsPanel.java:55) at tr.com.htr.hgys.ui.MainFrameController.saveBtnClick( MainFrameController.java:141) at tr.com.htr.hgys.ui.MainFrame$4.actionPerformed(MainFrame.java: 638) at javax.swing.AbstractButton.fireActionPerformed (AbstractButton.java :1995) at javax.swing.AbstractButton$Handler.actionPerformed( AbstractButton.java:2318) at javax.swing.DefaultButtonModel.fireActionPerformed( DefaultButtonModel.java:387) at javax.swing.DefaultButtonModel.setPressed (DefaultButtonModel.java :242) at javax.swing.plaf.basic.BasicButtonListener.mouseReleased( BasicButtonListener.java:236) at java.awt.AWTEventMulticaster.mouseReleased (AWTEventMulticaster.java :272) at java.awt.Component.processMouseEvent(Component.java:6038) at javax.swing.JComponent.processMouseEvent(JComponent.java:3260) at java.awt.Component.processEvent(Component.java:5803) at java.awt.Container.processEvent(Container.java:2058) at java.awt.Component.dispatchEventImpl(Component.java:4410) at java.awt.Container.dispatchEventImpl(Container.java:2116) at java.awt.Component.dispatchEvent(Component.java:4240) at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java :4322) at java.awt.LightweightDispatcher.processMouseEvent (Container.java:3986) at java.awt.LightweightDispatcher.dispatchEvent(Container.java: 3916) at java.awt.Container.dispatchEventImpl(Container.java:2102) at java.awt.Window.dispatchEventImpl(Window.java:2429) at java.awt.Component.dispatchEvent(Component.java:4240) at java.awt.EventQueue.dispatchEvent(EventQueue.java:599) at org.beryl.gui.WaitCursorEventQueue.dispatchEvent( WaitCursorEventQueue.java:83) at java.awt.EventDispatchThread.pumpOneEventForFilters( EventDispatchThread.java:273) at java.awt.EventDispatchThread.pumpEventsForFilter( EventDispatchThread.java:183) at java.awt.EventDispatchThread.pumpEventsForHierarchy( EventDispatchThread.java:173) at java.awt.EventDispatchThread.pumpEvents (EventDispatchThread.java:168) at java.awt.EventDispatchThread.pumpEvents (EventDispatchThread.java:160) at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
Re: SMall bug in docs
Hi Jerome, Could you please post the links to such pages? I don't see any references to objectstyle packages on cgen page, except for the 1.2 documentation bundle of course. Andrus On Apr 2, 2007, at 10:07 AM, jerome moliere wrote: Hi all, just to say that some web pages still refer to the old org.objectstylepackages, it prevents copy/paste to ant scripts ... please refer to the cgen page on cayenne website... Jerome -- Jerome Moliere - Mentor/J http://romjethoughts.blogspot.com/ auteur Eyrolles
Re: Calling MySql Stored Procedure return no resultset
Michael, Cayenne didn't officially support MySQL stored procedures as of 1.2 and 2.0. But in fact it is fairly easy to turn it on, based on the code used in other adapters. Let me poke around in the next few days - I may be able to enable it in 3.0 pretty quickly. Andrus On Apr 2, 2007, at 6:45 AM, Michael K wrote: Hi, I've written a stored procedure in mysql db that execute some join queries. Here is my sample stored procedure look like: DELIMITER $$ DROP PROCEDURE IF EXISTS `schooler`.`SearchDD` $$ CREATE PROCEDURE `SearchDD`(IN userInput varchar(200)) BEGIN CREATE TEMPORARY TABLE sp_mysrctoc12 SELECT sourceTable.id as source_id,sourceTable.topic_name,sourceTable.tid as source_tid,targetTable.topic_name as parent_name, sourceTable.scope as source_scope,sourceTable.st_timestamp,sourceTable.tid_table_name as source_tid_table_name,sourceTable.storage_id as source_storage_id,sourceTable.storage_label as source_storage_label FROM mk_search_topics as sourceTable inner join mk_search_topic_association as association on sourceTable.id = association.search_topic_id inner join mk_search_topics as targetTable on targetTable.id = association.target_topic_id where sourceTable.is_root_topic=0 and targetTable.is_root_topic=1 and sourceTable.storage_label = userInput; select source_id,topic_name,parent_name,relevance,source_tid,source_tid_table _name,source_storage_id,source_storage_label from sp_mysrctoc12 group by parent_name order by topic_name desc; DROP TABLE sp_mysrctoc12; END $$ DELIMITER ; Then I mapped the above stored procedure to Cayenne using modeller with one input parameter defined as userInput varchar(200). I also created DBEntity and ObjEntity with readOnly set to true. In my java code, I wrote something like this: DataContext ctxt = sSession.getDataContext(); ProcedureQuery query = new ProcedureQuery(SearchDD); query.addParameter(userInput,abcdef); List rows = ctxt.performQuery(query); // Display the row size System.out.println(row size: +row.size()); When I run the code in web application, it prints out 'row size: 0'. I executed the same stored procedure with the same parameter in mysql command line, it returned 4 rows. I wonder if this has something to do with accessing temporary table in multithreaded environment. I'm currently using Cayenne version 2.0.2 running jdk 1.5, mysql 5.0.18 with jconnector 5.0.5. Please help. Thanks, Michael __ __ 8:00? 8:25? 8:40? Find a flick in no time with the Yahoo! Search movie showtime shortcut. http://tools.search.yahoo.com/shortcuts/#news
Re: commitChanges() doesn't imply commit in db ?
Hi Jerome, I hope you don't mind that I am taking my reply back to the list to explain the line between free and commercial support for Cayenne. First - my proposal to help you as a consultant is not a business model! This is just reflecting a fact that there is only so much time a small developer community can dedicate to helping with specific user projects. Cayenne works with Sybase. All releases are tested against Sybase, and I am planning to do some testing again soon, when I get access to a Sybase instance. If you can demonstrate that this is a bug in Cayenne (which I am not yet convinced), we'll be glad to fix it. The line between what can and what can't be done as a free support is pretty fuzzy, but asking to debug a fairly complex setup on your hardware IMO crosses this line... unless there are more indicators that this is a Cayenne bug, not the driver bug or not the bug in your code. Please understand - there are many users, so there is a limit in personalized help. Andrus
Re: commitChanges() doesn't imply commit in db ?
On Apr 4, 2007, at 2:05 PM, Andrus Adamchik wrote: BTW, can you reproduce it without, just by running multiple parallel instances? that's reproduce without JMS :-)
Re: Cayenne web application tutorial
I am not aware of it, but this tutorial shows how to map and wire the main pieces. The next level is the User Guide itself. Andrus On Apr 8, 2007, at 10:25 AM, Reid Thompson wrote: Is there a more advance web application tutorial available than the one at http://cayenne.apache.org/doc/tutorial-webapp.html ??
Testing on Sybase
I just ran Cayenne unit test suite against Sybase ASE 12.5.3 (Mac OS X edition). The tests pass, although Sybase quickly runs out of transaction log space, printing the following message in the log: 00:0:4:2007/04/08 08:19:21.13 server 1 task(s) are sleeping waiting for space to become available in the log segment for database cayenne. This hangs the application. To unstuck it I had to log in to jISQL and execute the following SQL command, the application resumes and completes successfully: dump transaction cayenne with no_log I don't know if this information is of any relevance to what Jerome is doing, but can you possibly look in the Sybase logs to see what's going on on the Sybase server? Andrus On Apr 4, 2007, at 2:05 PM, Andrus Adamchik wrote: Cool - there may have been some misunderstanding on my part as well :-) I misinterpreted your suggestion, which was an offer of help with access to the environment. Anyways, let's move ahead with that. On Saturday I should get access to my old Mac laptop with Sybase 12 installed on it. If you could open a Jira with the code attachment that reproduces the problem, I'll try to run it in my env. https://issues.apache.org/cayenne/ BTW, can you reproduce it without, just by running multiple parallel instances? Andrus
Re: refreshing of cached objects
I suggest to use DataContext.invalidateObjects() to restore the object state after OptimisticLockingFailure. This will of course override all uncommitted changes on those objects, but this may be exactly what you want. Andrus On Apr 19, 2007, at 6:29 PM, Ayhan Kondoz wrote: Hi, i have a problem with refreshing of cached objects. I do something like this: SelectQuery query = new SelectQuery (de.freenet.cayenne.kontingent.Customer.class, Expression.fromString (cid = + cid)); List list = context.performQuery(query); Customer customer = list.get(0); List accounts = c.getAccounts(); Account a = accounts.get(0); a.setAmount(amount); context.commitChanges(); I am using Optimistic Locking on the Account Object and what I need to do is to catch the OptimisticLockException which may be thrown and redo the steps again. So if the data of the Account is changed within the database while I am using it I want to reload the customer and all it's related objects and try again. My problem is that after the OptimisticLockException is thrown the data within the Account object is not reloaded from the database. I tried to use query.setRefreshingObject(true); but still no changes. In the logging file I see that cayenne entries like this: SELECT t0.cid, t0.last_updated, t0.login, t0.next_cycle_date, t0.rec_change, t0.rec_create, t0.suspended, t0.id, t0.mandant_id FROM customer t0 WHERE t0.cid = ? [bind: 7] SELECT t0.activation_date, t0.amount, t0.credit_limit, t0.expire_date, t0.next_cycle_date, t0.rec_change, t0.rec_create, t0.account_type_id, t0.customer_id, t0.id, t0.unit_id FROM account t0 WHERE t0.customer_id = ? [bind: 797380] But the objects I get still contain the old data and I keep getting OptimisticLockExceptions. How do I tell cayenne to reload the customer and all it's related object from the database??? I am using cayenne 1.2.1, with shared caching and JavaGroups. Thanx Ayhan Kondoz Ayhan Kondoz Software-Entwicklung -- Telefon:+49 (0) 40 513 06 616 Telefax:+49 (0) 40 513 06 998 616 E-Mail: [EMAIL PROTECTED] mailto:[EMAIL PROTECTED] ag.de Website: http://www.freenet.de http://www.freenet.de/ ; http:// www.freenet-ag.de http://www.freenet-ag.de/ -- freenet.de AG Deelbögenkamp 4c 22297 Hamburg -- Vorsitzender des Aufsichtsrates: Prof. Dr. Helmut Thoma Vorstand: Eckhard Spoerr (Vors.), Axel Krieger, Stephan Esch, Eric Berger Amtsgericht Hamburg HRB 74048
Re: Validation problem
Hi Landry, It could be possible that there is another instance of 'Performer' created as a side effect of some other operation. One way to verify this is to inspect a list of dirty objects returned from 'DataContext.newObjects()' method right before commit. Another place to check for suspect objects is the list returned by 'DataContext.modifiedObjects()'. Andrus On Apr 22, 2007, at 4:32 PM, Landry Soules wrote: Hello, I have a strange problem wit my web app. From time to time, i get a ValidationException when i submit a form. Here is the trace : org.apache.cayenne.validation.ValidationException: [v.2.0.2 January 14 2007] Validation has failed. Validation failure for eu.kwark.sql.Performer.toGender: toGender is required. Validation failure for eu.kwark.sql.Performer.id: id is required. Validation failure for eu.kwark.sql.Performer.firstName: firstName is required. Validation failure for eu.kwark.sql.Performer.dob: dob is required. Validation failure for eu.kwark.sql.Performer.lastName: lastName is required. at org.apache.cayenne.access.ObjectStoreGraphDiff.validateAndCheckNoop (ObjectStoreGraphDiff.java:112) at org.apache.cayenne.access.DataContext.flushToParent (DataContext.java:1209) at org.apache.cayenne.access.DataContext.commitChanges (DataContext.java:1130) at eu.kwark.inscription.InscriptionPerformer$1.onSubmit (InscriptionPerformer.java:88) Here is the code executed in my submit : tmpPerformer = (Performer) context.newObject(Performer.class); ... context.commitChanges(); Of course all these fields are filled ! Please can someone help me, or at least give me a hint about where i can search to solve my problem ? Thanks Landry
Re: AW: postgres, idle in transaction
Interesting... Looking at your log I see this: 15:33:08.267 (2) FE= Parse(stmt=S_1,query=BEGIN,oids={}) . 15:33:08.268 (2) FE= Parse(stmt=null,query=SELECT 15:33:28.461 (2) FE= Parse(stmt=S_2,query=COMMIT,oids={}) So transaction is clearly committed. But of course connection is not closed. It is returned to the pool instead. Still looks like a driver bug to me. Andrus On Apr 24, 2007, at 5:03 PM, Oilid Adsi wrote: Hi again, -Ursprüngliche Nachricht- Von: Andrus Adamchik [mailto:[EMAIL PROTECTED] Gesendet: Dienstag, 24. April 2007 12:23 An: user@cayenne.apache.org Betreff: Re: postgres, idle in transaction On Apr 24, 2007, at 12:58 PM, Oilid Adsi wrote: Normally I thought we can do the workaround with committing every query (method commitChanges in the DataContext) or setting the JDBC- parameter defaultAutoCommit=true. But both of these workarounds didn't work properly. I am sure they did not. I was surprised when Peter reported that 'commitChanges' worked as a workaround. This shouldn't make any difference. Postgres-JDBC-driver 8.2-504.jdbc3 Worth checking a different version as well (I've see strangest cross- version issues with the driver in the past). The postgres mailinglist is sure that this problem/bug was fixed (see attachment). I also switched to the newest jdbc-version: PostgreSQL 8.3devel JDBC3 with SSL (build 600). Re JDBC idle in transaction problem.txt Also could you possibly switch the DataSource to DBCP [2] and see if that DBCP DataSource does the right thing? We will do this switch and give feedback. Please do. This will be an indication of whether we need to fix our connection pool or not. Same behaviour and still the same problem with DBCP DataSource ;-( Sometimes the transaction will be committed sometimes not: postgres_debug_transaction.txt Why cayenne uses a transaction (BEGIN - COMMIT) for performing a select-query? Is this the useful way as described on this link: http://www.ashtech.net/~syntax/blog/archives/56-Hibernate-and- PostgreSQL-Require-Transactions.html Main reason is consistency. There can be select queries that are not just select (e.g. stored procedure queries that both select and update). So Cayenne handles all queries the same way, instead of trying to analyze each query coming down the pipe. Andrus Re JDBC idle in transaction problem.txt postgres_debug_transaction.txt
Re: AW: postgres, idle in transaction
On Apr 24, 2007, at 5:17 PM, Andrus Adamchik wrote: Interesting... Looking at your log I see this: 15:33:08.267 (2) FE= Parse(stmt=S_1,query=BEGIN,oids={}) . 15:33:08.268 (2) FE= Parse(stmt=null,query=SELECT 15:33:28.461 (2) FE= Parse(stmt=S_2,query=COMMIT,oids={}) So transaction is clearly committed. But of course connection is not closed. It is returned to the pool instead. Still looks like a driver bug to me. Andrus Sorry, you said sometimes. Just noticed that the first case indeed doesn't commit. Just thought of another potential source of leaks - Cayenne iterated queries. Are you using any of those? http://cayenne.apache.org/doc/iterating-through-data-rows.html Andrus
Re: postgres, idle in transaction
I just uploaded a patched 1.2 build with Cayenne connection pool rolling back transactions before returning them to the pool. Can you try it out (of course resetting DBCP data source back to Cayenne): http://people.apache.org/~aadamchik/patched/cayenne-nodeps-1.2.3-dev.jar I don't have too much hope this will fix it... but still worth a try. Andrus On Apr 24, 2007, at 5:28 PM, Oilid Adsi wrote: -Ursprüngliche Nachricht- Von: Andrus Adamchik [mailto:[EMAIL PROTECTED] Gesendet: Dienstag, 24. April 2007 16:21 An: user@cayenne.apache.org Betreff: Re: AW: postgres, idle in transaction On Apr 24, 2007, at 5:17 PM, Andrus Adamchik wrote: Interesting... Looking at your log I see this: 15:33:08.267 (2) FE= Parse(stmt=S_1,query=BEGIN,oids={}) . 15:33:08.268 (2) FE= Parse(stmt=null,query=SELECT 15:33:28.461 (2) FE= Parse(stmt=S_2,query=COMMIT,oids={}) So transaction is clearly committed. But of course connection is not closed. It is returned to the pool instead. Still looks like a driver bug to me. Andrus Sorry, you said sometimes. Just noticed that the first case indeed doesn't commit. Just thought of another potential source of leaks - Cayenne iterated queries. Are you using any of those? No, we are not using performIteratedQuery() with postgres. Is there another possibility to debug this problem or verify if this is maybe a cayenne or jdbc-postgres bug? Oilid
Re: AW: AW: postgres, idle in transaction
On Apr 26, 2007, at 1:14 PM, Oilid Adsi wrote: Or maybe by adding an explicit COMMIT after every SELECT- Statement when the connection will be returned to the pool? Can this implemented as an optional function to the Cayenne framework? Per your comment the patch doing rollback didn't help, why do you think commit should help? Commit and rollback both terminate a transaction. http://objectstyle.org/cayenne/lists/cayenne-user/2007/04/0159.html But if you want to explore various scenarios, Cayenne allows you to plug a custom implementation of DataSource via the DataSourceFactory mechanism. So you don't need to patch Cayenne, but instead you can write a custom DataSource (based on Cayenne or DBCP library, or do it from scratch) to do any pre- or post- processing of connections checked in or out of the pool. If you get to the cause of it, please share. Unfortunately I am out of ideas regarding this issue. Andrus
Re: user-defined transactions
On Apr 26, 2007, at 1:04 PM, Jens Mayer wrote: (Here is the first question: is it possible to bind two different transactions to the same thread?) No you can't. I am accessing two different db-schemas at the same time, using two DataDomains, one for each schema. Now I want to update data (synchronously) on both schemas with my own user-defined transaction-scope. You can use just one... Normally it should not matter whether domain1 or domain2 created a transaction, or you did it manually. If it is bound to an execution thread, Cayenne will figure out how to add all JDBC connections to this single transaction. Andrus
Re: CayenneDataObject missing from 2.0.2 cayenne-client-nodeps.jar
Hi, Since you mentioned war, I assume you are deploying a web application. So you should be using cayenne-nodeps.jar, not cayenne- client-nodeps.jar. Andrus On Apr 26, 2007, at 6:03 PM, Giulio Cesare Solaroli wrote: Hello everybody, I was trying to trim the size of my application war replacing the full cayenne jar with the client one. But when compiling the application using the cayenne-client-nodeps.jar, the compiler barks about a missing symbol: class CayenneDataObject. I have opened the jar, and the CayenneDataObject is really missing. Did I miss something really obvious, or this is just a problem left behind during all the migrations that had happened recently? Thanks, Giulio Cesare
Re: Error: Parameter #1 has not been set
On May 9, 2007, at 11:32 PM, Alejandro Daniel Toffetti wrote: I'm getting lots of incompatible types errors in sentences such as: List rows = context.performQuery(query); I have very little experience with NetBeans, but something tells me this is about JDK 1.5 generics. Essentially the problem is that Cayenne framework can't use generics because it has to support JDK 1.4, while most IDEs totally unreasonably complain about that. The point is that generics use is optional in Java, and this is not an *error*, in a sense that such code will compile and run fine under JDK 1.5. In Eclipse (another popular IDE), this type of situation is reported as a *warning* (and can be turned off completely). So you have two choices - (1) figure out how to configure NetBeans to stop treating it as an error or (2) just ignore it. Andrus
Re: complex query and SQLtemplate
Hi Marcin, Initially I thought the query may be losing a parameter $joinClause, but then the SQL at the DB level would look like SELECT ... FROM ROOM join ORDER BY Room.name The join word is not a parameter and is instead hardcoded in your template, right? And still does not show up in the output... So there's something else. Could you post the code you are using to build and call the query on the client? Andrus On May 14, 2007, at 3:39 AM, Marcin Skladaniec wrote: Hi I did some more debugging and I found that SQLTemplate on client : SELECT #result('Room.name' 'java.lang.String'), #result('site.name' 'java.lang.String'), #result('Room.seatedCapacity' 'java.lang.Integer') FROM ROOM INNER JOIN SITE on ROOM.siteid = SITE.id ORDER BY Room.name is loosing the join part when executed on server: [java] 10:24:24,003 [SocketListener0-0] INFO org.apache.cayenne.access.QueryLogger :276 - SELECT Room.name, site.name, Room.seatedCapacity FROM ROOM ORDER BY Room.name Why is that? Is there something I'm doing wrong ? Marcin On 13/05/2007, at 8:29 PM, Marcin Skladaniec wrote: Hi In our project we needed a generic way to relate many different entities. Cayenne does not allow vertical inheritance, therefore I had to make my way around, and create a fake relationship. I'm using custom superclass for entities, in which accessing methods, like the one in cayenne are implemented (getTags/addToTags/ removeFromTags). Those methods execute SelectQuery(). I had to expose the pk's , but it works well. The application is using derby and ROP. the problem we have is with creating a query like: select $attributes from $entity join $joinClause where ((id in ( select TAGRELATION.ENTITYRECORDID from TAGRELATION join tag on TAGRELATION.tagid = tag.id where ((TAGRELATION.ENTITYIDENTIFIER = $entityCode) AND (id = $entityId)) )) AND ($qualifier)) order by $orderby org.apache.cayenne.exp.Expression does not support that complexity, therefore I started to use SQLTemplate, but when query like this is executed: SELECT #result('Room.name' 'java.lang.String'), #result ('site.name' 'java.lang.String'), #result('Room.seatedCapacity' 'java.lang.Integer') FROM ROOM JOIN SITE on ROOM.siteid = SITE.id exception is thrown: org.apache.cayenne.CayenneRuntimeException: [v.3.0-SNAPSHOT Mar 29 2007 11:34:53] Remote error. URL - http://localhost:8181/angel- server-cayenne; CAUSE - [v.3.0-SNAPSHOT Mar 29 2007 11:34:53] [v.$ {project.version} ${project.build.date} ${project.build.time}] Exception processing message org.apache.cayenne.remote.QueryMessage. Root cause: [v.$ {project.version} ${project.build.date} ${project.build.time}] Error getting ResultIterator: Query Exception: java.sql.SQLException: Column 'SITE.NAME' is either not in any table in the FROM list or appears within a join specification and is outside the scope of the join specification or appears in a HAVING clause and is not in the GROUP BY list. If this is a CREATE or ALTER TABLE statement then 'SITE.NAME' is not a column in the target table. at org.apache.derby.client.am.SQLExceptionFactory.getSQLException (Unknown Source) at org.apache.derby.client.am.SqlException.getSQLException (Unknown Source) at org.apache.derby.client.am.Connection.prepareStatement(Unknown Source) at org.apache.cayenne.conn.ConnectionWrapper.prepareStatement (ConnectionWrapper.java:274) at org.apache.cayenne.conn.ConnectionWrapper.prepareStatement (ConnectionWrapper.java:280) at org.apache.cayenne.access.TransactionConnectionDecorator.prepareState ment(TransactionConnectionDecorator.java:179) at org.apache.cayenne.access.jdbc.SQLTemplateAction.execute (SQLTemplateAction.java:130) at org.apache.cayenne.access.jdbc.SQLTemplateAction.performAction (SQLTemplateAction.java:107) at org.apache.cayenne.access.DataNodeQueryAction.runQuery (DataNodeQueryAction.java:57) at org.apache.cayenne.access.DataNode.performQueries (DataNode.java:236) at org.apache.cayenne.access.DataDomainLegacyQueryAction.execute (DataDomainLegacyQueryAction.java:82) at org.apache.cayenne.access.DataDomain$1.transform (DataDomain.java:704) at org.apache.cayenne.access.DataDomain.runInTransaction (DataDomain.java:802) at org.apache.cayenne.access.DataDomain.performQueries (DataDomain.java:698) at org.apache.cayenne.access.DataContext.internalPerformIteratedQuery (DataContext.java:1261) at org.apache.cayenne.access.DataContext.performIteratedQuery (DataContext.java:1227) at org.apache.cayenne.access.IncrementalFaultList.fillIn (IncrementalFaultList.java:190) at org.apache.cayenne.access.IncrementalFaultList.init (IncrementalFaultList.java:156) at org.apache.cayenne.access.DataContextQueryAction.interceptPaginatedQu ery(DataContextQueryAction.java:109) at org.apache.cayenne.access.DataContextQueryAction.execute (DataContextQueryAction.java:54) at
Re: Stored procedure question ?
This doesn't make sense to me either. So what happens of you remove the first parameter and set returningValue to false? Andrus On May 14, 2007, at 4:58 PM, Marc Gabriel-Willem wrote: procedure name=spViewCustomer schema=dbo returningValue=true procedure-parameter name=returnValue type=INTEGER direction=in/ procedure-parameter name=id type=INTEGER direction=in/ procedure-parameter name=user type=VARCHAR length=25 direction=in/ /procedure ... I've no problem with the id and user parameters. But I really do not understand why I have to set my returnValue as INTEGER with the direction IN... I tried with other options but without any success.
Re: Stored procedure question ?
Is it a problem from the modeler? Per SQLServer docs: http://support.microsoft.com/kb/285295 Every SQL Server stored procedure has a return value parameter (whether it is explicitly used or not) which is called @return_value. I suspect that JDBC blows on implicit mapped @return_value. We can probably do something smarter about reverse engineering of SQLServer procedures to account for that (like removing an implicit return). Would you mind opening an improvement request in Jira? http://issues.apache.org/cayenne The exception: Caused by: java.sql.SQLException: Operand type clash: int is incompatible with cursor ... I am not sure about this handling a refcursor OUT parameter - I need to try it for myself to be able to comment intelligently. Unfortunately I don't have time to look at it now either :-( For now you can try the same trick with removing the return value? Andrus On May 15, 2007, at 10:53 AM, Marc Gabriel-Willem wrote: Hello, I removed the first parameter and the returningValue flag ... and indeed it is working properly. I'm really surprised because I used the reengineer database schema function to create the mapping file. Is it a problem from the modeler? I've another question for you. In MS sqlserver, we have the following stored procedure: CREATE procedure [dbo].[spTestGet2] @rs_cursor CURSOR VARYING OUTPUT AS SET @rs_cursor = CURSOR FOR select id, data, lastupdate, description from tTest OPEN @rs_cursor GO Following mapping has been done using the modeler: procedure name=spTestGet2 schema=dbo catalog=spp returningValue=true procedure-parameter name=@RETURN_VALUE type=INTEGER length=4/ procedure-parameter name=@rs_cursor type=INTEGER length=4 direction=in_out/ /procedure By the way, for the @return_value, I've the following warning: missing direction. I removed the first parameter in order to fix that warning. Nevertheless, the performGenericQuery function throws an exception: ... ProcedureQuery query = new ProcedureQuery(spTestGet2); QueryResponse result = context.performGenericQuery(query); ... The exception: Caused by: java.sql.SQLException: Operand type clash: int is incompatible with cursor ... For information, I'm using the JTDS 1.2 driver. Thank you for your help. Regards, Marc -Original Message- From: Andrus Adamchik [mailto:[EMAIL PROTECTED] Sent: Monday, May 14, 2007 4:04 PM To: user@cayenne.apache.org Subject: Re: Stored procedure question ? This doesn't make sense to me either. So what happens of you remove the first parameter and set returningValue to false? Andrus On May 14, 2007, at 4:58 PM, Marc Gabriel-Willem wrote: procedure name=spViewCustomer schema=dbo returningValue=true procedure-parameter name=returnValue type=INTEGER direction=in/ procedure-parameter name=id type=INTEGER direction=in/ procedure-parameter name=user type=VARCHAR length=25 direction=in/ /procedure ... I've no problem with the id and user parameters. But I really do not understand why I have to set my returnValue as INTEGER with the direction IN... I tried with other options but without any success.
Re: OutOfMemoryError: reading a large number of objects one by one
On May 15, 2007, at 12:47 AM, Tomi N/A wrote: Reduced the max number of objects to 1000. The result? A NPE at: for (MyClassC mcc : (ListMyClassC)mca.getToMyClassC().getToParentClass ().getMyClassCArray()) { Ok, so the cache size will have to be big enough to hold all resolved objects within the lifetime of a context. So let's try another strategy. Return the max objects back to 1 and uncheck use shared cache for the DataDomain. If this doesn't work, I suggest to run the app in profiler to see exactly how objects are allocated and collected. The database referential integrity ensures there can be no nulls if (mcc != null), which it is. As far as -Xmx is concerned, it's at it's default value (64M), which should be several times more than necessary for the job. Agreed - the default 64m should be enough if there's no leaks. Andrus
[ANN] Apache Cayenne 1.2.3 and 2.0.3 release
Cayenne team is glad to announce a major bugfix release of the two stable branches: 1.2.3 and 2.0.3. See the details here: http://cayenne.apache.org/2007/05/16/may-16-2007-cayenne-203- and-123-released.html Note that 1.2.3 Maven bundle will take a few days to appear on ibiblio. 2.0.3 should be there a bit quicker. Cheers, Andrus
Re: How do I get a record for non integer pk?
Exactly. There is an 'objectForPk(.., int)' and another one 'objectForPk(.., Object)': http://cayenne.apache.org/doc20/api/cayenne/org/apache/cayenne/ DataObjectUtils.html Andrus On May 16, 2007, at 8:01 PM, Bryan Lewis wrote: We use that objectForPK() method routinely with a String key and haven't had any problems. What do you mean by not working? Is it throwing a CayenneRuntimeException? Frank wrote: Hello, The code below is not working, as it expects the PK to be integer. There is only one String field in the table defined as a pk. Thanks Frank private void getRecord(String name) { DataContext context = DataContext.getThreadDataContext(); System s = new System(); s = (System) DataObjectUtils.objectForPK(context, System.class, name); form.setDataObject(s); }
Re: How do I get a record for non integer pk?
These two lines are not the same: at org.objectstyle.cayenne.DataObjectUtils.intPKForObject (DataObjectUtils.java:93) s = (System) DataObjectUtils.objectForPK(context, System.class, name); So now you are talking about a different problem. To fix your latest problem use pkForObject instead of intPKForObject Andrus On May 16, 2007, at 8:11 PM, Frank wrote: Does it have someting to do with the System name? reserved word? Class org.objectstyle.cayenne.CayenneRuntimeException Message [v.1.2.3 May 6 2007] PK is not a number: ObjectId:System, System=AIX org.objectstyle.cayenne.CayenneRuntimeException: [v.1.2.3 May 6 2007] PK is not a number: ObjectId:System, System=AIX at org.objectstyle.cayenne.DataObjectUtils.intPKForObject (DataObjectUtils.java:93) at net.sf.click.extras.cayenne.CayenneForm.setDataObject (CayenneForm.java:335) at stemc.page.EditSystemPage.getRecord(EditSystemPage.java:41) at stemc.page.EditSystemPage.onGet(EditSystemPage.java:71) Thanks Frank - Original Message - From: Bryan Lewis [EMAIL PROTECTED] To: user@cayenne.apache.org Sent: Wednesday, May 16, 2007 1:01 PM Subject: Re: How do I get a record for non integer pk? We use that objectForPK() method routinely with a String key and haven't had any problems. What do you mean by not working? Is it throwing a CayenneRuntimeException? Frank wrote: Hello, The code below is not working, as it expects the PK to be integer. There is only one String field in the table defined as a pk. Thanks Frank private void getRecord(String name) { DataContext context = DataContext.getThreadDataContext(); System s = new System(); s = (System) DataObjectUtils.objectForPK(context, System.class, name); form.setDataObject(s); }
Re: How do I get a record for non integer pk?
I think you are right. Click CayenneForm IIRC does not support non- int PK's. Your stack confirms that: at org.objectstyle.cayenne.DataObjectUtils.intPKForObject (DataObjectUtils.java:93) at net.sf.click.extras.cayenne.CayenneForm.setDataObject (CayenneForm.java:335) Andrus On May 16, 2007, at 8:23 PM, Frank wrote: I think it has something to do with Click CayenneForm I changed CayenneForm to Form and it works. Seems CayenneForm is tring to fetch my int id Frank - Original Message - From: Andrus Adamchik [EMAIL PROTECTED] To: user@cayenne.apache.org Sent: Wednesday, May 16, 2007 1:17 PM Subject: Re: How do I get a record for non integer pk? These two lines are not the same: at org.objectstyle.cayenne.DataObjectUtils.intPKForObject (DataObjectUtils.java:93) s = (System) DataObjectUtils.objectForPK(context, System.class, name); So now you are talking about a different problem. To fix your latest problem use pkForObject instead of intPKForObject Andrus On May 16, 2007, at 8:11 PM, Frank wrote: Does it have someting to do with the System name? reserved word? Class org.objectstyle.cayenne.CayenneRuntimeException Message [v.1.2.3 May 6 2007] PK is not a number: ObjectId:System, System=AIX org.objectstyle.cayenne.CayenneRuntimeException: [v.1.2.3 May 6 2007] PK is not a number: ObjectId:System, System=AIX at org.objectstyle.cayenne.DataObjectUtils.intPKForObject (DataObjectUtils.java:93) at net.sf.click.extras.cayenne.CayenneForm.setDataObject (CayenneForm.java:335) at stemc.page.EditSystemPage.getRecord(EditSystemPage.java:41) at stemc.page.EditSystemPage.onGet(EditSystemPage.java:71) Thanks Frank - Original Message - From: Bryan Lewis [EMAIL PROTECTED] To: user@cayenne.apache.org Sent: Wednesday, May 16, 2007 1:01 PM Subject: Re: How do I get a record for non integer pk? We use that objectForPK() method routinely with a String key and haven't had any problems. What do you mean by not working? Is it throwing a CayenneRuntimeException? Frank wrote: Hello, The code below is not working, as it expects the PK to be integer. There is only one String field in the table defined as a pk. Thanks Frank private void getRecord(String name) { DataContext context = DataContext.getThreadDataContext(); System s = new System(); s = (System) DataObjectUtils.objectForPK(context, System.class, name); form.setDataObject(s); }
Re: Should localObject() traverse the whole graph?
Hi Kevin, 'localObject' is not moving objects, between contexts. Instead it locates an object counterpart (another copy) in the target context, instantiating a fault if needed. In light of that your question about graph traversal is probably not relevant. Andrus On May 18, 2007, at 7:32 PM, Kevin Menard wrote: Hi, I've just noticed that localObject does not traverse whole graph of the object moving to the new DC. Is this by design, due to computational complexity, or a bug? Just to illustrate the problem: Given three data objects {A, B, C}, registered with the following data contexts: DC1: A (committed) DC2: B (new, modified) C (new, modified) Such that B and C have a to-one relationship. A and B also required a relationship, but are in separate DCs. So, move B to DC1 via localObject. After that, we have: DC1: A B DC2: C? The relationship between B C is clobbered. I haven't debugged enough to see if C is still in DC2 or not. All handles to DC2 are effectively destroyed in the normal code, so I'd have to add additional code to deal with it. Anyway, I know how to workaround it, but am wondering whether this is something that should go into JIRA or if it's something that won't change. Thanks, Kevin Kevin Menard Servprise International, Inc. 800.832.3823 x308
Re: Should localObject() traverse the whole graph?
On May 18, 2007, at 8:13 PM, Kevin Menard wrote: The section in the docs titled Moving Objects Between Contexts may be better named as well. Agreed. The moving emphasis is wrong. Maybe the correct solution is to finally make it possible to associate two unregistered data objects and then only bring the DC into the mix once the data is all set . . . Yes. I advocated for some time aligning Cayenne context API with JPA in this respect, that defines two methods for sucking a non- persistent object graph into a context - persist, which is roughly the same as registerNewObject, and merge, which is somewhat similar to localObject, but works recursively. Andrus
Re: Behavior of remove(object) on ToManyList
Actually I see no problem with the list being modifiable, (dis) connecting a relationship on remove/add. This fits into the ORM model, as long as there is an understanding that a relationship list is connected to a persistence engine, the same way individual objects are. Andrus On May 30, 2007, at 6:20 AM, Kevin Menard wrote: -Original Message- From: Andrus Adamchik [mailto:[EMAIL PROTECTED] Sent: Thursday, May 24, 2007 5:52 AM To: user@cayenne.apache.org Subject: Re: Behavior of remove(object) on ToManyList Hi Alex, Well, actually one of Cayenne responsibilities is maintaining consistent object graph. To-many lists are a part of that object graph. So if you want to remove an object from the list for presentation reasons, but keep the relationship intact, the only right way is to clone the list and remove items from the clone. I.e.: List centers = new ArrayList(getSelectedCountry().getCenters()); Perhaps it would make sense if the relationships return unmodifiable Lists then? It seems to me like it could clear up this whole class of problems. -- Kevin
Re: Not all values are saved
From your description the flow of events is not quiet clear, but my guess is that you haven't defined the mapping for the corresponding obj-attribute's - hasIndex, hasWkn, wknisin. One way to do it is to select the Clip ObjEntity and click on the Sync ObjEntity with DbEntity button (a button with back and forward arrows). Andrus On May 30, 2007, at 5:42 PM, Tobias Marx wrote: Hi there! I am having some problems trying to save an object using Cayenne's CayenneDataObject.class I have added 3 new attributes to an already-existing object, but those values are not stored. Inside the XML file these additional lines are: db-attribute name=has_index type=BOOLEAN/ db-attribute name=has_wkn type=BOOLEAN/ db-attribute name=wknisin type=VARCHAR length=15/ Inside the _Clip.java class the methods are: public void setHasIndex(Boolean hasIndex) { writeProperty(hasIndex, hasIndex); } public Boolean getHasIndex() { return (Boolean)readProperty(hasIndex); } public void setHasWkn(Boolean hasWkn) { writeProperty(hasWkn, hasWkn); } public Boolean getHasWkn() { return (Boolean)readProperty(hasWkn); } The code that saves the new data is: getClip().saveObject(context); If I add another lines for debug purposes: Clip temp = getClip(); getClip().saveObject(context); temp contains true, true and something. However, the line that is stored in the database table Contains null, null, null for those 3 Attributes. Any ideas? Thanks! Tobias
Re: UTF8 problem
I still suspect that this is a JDBC or MySQL problem, not Cayenne. Here is another URL parameter you may try: useUnicode=true. Also you may want to doublecheck whether database was configured to support UTF-8. Enter mysql prompt and do something like this: use mydb; status; This should print a bunch of info, including this: Server characterset:utf-8 Db characterset:utf-8 Client characterset:utf-8 Conn. characterset:utf-8 If it prints anything other than utf-8, you may need to recreate the DB with an appropriate charset. Andrus On Jun 1, 2007, at 8:07 PM, marco turchi wrote: Dear Kevin, I have tried, but nothing has changed. here I have an Italian example of my problem: 1a)Assemblea e scontro in redazione per l'allegato di Michela Brambilla Interviene anche il direttore Belpietro: Il quotidiano sarà in edicola Inserto dei Circoli della Libertà e al Giornale scatta lo sciopero 1b)Assemblea e scontro in redazione per l'allegato di Michela Brambilla Interviene anche il direttore Belpietro: Il quotidiano sarà in edicola Inserto dei Circoli della Libertà e al Giornale scatta lo sciopero where 1a is obtained directly by mysql, and 1b is obtained by Java/ Cayenne. A difference that I have noticed is that: if I write on two different files the sentence using mysql for 1a and Java for 1b. The first is encoded as UTF-8 Unicode English text,while the second as UTF-8 Unicode text. Sorry about that. Thanks Marco On 6/1/07, Kevin Menard [EMAIL PROTECTED] wrote: -Original Message- From: marco turchi [mailto:[EMAIL PROTECTED] Sent: Friday, June 01, 2007 9:26 AM To: user@cayenne.apache.org Subject: Re: UTF8 problem I'm using Cayenne 1.2.1, could the version be the problem? Note that the languages of my shell are: en_GB.UTF-8:en_GB:en I don't know for certain that this will fix your problem, but you should probably try 1.2.3. It's the latest 1.2.x release, is fully backward-compatible with 1.2.1, and includes a decent number of bug fixes. -- Kevin
Re: UTF8 problem
On Jun 2, 2007, at 9:43 PM, marco turchi wrote: | summary | longtext | utf8_general_ci | YES | | description | longtext | utf8_general_ci | YES | I believe the third column is collation, not encoding; so encoding is still latin. My idea is that the data are encoding UTF8 inside the table, but when Cayenne creates a connection, all the data that pass through that connection are encoding latin1. Is it right? Disclaimer *** : I've never tried the advise below myself, only found it in MySQL docs. So I suggest taking a full MySQL dump from your production DB, loading it to an offline test DB, and trying it there first, before applying to production. With ALTER DATABASE and ALTER TABLE you can change the default database charset and a default table charset on MySQL 5.0: http://dev.mysql.com/doc/refman/5.0/en/alter-database.html http://dev.mysql.com/doc/refman/5.0/en/alter-table.html Be careful with various ALTER TABLE charset options. According to the docs there are different ways to address a number of related but distinct charset conversion issues. You need to pick the one that is appropriate for you. So definitely do it on a test DB first. Good luck! Andrus
Re: Creating Compound PKs
Hi John, A question - is serverid a foreign key to another table by any chance? Andrus On Jun 4, 2007, at 9:09 AM, John Armstrong wrote: Does Cayenne allow for the creation of a compound PK? I searched the archives and google more generally and could only find hints at this. The docs did not clarify either (although it was also hinted at. .I think, its a bit late :) ). My table looks like this: id name serverid status enabled I need to create a compound PK on name/serverid that will maintain uniqueness across these segments. My fallback is to create a validation that checks these before commit but my normal route in a non-ORM context is to let the DB enforce it and catch it there. Thanks! John-
Re: performing count
On Jun 2, 2007, at 4:29 AM, Michael Gentry wrote: Well, it would work without you providing a DataContext by creating a default DataContext and using it (obviously, only useful if the model is simple -- hence also needing a version where you provide the DataContext to use). I wouldn't even bother with a version that doesn't take a context - IMO we should minimize the number of places in the framework that assume a singleton Configuration based stack structure (even though it is a default). Ideally we should get rid our code of this assumption completely. Otherwise the usability of Cayenne across various J2EE (and other) environments will suffer greatly. We do have utility classes already, like DataObjectUtils (which are mainly containers for static methods -- aka functions). This would be a real class (or extension of an existing class), though. I am with Matt on the point that any new utility should preferably stay within the well understood framework concepts. A query that runs itself is definitely NOT something Cayenne has ever done. I think we can squeeze it in the current framework, tweaking what has been already proposed - a CountQuery, by adding a new method to DataObjectUtils: intValueForQuery (analogous to existing objectForQuery). So one can do: Query q = new CountQuery(Artist.class, qualfier); int count = DataObjectUtils.intValueForQuery(context, q); I'll ponder this a bit more. Doing the basic count would be pretty easy, but getting it to work with a qualifier will be a bit more work to make it nice. BTW with EJBQL coming in 3.0 should provide the runtime to run the following object syntax: select count(a) from Artist a where a.name = 'Dali' So this will provide a ready-to-use runtime for the classic count query. Although if somebody wants to implement the count-with- qualifier backend differently for the interim, that's fine too. Andrus
Re: performing count
It'd be worth adding support for not only count but avg, max, min, sum operations on keys... like: [EMAIL PROTECTED] Sure, but my point was that query should not run itself. Hence the separation between the query and its execution logic. Maybe the class I posted beforehand could be easily morphed into such a query helper(?). Yes - in defining CountQuery, MaxQuery, etc. it seems like what we need. I think the query needs to return 1 object in the list of results which is a Number rather than returning a Map where there's an element with key 'C' (which is fine for sql template operations but I'd have thought the point of a stats helper would be to abstract that kind of stuff. I was thinking that DataObjectUtils.intValueForQuery proposed below would do the unwrapping of the map into a scalar value. It can do it in a generic fashion as long as there's only one key in the returned map. Andrus On Jun 4, 2007, at 10:30 AM, Lachlan Deck wrote: Hi there, On 04/06/2007, at 5:05 PM, Andrus Adamchik wrote: We do have utility classes already, like DataObjectUtils (which are mainly containers for static methods -- aka functions). This would be a real class (or extension of an existing class), though. I am with Matt on the point that any new utility should preferably stay within the well understood framework concepts. A query that runs itself is definitely NOT something Cayenne has ever done. I think we can squeeze it in the current framework, tweaking what has been already proposed - a CountQuery, by adding a new method to DataObjectUtils: intValueForQuery (analogous to existing objectForQuery). So one can do: Query q = new CountQuery(Artist.class, qualfier); int count = DataObjectUtils.intValueForQuery(context, q); It'd be worth adding support for not only count but avg, max, min, sum operations on keys... like: [EMAIL PROTECTED] Maybe the class I posted beforehand could be easily morphed into such a query helper(?). I think the query needs to return 1 object in the list of results which is a Number rather than returning a Map where there's an element with key 'C' (which is fine for sql template operations but I'd have thought the point of a stats helper would be to abstract that kind of stuff. with regards, -- Lachlan Deck
Re: performing count
On Jun 4, 2007, at 10:46 AM, Lachlan Deck wrote: Will the DataObjectUtils.intValueForQuery work with 3 tier also? It should. You can look at the sources of the current DataObjectUtils.objectForQuery - the new method is really just an extension of it. Andrus
Re: Serialization of datacontext
Could you please open a bug report? We'll need to do some testing to settle on the best strategy (I am leaning towards not serializing the local DataRowStore at all, and rebuilding it on deserialization instead). Thanks Andrus On Jun 4, 2007, at 11:46 AM, bob wrote: Hi I debugged this a bit and notice the following: on DataContext serialization the following code is executed in writeObject(ObjectOutputStream) ... // Serialize local snapshots cache if (!isUsingSharedSnapshotCache()) { out.writeObject(objectStore.getDataRowCache()); } ... So if useSharedCache is false, the ObjectStore's DataRowStore is also serialized. DataRowStore's reference to EventManager is transient and not serialized. So upon deserialization, when DataRowStore is read back in, the EventManager is null and this caused the exception below. What is the best way to fix this? EventManager should not be transient? Or a new EventManager should be created in DataRowStore.readObject(ObjectInputStream)? regards bob bob wrote: Hi all Using cayenne 1.2.3 and jdk 1.5 on Windows XP. Sometimes while developing with Tomcat I get the following exception. Seems to happen on serialization of DataContext along with the session. Below the exception is a little test class to reproduce this. Note that if useSharedCache = true, then there is no exception. Should I open a JIRA issue or is this expected behavior? Exception in thread main org.objectstyle.cayenne.CayenneRuntimeException: [v.1.2.3 May 6 2007] Commit Exception org.objectstyle.cayenne.access.DataContext.flushToParent (DataContext.java:1290) org.objectstyle.cayenne.access.DataContext.commitChanges (DataContext.java:1166) test.SerializeDCTest.main (SerializeDCTest.java:29) Caused by: java.lang.NullPointerException org.objectstyle.cayenne.access.DataRowStore.sendUpdateNotification (DataRowStore.java:709) org.objectstyle.cayenne.access.DataRowStore.processSnapshotChanges (DataRowStore.java:574) org.objectstyle.cayenne.access.DataDomainFlushAction.postprocess (DataDomainFlushAction.java:278) org.objectstyle.cayenne.access.DataDomainFlushAction.flush (DataDomainFlushAction.java:178) org.objectstyle.cayenne.access.DataDomain.onSyncFlush (DataDomain.java:846) org.objectstyle.cayenne.access.DataDomain$2.transform (DataDomain.java:817) org.objectstyle.cayenne.access.DataDomain.runInTransaction (DataDomain.java:872) org.objectstyle.cayenne.access.DataDomain.onSync(DataDomain.java:814) org.objectstyle.cayenne.access.DataContext.flushToParent (DataContext.java:1262) package test; public class SerializeDCTest { public SerializeDCTest() { } public static void main(String[] args) { //boolean useSharedCache = true; //works boolean useSharedCache = false; DataContext context = DataContext.createDataContext (useSharedCache); context = serializeDC(context); Employee emp = (Employee) DataObjectUtils.objectForPK (context, Employee.class, 740); emp.setFirstname(test + Math.random()); context.commitChanges(); } public static DataContext serializeDC(DataContext dc) { try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(dc); ByteArrayInputStream is = new ByteArrayInputStream (bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(is); DataContext result = (DataContext) ois.readObject(); return result; } catch (Exception ex) { throw new RuntimeException(DataContext serialization failed, ex); } } } kind regards bob
Re: Cayenne with PerUserPoolDataSource
Hi Emilian, It these some way to make Cayenne use this (basically DataSource.getConnection(user,password) instead of DataSource.getConnection()) ? Not out-of-the-box. But you can achieve that via a custom DataSource wrapper that channels DataSource.getConnection() to DataSource.getConnection(user,password): class DataSourceDecorator implements DataSource { protected PerUserPoolDataSource delegate; public Connection getConnection() { // get user name and password via some custom mechanism, e.g. via a ThreadLocal... String userName = ... String password = ... return delegate.getConnection(userName, password); } . } Such custom DataSource can be installed in runtime via a custom DataSourceFactory that can be configured for the DataNode in the Modeler: http://cayenne.apache.org/doc/api/org/apache/cayenne/conf/ DataSourceFactory.html Andrus On Jun 4, 2007, at 4:16 PM, Emilian Bold wrote: Hy, I would like to use Cayenne with something like PerUserPoolDataSource [1]. Basically I would like separate database-connections for particular users and not generic data-source-wide user /passwords. It these some way to make Cayenne use this (basically DataSource.getConnection(user,password) instead of DataSource.getConnection()) ? I would also like to know of any other way to have a per-user pool with Cayenne, if any. Thanks, Emilian Bold 1.http://jakarta.apache.org/commons/dbcp/apidocs/org/apache/commons/ dbcp/datasources/PerUserPoolDataSource.html -- Emilian Bold +40 740235562 http://www.emilianbold.ro Java and NetBeans Platform-loving consulting services from Timisoara, Romania.
Re: SQLTemplate not faulting an object
Yeah, capitalization mismatch between the default DB behavior and your mapping can bite you when you use select *. You may have to use the #result directive to describe all your columns: http://cayenne.apache.org/doc/scripting-sqltemplate.html Since this is a pretty common and annoying problem (and presuming that most users do follow some naming convention in mapping their case-insensitive DB), I wonder if we should add a simple fix - two methods in a SQLTemplate - setUppercaseColumnNames, setLowercaseColumnNames? Anybody has thoughts on that? Or is there some JDBC way to achieve the same with SELECT * queries? Andrus On Jun 5, 2007, at 8:33 AM, Marcin Skladaniec wrote: Hi everyone I'm having some troubles with SQLTemplate. The one I use is fairly simple: SQLTemplate query = new SQLTemplate(Student.class, select * from Student WHERE isDeleted = 1); the student entity is defined by : db-entity name=Student db-attribute name=studentNumber type=BIGINT/ ... some other fields here ... db-attribute name=id type=INTEGER isPrimaryKey=true isMandatory=true/ /db-entity obj-entity name=Student className=ish.oncourse.server.cayenne.Student dbEntityName=Student superClassName=ish.oncourse.server.cayenne.glue.CayenneDataObject qualifier![CDATA[(isDeleted = null) or (isDeleted = 0)]]/ qualifier obj-attribute name=studentNumber type=java.lang.Long db- attribute-path=studentNumber/ ... some other fields here ... obj-attribute name=id type=java.lang.Integer db-attribute- path=id/ /obj-entity When the query is performed an exception is raised: [java] org.apache.cayenne.CayenneRuntimeException: [v.$ {project.version} ${project.build.date} ${project.build.time}] Null value for 'id'. Snapshot: [EMAIL PROTECTED] {STUDENTNUMBER=5, (Other fields in here, all in upper case), ID=241}, version=-9223372036854775761, replaces=-9223372036854775808]. Prefix: null [java] at org.apache.cayenne.access.ObjectResolver.createObjectId (ObjectResolver.java:280) [java] at org.apache.cayenne.access.ObjectResolver.objectFromDataRow (ObjectResolver.java:206) [java] at org.apache.cayenne.access.ObjectResolver.objectsFromDataRows (ObjectResolver.java:120) [java] at org.apache.cayenne.access.ObjectResolver.synchronizedObjectsFromDataRo ws(ObjectResolver.java:100) [java] at org.apache.cayenne.access.DataDomainQueryAction.interceptObjectConvers ion(DataDomainQueryAction.java:433) [java] at org.apache.cayenne.access.DataDomainQueryAction.execute (DataDomainQueryAction.java:124) [java] at org.apache.cayenne.access.DataDomain.onQuery (DataDomain.java:722) [java] at org.apache.cayenne.intercept.DataChannelCallbackInterceptor.onQuery (DataChannelCallbackInterceptor.java:74) [java] at org.apache.cayenne.util.ObjectContextQueryAction.runQuery (ObjectContextQueryAction.java:282) [java] at org.apache.cayenne.access.DataContextQueryAction.execute (DataContextQueryAction.java:59) [java] at org.apache.cayenne.access.DataContext.onQuery (DataContext.java:1321) [java] at org.apache.cayenne.access.DataContext.performQuery(DataContext.java: 1310) [java] at org.apache.cayenne.intercept.ObjectContextDecorator.performQuery (ObjectContextDecorator.java:98) [java] at ish.oncourse.server.services.DataPopulationService.runService (DataPopulationService.java:688) [java] at ish.oncourse.server.services.Service.run (Service.java:174) [java] at java.lang.Thread.run(Thread.java:613) What is wrong ? Why when all my field properties are set to lowercase (like id) the SQLTemplate returns a DataRow with only capital letters ? I have to use the SQLTemplate since my model defines a qualifier qualifier![CDATA[(isDeleted = null) or (isDeleted = 0)]]/ qualifier and I actually want to fetch the records with isDeleted=1. I tried different ways to waive the constraint on the data like: ObjEntity studentEntity = new ObjEntity (ish.oncourse.server.cayenne.Student); Expression exp = studentEntity.getDeclaredQualifier(); studentEntity.setDeclaredQualifier(null); SelectQuery selectQuery = new SelectQuery(studentEntity); studentEntity.setDeclaredQualifier(exp); but nothing worked. Did someone achieve it ? Thanks Marcin -- ish http://www.ish.com.au Level 1, 30 Wilson Street Newtown 2042 Australia phone +61 2 9550 5001 fax +61 2 9550 4001
Re: performing count
So where do we put it then? QueryUtils? Andrus On Jun 5, 2007, at 4:31 PM, Michael Gentry wrote: I don't see a reason to dump it into DataObjectUtils since we don't have to. :-) I was thinking about something in CayenneDataObject, but that doesn't seem quite right, either for the same reasoning (although might be more convenient on users). As to not having a fetch method in a query class, I'm fine with that. I was asking for opinions, after all. Thanks, /dev/mrg On 6/4/07, Andrus Adamchik [EMAIL PROTECTED] wrote: On Jun 4, 2007, at 5:06 PM, Michael Gentry wrote: Putting it in DataObjectUtils doesn't seem the right place to me. Using your example: DataObjectUtils.objectForQuery(...) returns a DataObject (which makes sense to me, being packaged in DataObjectUtils). Something that returns an int, which can't even be converted into a DataObject, doesn't feel like it should be in DataObjectUtils. I agree that DataObjectUtils becoming a kitchen sink is bad, and DataObjectUtils name is a bit obsolete anyways, considering that Persistent is the interface Cayenne stack is dealing with. So DataObjectUtils class itself needs some redesign (split QueryUtils out of it or something?) My other point about not adding fetch methods to the query classes is still valid though. So we can either push for DataObjectUtils redesign now, or use it as a kitchen sink one more time :-) Andrus
Re: Select Query on Table with no Primary Key
Tore is right - for Cayenne to handle an object (whether read-only on read/write), it needs to know which column or columns uniquely identify each row. Now... you can fake a PK in your model, even if there's none in the db - just select a really unique combination of columns, and mark those columns as the PK in the modeler. I've mapped tables with such imaginary PK a lot. If it is not possible (i.e. duplicate rows are expected to be fetched), you will have to use DataRows. Andrus On Jun 7, 2007, at 1:04 PM, Tore Halset wrote: On Jun 6, 2007, at 16:12 , Dave Merrin wrote: I'm trying to run a SelectQuery on a table with no primary key. Unfortunately it's not working. Can anybody help? I have no control over the database so I can't add in primary keys. As you know the PK are essential not only to update a row, but to make sure a single row maps to a single DataObject in your context. Some database engines do have a unique invisible column. If your database does this, then perhaps you could map that column as your primary key? What database engine are you using? Regards, - Tore.
Re: Select Query on Table with no Primary Key
To give an example - if you have an EMPLOYEE table, you can make an assumption that it is highly unlikely that there are two people with the same name, born on the same date, and working in the same department. On that assumption you can mark these 4 columns as PK in the Modeler: FIRST_NAME, LAST_NAME, DATE_OF_BIRTH, DEPARTMENT_ID. Works well with views or tables (updateable or read-only) on any DB. Andrus On Jun 7, 2007, at 1:29 PM, Andrus Adamchik wrote: Tore is right - for Cayenne to handle an object (whether read-only on read/write), it needs to know which column or columns uniquely identify each row. Now... you can fake a PK in your model, even if there's none in the db - just select a really unique combination of columns, and mark those columns as the PK in the modeler. I've mapped tables with such imaginary PK a lot. If it is not possible (i.e. duplicate rows are expected to be fetched), you will have to use DataRows. Andrus On Jun 7, 2007, at 1:04 PM, Tore Halset wrote: On Jun 6, 2007, at 16:12 , Dave Merrin wrote: I'm trying to run a SelectQuery on a table with no primary key. Unfortunately it's not working. Can anybody help? I have no control over the database so I can't add in primary keys. As you know the PK are essential not only to update a row, but to make sure a single row maps to a single DataObject in your context. Some database engines do have a unique invisible column. If your database does this, then perhaps you could map that column as your primary key? What database engine are you using? Regards, - Tore.
Re: Select Query on Table with no Primary Key
On Jun 8, 2007, at 7:01 AM, Craig L Russell wrote: Just FYI, when JDO reads data from tables without PK, it internally creates a unique id, similar to a generated PK, for the objects that it reads and these ids are discarded when no longer needed. The fact that the mapping is for tables without PK is known by the code that creates the temporary ids. Craig Hi Craig, I can probably implement this in Cayenne in about 30 minutes, as Cayenne has a notion of temporary id (normally used for new uncommitted objects). The problem of course is uniquing. So say if a DB row is fetched from a table via a query, resulting in object A, and then later the same row is navigated to via a relationship from another object, resulting in a second object B, distinct from A. This breaks the fundamental assumption about object identity. So we chose not to go this way. Andrus
Re: Select Query on Table with no Primary Key
I am +0 on this feature. Maybe you are right and the users should have an opportunity to mess up the object graph in this case :-) Would you mind logging a Jira issue? And let's see what other Cayenne developers say on that. Thanks Andrus On Jun 8, 2007, at 10:25 AM, Dave Merrin wrote: Hi Andrus, I had seen this as being a problem but not one that I really cared about. The main functionality I was after was being able to generate classes and have them mapped through to database tables. I've got a fair bit of code using cayenne already which I wanted to use again. It would be good if Cayenne had some options which allowed for no primary keys but made you aware you would lose some functionality. As mentioned before I've got round the problem for this project but next time it might not be so easy. Cheers, Dave Andrus Adamchik wrote: Hi Craig, I can probably implement this in Cayenne in about 30 minutes, as Cayenne has a notion of temporary id (normally used for new uncommitted objects). The problem of course is uniquing. So say if a DB row is fetched from a table via a query, resulting in object A, and then later the same row is navigated to via a relationship from another object, resulting in a second object B, distinct from A. This breaks the fundamental assumption about object identity. So we chose not to go this way. Andrus On Jun 8, 2007, at 7:01 AM, Craig L Russell wrote: Just FYI, when JDO reads data from tables without PK, it internally creates a unique id, similar to a generated PK, for the objects that it reads and these ids are discarded when no longer needed. The fact that the mapping is for tables without PK is known by the code that creates the temporary ids. Craig
Re: SQLTemplate not faulting an object
Just checked this in to 3.0 branch (with Modeler support): https://issues.apache.org/cayenne/browse/CAY-800 so you'll be able to do this for instance: sqlTemplate.setColumnNamesCapitalization (SQLTemplate.UPPERCASE_COLUMN_NAMES) Andrus On Jun 5, 2007, at 2:38 PM, Andrus Adamchik wrote: Yeah, capitalization mismatch between the default DB behavior and your mapping can bite you when you use select *. You may have to use the #result directive to describe all your columns: http://cayenne.apache.org/doc/scripting-sqltemplate.html Since this is a pretty common and annoying problem (and presuming that most users do follow some naming convention in mapping their case-insensitive DB), I wonder if we should add a simple fix - two methods in a SQLTemplate - setUppercaseColumnNames, setLowercaseColumnNames? Anybody has thoughts on that? Or is there some JDBC way to achieve the same with SELECT * queries? Andrus On Jun 5, 2007, at 8:33 AM, Marcin Skladaniec wrote: Hi everyone I'm having some troubles with SQLTemplate. The one I use is fairly simple: SQLTemplate query = new SQLTemplate(Student.class, select * from Student WHERE isDeleted = 1); the student entity is defined by : db-entity name=Student db-attribute name=studentNumber type=BIGINT/ ... some other fields here ... db-attribute name=id type=INTEGER isPrimaryKey=true isMandatory=true/ /db-entity obj-entity name=Student className=ish.oncourse.server.cayenne.Student dbEntityName=Student superClassName=ish.oncourse.server.cayenne.glue.CayenneDataObject qualifier![CDATA[(isDeleted = null) or (isDeleted = 0)]]/ qualifier obj-attribute name=studentNumber type=java.lang.Long db- attribute-path=studentNumber/ ... some other fields here ... obj-attribute name=id type=java.lang.Integer db-attribute- path=id/ /obj-entity When the query is performed an exception is raised: [java] org.apache.cayenne.CayenneRuntimeException: [v.$ {project.version} ${project.build.date} ${project.build.time}] Null value for 'id'. Snapshot: [EMAIL PROTECTED] [values={STUDENTNUMBER=5, (Other fields in here, all in upper case), ID=241}, version=-9223372036854775761, replaces=-9223372036854775808]. Prefix: null [java] at org.apache.cayenne.access.ObjectResolver.createObjectId (ObjectResolver.java:280) [java] at org.apache.cayenne.access.ObjectResolver.objectFromDataRow (ObjectResolver.java:206) [java] at org.apache.cayenne.access.ObjectResolver.objectsFromDataRows (ObjectResolver.java:120) [java] at org.apache.cayenne.access.ObjectResolver.synchronizedObjectsFromDataR ows(ObjectResolver.java:100) [java] at org.apache.cayenne.access.DataDomainQueryAction.interceptObjectConver sion(DataDomainQueryAction.java:433) [java] at org.apache.cayenne.access.DataDomainQueryAction.execute (DataDomainQueryAction.java:124) [java] at org.apache.cayenne.access.DataDomain.onQuery (DataDomain.java:722) [java] at org.apache.cayenne.intercept.DataChannelCallbackInterceptor.onQuery (DataChannelCallbackInterceptor.java:74) [java] at org.apache.cayenne.util.ObjectContextQueryAction.runQuery (ObjectContextQueryAction.java:282) [java] at org.apache.cayenne.access.DataContextQueryAction.execute (DataContextQueryAction.java:59) [java] at org.apache.cayenne.access.DataContext.onQuery (DataContext.java:1321) [java] at org.apache.cayenne.access.DataContext.performQuery (DataContext.java:1310) [java] at org.apache.cayenne.intercept.ObjectContextDecorator.performQuery (ObjectContextDecorator.java:98) [java] at ish.oncourse.server.services.DataPopulationService.runService (DataPopulationService.java:688) [java] at ish.oncourse.server.services.Service.run (Service.java:174) [java] at java.lang.Thread.run(Thread.java:613) What is wrong ? Why when all my field properties are set to lowercase (like id) the SQLTemplate returns a DataRow with only capital letters ? I have to use the SQLTemplate since my model defines a qualifier qualifier![CDATA[(isDeleted = null) or (isDeleted = 0)]]/ qualifier and I actually want to fetch the records with isDeleted=1. I tried different ways to waive the constraint on the data like: ObjEntity studentEntity = new ObjEntity (ish.oncourse.server.cayenne.Student); Expression exp = studentEntity.getDeclaredQualifier(); studentEntity.setDeclaredQualifier(null); SelectQuery selectQuery = new SelectQuery(studentEntity); studentEntity.setDeclaredQualifier(exp); but nothing worked. Did someone achieve it ? Thanks Marcin -- ish http://www.ish.com.au Level 1, 30 Wilson Street Newtown 2042 Australia phone +61 2 9550 5001 fax +61 2 9550 4001
Re: How to set setEndToEndMetrics through Cayenne
Right, I overlooked that aspect. Still I think you can get access to the Oracle connection intercepting the Connection creation in a different place. The trick is to use the following PoolManager constructor in the factory: public PoolManager(ConnectionPoolDataSource, int, int, String, String) and for ConnectionPoolDataSource do something like this: // subclass DriverDataSource to intercept connection creation DriverDataSource driverDS = new DriverDataSource(jdbcDriver, dataSourceUrl) { public Connection getConnection(String userName, String password) throws SQLException { OracleConnection c = super.getConnection(userName, password); c.setEndToEndMetrics(...); return c; } } ConnectionPoolDataSource poolDS = new PoolDataSource(driverDS); Andrus On Jun 12, 2007, at 7:32 PM, Daniel Uribe wrote: Andrus, We are pursuing this idea, but unfortunately it seems that the connection object returned from the wrapped data source (in this case, the wrapped data source is a PoolManager) is a ConnectionWrapper object. I can't find a method in that class to retrieve the native OracleConnection to be able to call the 'setEndToEndMetrics' method on it. Any ideas? Thanks, Daniel Andrus Adamchik wrote: The other day I posted a DataSource customization advice in reply to a different question: http://objectstyle.org/cayenne/lists/cayenne-user/ 2007/06/0039.html This approach (custom DataSourceFactory, that instantiates a DataSource wrapper that in turn would call 'setEndToEndMetrics' on every returned connection) is applicable for your case as well. Andrus P.S. Custom DataSource is a solution to like 80% of the environment integration problems. Probably need to write a detailed article on that under the user guide at http://cayenne.apache.org/doc/ customizing.html On Jun 8, 2007, at 8:43 PM, Srinivas Chinthalapudi wrote: Hi, In our project GLIN we would like to have a debugging mechanism and hence would like to pass user object or userID to be passed into the connection as a parameter, this can be done using the method setEndToEndMetrics in = oracle.jdbc.OracleConnectionWrapper. But I do not find a way in Cayenne's implementation where I can set these metrics into the setEndToEndMetrics method. I appreciate if I get some sort of hint or resolution for the same. -- Thanks Regards Sri The Seven Blunders of the World: * Wealth without work * Pleasure without conscience * Knowledge without character * Commerce without morality * Science without humanity * Worship without sacrifice * Politics without principle -- View this message in context: http://www.nabble.com/How-to-set- setEndToEndMetrics-through-Cayenne-tf3891375.html#a11082191 Sent from the Cayenne - User mailing list archive at Nabble.com.
Re: Wikipedia Cayenne page is gone
Yeah would be nice if somebody following this community, but with an outside view could contribute to make it more encyclopedia style. Andrus On Jun 12, 2007, at 2:39 AM, Aristedes Maniatis wrote: On 06/06/2007, at 8:56 AM, Aristedes Maniatis wrote: I'll have a go at reinstating it and change a few words. I've arranged for the page to be returned, but now they slapped a The neutrality of this article or section is disputed. sticker on the top. Perhaps some other people would like to help improve upon that page, give it a bit more breadth and a less sales pitch style. http://en.wikipedia.org/wiki/Apache_Cayenne Ari -- Aristedes Maniatis phone +61 2 9660 9700 PGP fingerprint 08 57 20 4B 80 69 59 E2 A9 BF 2D 48 C2 20 0C C8
Re: paged query slow when fetching big lists
Hi Marcin, * fetch only Pk columns and create all ObjectIds at once, get rid of the iterating process if possible * use already existing method resolveInterval() to fault the required range of records This strategy was discussed in the May thread with Ari (the one that Michael Gentry mentioned). My vote is +0, meaning that before we make this change, I want to confirm first that it has a visible impact on performance. Could you possibly make such change locally and see if it helps? (Look at SelectQuery.addCustomDbAttribute() to only include PK; if you have problems making this change, ping me via the dev list - I'll try my best to help). If the creation of ObjectId and getting the results from ResultSet cannot be speed up (because it simply has to happen, and it does not depend on the way it is done), the only choice will be to implement some more complex solution using sql LIMIT statement. I'd love to avoid that, as the data you get may as well be different the next time you resolve a page, so you may end up with duplicates or skipped records. If we ever go this way, we'll probably need to make it a user choice (use LIMIT vs. IncrementalFaultList). Andrus On Jun 22, 2007, at 2:35 AM, Marcin Skladaniec wrote: Hi Recently we have found that fetching a list of 100,000 records using ROP with paging and no cache takes a long time, about 50 seconds in our case. We have profiled the cpu usage and the result shows that 99% of time is spent in IncrementalFaultList, within the fillIn() method. The fillIn method works (in my opinion) in a bit strange fashion: it does execute query at once, stores the query result in java.sql.ResultSet, and than iterates through the result either creating the whole DataRow or just ObjectId. If there is a need the DataRows are faulted at the end of the method. From our testing it came up that this bit of code : while (it.hasNextRow()) { elements.add(it.nextObjectId(entity)); } is where all the time is spent. Each iteration in this loop takes about 0.5ms, which multiplied by 100,000 takes almost 50 seconds. nextObjectId method consists of two parts: fetching the next result from ResultSet and creating a ObjectId, but I was unable to check which one takes the most time, anyway I think that this approach is somewhat wrong, since always 99% of the records will be fetched as ObjectId and never faulted, so my ideas to enhance this are: * fetch only Pk columns and create all ObjectIds at once, get rid of the iterating process if possible * use already existing method resolveInterval() to fault the required range of records If the creation of ObjectId and getting the results from ResultSet cannot be speed up (because it simply has to happen, and it does not depend on the way it is done), the only choice will be to implement some more complex solution using sql LIMIT statement. I would like to mention that we are using some DataContext decorators and life-cycle callbacks, but I don't believe those are important factors in this case. Whatever is the solution, i think it is pretty crucial that it will be implemented soon, since the usability of the ROP without fast paging is rather low. With regards Marcin -- ish http://www.ish.com.au Level 1, 30 Wilson Street Newtown 2042 Australia phone +61 2 9550 5001 fax +61 2 9550 4001
Re: Relationships across databases
On Jun 21, 2007, at 6:15 PM, Mike Kienenberger wrote: but there's no reason that Cayenne could not attempt to solve it down the road. +1. I think we can devise a sensible algorithm along the following lines: * Split the qualifier into DB-specific parts * Fetch the root entity with its own qualifier (obtained above) * Add prefetches for all cross-DB relationships. * Iterate through the result list in-memory applying remaining qualifiers, filtering matching objects. This obviously won't scale to very large result sets, but it can still be useful. Jira anyone? Andrus
Re: paged query slow when fetching big lists
Hi Marcin, 1) SelectQuery(Student.class) with page size 10 takes 30-50 seconds. 2) SQLTemplate(Student.class, SELECT #result('id' 'int') from STUDENT) without paging takes 100 sec. 3) SQLTemplate(Student.class, SELECT #result('id' 'int') from STUDENT) with page size 10 takes 5 sec. 4) SQLTemplate(Student.class, SELECT #result('id' 'int') from STUDENT) with page size 10 and fetching row data rows takes 4.5 sec. I see you still didn't use profiler, but the data you provided seems to finally confirm that at least on Derby not fetching all columns does result in significant speedup (#1 vs. #3). So now it is a question of implementing the right algorithm for the IncrementalFaultList. Andrus, you mentioned using addCustomDbAttribute to fetch only part of the data. I tried to use addCustomDbAttribute(id) on client, it resulted in returning the raw dataRows, is there something I can do to fetch faulted objects ? We should encapsulate this logic inside IncrementalFaultList on the server. Our application was designed to use the SelectQuery. If we have to change that and use the SQLTemplate instead, there is a lot of work for us, including: Same thing - the right thing to do is to fix it on the server. Let me try to find a spare minute later tonight and implement id-only fetch. I have some large tables in a MySQL5 so I can test the performance in a slightly different environment. Andrus On Jun 26, 2007, at 9:26 AM, Marcin Skladaniec wrote: Hi I have done some more profiling and testing. executing queries on table with 10 records, directly on server (not on client) gave results as listed below: 1) SelectQuery(Student.class) with page size 10 takes 30-50 seconds. 2) SQLTemplate(Student.class, SELECT #result('id' 'int') from STUDENT) without paging takes 100 sec. 3) SQLTemplate(Student.class, SELECT #result('id' 'int') from STUDENT) with page size 10 takes 5 sec. 4) SQLTemplate(Student.class, SELECT #result('id' 'int') from STUDENT) with page size 10 and fetching row data rows takes 4.5 sec. what more, I found that executing the SQLTemplate does allow to fault the objects (I sometimes discover the simplest things last), so I did try to check how long it takes for the objects to be faulted: 1) first object on every page (except first) 30-200ms, rest = 0ms 2) objects is faulted in 20ms (average) 3) on first page first object faulted in 200ms, rest ~20 ms, on any following page first object faulted in 30-200ms, rest 0ms (interesting that the first page does not seem to be faulted at all) 4) no point testing. Also I did check if the resizing of the ArrayList which is keeping the results does affect the speed, and it does not. (Tried to make the ArrayList initial size = 150,000). My conclusion is that SelectQuery with paging is usable only for fetching less than, say 10,000 records, otherwise the performance is to low. With SQLTemplate the performance is much greater. It applies to both ROP and 'normal' cayenne, since I made those tests on server. Andrus, you mentioned using addCustomDbAttribute to fetch only part of the data. I tried to use addCustomDbAttribute(id) on client, it resulted in returning the raw dataRows, is there something I can do to fetch faulted objects ? Our application was designed to use the SelectQuery. If we have to change that and use the SQLTemplate instead, there is a lot of work for us, including: - dealing with adding and concatenating Expressions to the SQLTemplate (is there an easy way ?) - dealing with declared qualifier (the one set in modeller) - possibly more... i would really like to avoid all of that, so if you have any ideas on how to improve the performance without too much hassle I would really appreciate. Marcin On 25/06/2007, at 8:31 PM, Marcin Skladaniec wrote: Hi Andrus I had not much time to check, but with the fix the 100k records load in 30 instead of 50 seconds. It is some improvement, but not enough. I'll do some more profiling tomorrow and let you know. By the way, we are using netbeans for profiling, the benefit : it is free. I will evaluate the yourkit as we are moving away from netbeans as a development platform. Marcin On 23/06/2007, at 5:38 PM, Andrus Adamchik wrote: Ari, Marcin -- going through the code I noticed one inefficiency - the elements array access is synchronized in 'fillIn' method. Since 'fillIn' is called from constructor, such synchronization is unneeded and only slows things down. I just checked a fixed version to trunk. Could you try it out? Andrus On Jun 23, 2007, at 12:33 AM, Aristedes Maniatis wrote: On 22/06/2007, at 11:10 PM, Michael Gentry wrote: Marcin, this thread might be of interest to you ... http://mail-archives.apache.org/mod_mbox/cayenne-dev/ 200705.mbox/browser Look at the Paging and SQL queries thread on May 25. Yes, this is the same project we are working on. I started some
Re: paged query slow when fetching big lists
Hi Marcin, I have good news (I think). Fetching just id columns inside the IncrementalFaultList indeed speeds things up significantly. I just committed the change to optimize SelectQueries to do just that. Please let me know how does it work for you. Now the profiling details... * I profiled on Derby and MySQL. In both cases fetching a table with 25 columns and 10 rows took between 3-4 seconds (not as long as in your case, but what's important is relative times I guess) * YourKit clearly showed the bottleneck: ~95% of the 'fillIn' method is spent in the driver code, rewinding the result set (i.e. brining the data from db to the client). * After my change the query time went down to 0.2-0.5 second (0.8 if you consider the second query needed to fault the first page). Not bad! * ResultSet reading still remained a bottleneck, but it became faster in absolute terms. And now finally Cayenne-related code (such as DataRow creation) started to show up on the radar (e.g. DataRow constructor taking 3% of the 'fillIn' method time). Andrus On Jun 26, 2007, at 10:55 AM, Marcin Skladaniec wrote: Hi Andrus ! Many thanks for that ! Marcin On 26/06/2007, at 5:39 PM, Andrus Adamchik wrote: Hi Marcin, 1) SelectQuery(Student.class) with page size 10 takes 30-50 seconds. 2) SQLTemplate(Student.class, SELECT #result('id' 'int') from STUDENT) without paging takes 100 sec. 3) SQLTemplate(Student.class, SELECT #result('id' 'int') from STUDENT) with page size 10 takes 5 sec. 4) SQLTemplate(Student.class, SELECT #result('id' 'int') from STUDENT) with page size 10 and fetching row data rows takes 4.5 sec. I see you still didn't use profiler, but the data you provided seems to finally confirm that at least on Derby not fetching all columns does result in significant speedup (#1 vs. #3). So now it is a question of implementing the right algorithm for the IncrementalFaultList. Andrus, you mentioned using addCustomDbAttribute to fetch only part of the data. I tried to use addCustomDbAttribute(id) on client, it resulted in returning the raw dataRows, is there something I can do to fetch faulted objects ? We should encapsulate this logic inside IncrementalFaultList on the server. Our application was designed to use the SelectQuery. If we have to change that and use the SQLTemplate instead, there is a lot of work for us, including: Same thing - the right thing to do is to fix it on the server. Let me try to find a spare minute later tonight and implement id- only fetch. I have some large tables in a MySQL5 so I can test the performance in a slightly different environment. Andrus On Jun 26, 2007, at 9:26 AM, Marcin Skladaniec wrote: Hi I have done some more profiling and testing. executing queries on table with 10 records, directly on server (not on client) gave results as listed below: 1) SelectQuery(Student.class) with page size 10 takes 30-50 seconds. 2) SQLTemplate(Student.class, SELECT #result('id' 'int') from STUDENT) without paging takes 100 sec. 3) SQLTemplate(Student.class, SELECT #result('id' 'int') from STUDENT) with page size 10 takes 5 sec. 4) SQLTemplate(Student.class, SELECT #result('id' 'int') from STUDENT) with page size 10 and fetching row data rows takes 4.5 sec. what more, I found that executing the SQLTemplate does allow to fault the objects (I sometimes discover the simplest things last), so I did try to check how long it takes for the objects to be faulted: 1) first object on every page (except first) 30-200ms, rest = 0ms 2) objects is faulted in 20ms (average) 3) on first page first object faulted in 200ms, rest ~20 ms, on any following page first object faulted in 30-200ms, rest 0ms (interesting that the first page does not seem to be faulted at all) 4) no point testing. Also I did check if the resizing of the ArrayList which is keeping the results does affect the speed, and it does not. (Tried to make the ArrayList initial size = 150,000). My conclusion is that SelectQuery with paging is usable only for fetching less than, say 10,000 records, otherwise the performance is to low. With SQLTemplate the performance is much greater. It applies to both ROP and 'normal' cayenne, since I made those tests on server. Andrus, you mentioned using addCustomDbAttribute to fetch only part of the data. I tried to use addCustomDbAttribute(id) on client, it resulted in returning the raw dataRows, is there something I can do to fetch faulted objects ? Our application was designed to use the SelectQuery. If we have to change that and use the SQLTemplate instead, there is a lot of work for us, including: - dealing with adding and concatenating Expressions to the SQLTemplate (is there an easy way ?) - dealing with declared qualifier (the one set in modeller) - possibly more... i would really like to avoid all of that, so if you have any ideas on how to improve the performance
Re: Exception: No property for arcId
Could you doublecheck the model making sure the 'toDepartmentPrefix' relationship is still mapped? I often get similar errors when I forget to refresh the source tree in Eclipse after changing the mapping in the Modeler. Andrus On Jun 26, 2007, at 5:20 PM, Michael Lepine wrote: Hello all. I am getting the CayenneRuntimeException below when trying to invoke the setToOneTarget on one of my generated classes. The _Req and _DepartmentPrefix classes are generated classes. This same code worked yesterday morning but after some updates to the database and subsequent updates to the model in Cayenne, I'm getting this error now. I searched the archives but didn't see much on why I would be getting this error. Does anyone have an idea why I'm receiving it and how I can fix it? Thanks in advance for any help. Stacktrace: * org.apache.cayenne.CayenneRuntimeException*: [v.2.0.3 May 6 2007] No property for arcId toDepartmentPrefix at org.apache.cayenne.access.ObjectDiff.addDiff(*ObjectDiff.java:228*) at org.apache.cayenne.access.ObjectStore.registerDiff (*ObjectStore.java:207* ) at org.apache.cayenne.access.ObjectStore.recordArcCreated (*ObjectStore.java :132*) at org.apache.cayenne.CayenneDataObject.setToOneTarget(* CayenneDataObject.java:297*) at com.buyspeed.dao.auto._Req.setToDepartmentPrefix(*_Req.java:521*)
Re: 1.2.1: Loosing references to 1 to 1 reference objects
Hmm... nothing obvious comes to mind. If you watch the SQL logs generated by Cayenne, is there an attempt to fetch Specification in step 2? Andrus On Jun 25, 2007, at 5:45 PM, [EMAIL PROTECTED] wrote: Hi, sometimes we are loosing references to one to one reference in Cayennen objects. The database allways have these objects. Datamodell Product has n ProductStateallways ok Product basic data type allways ok Product has a Client sometime not set in Product object Product has a Specification sometime not set in Product object (foreign key constraint in database, reference All products that are not correct have the persistentstate == 4 (MODIFIED) Normally our code work on Product object like this: 0. begin transaction 1. read current ProductState 2. read Specification (Error sometime null) 3. create new ProductState 4. set new ProductState 5. commit The error occurse only if we work with more than 400 objects. It will occure not allways with the same objects. All work will be done in one thread with the same DataContext. Envrionment: using Cayenne 1.2.1 JDK 1.5 OS: Windows/Solaris DB: Oracle JBoss Application Server 4.04 thank's florian
Re: Error when main class is executed
Sorry for the late reply. So do you have a Gallery entity in your mapping? Andrus On Jun 20, 2007, at 12:05 PM, janesh wrote: Hi I followed the tutorial to understand the tool. It went fine till main class is executed after adding artists etc. Following error message appears and looks like a basic configuration issue that I missed. Please find the error message. Exception in thread main java.lang.IllegalArgumentException: Class is not mapped with Cayenne: cayenne.tutorial.Gallery at org.apache.cayenne.access.DataContext.createAndRegisterNewObject (DataContext.java:842) at org.apache.cayenne.access.DataContext.newObject (DataContext.java:826) at cayenne.tutorial.Main.main(Main.java:27) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at com.intellij.rt.execution.application.AppMain.main (AppMain.java:86) Appreciate if you could help me. Thanking you. Best Regards -- Janesh Kodikara, Team Lead-QA BeyondM (Pvt) Ltd. (a hSenid Company) Phone: +94-11-2446623/4 Fax: +94-11-2307579 Web: http://www.hSenidMobile.com Mobilizing your enterprises Disclaimer: This email and any files transmitted with it are confidential and intended solely for the use of the individual or entity to which they are addressed. The content and opinions contained in this email are not necessarily those of hSenid Software International. If you have received this email in error please contact the sender
Re: Self-join
Just to clarify, CAY-732 is a real bug, but it is not a bug with relationships to same entity per se (those resolve just fine). This is a bug specifically related to *prefetching* on such relationships. Andrus On Jun 12, 2007, at 10:33 PM, Mike Kienenberger wrote: Not really sure as I don't use them, but at least one issue with self-joins is solved if you use my outer join patch for 1.2. https://issues.apache.org/cayenne/browse/CAY-732 On 6/12/07, Fredrik Liden [EMAIL PROTECTED] wrote: What is the status of self joins in v. 1.2.3? From the 2 posts I find in the archive seems like some people are using it. The documentation doesn't mention it. Just wondering if it's ok to use or if there are any limitations that discourages it's use? I'm have a set of nodes. I'm guessing the source node will have Source_node_id NULL or 0. And then the target nodes will refer back to the source nodes Node_id. Would it be worth using self joins here or should I just look up the target nodes based on the source nodes using regular queries and not worry about the relations? NODE Node_id (pk) Text Source_node_id (fk) Thanks! Fredrik
Re: Self-join
Or actually ... I take it back :-) The underlying cause is still the inability to build correct joins when traversing a multi-step path qualifier, such as parent.parent = null. This explains why Mike's patch made a difference. Andrus On Jun 27, 2007, at 4:50 PM, Andrus Adamchik wrote: Just to clarify, CAY-732 is a real bug, but it is not a bug with relationships to same entity per se (those resolve just fine). This is a bug specifically related to *prefetching* on such relationships. Andrus On Jun 12, 2007, at 10:33 PM, Mike Kienenberger wrote: Not really sure as I don't use them, but at least one issue with self-joins is solved if you use my outer join patch for 1.2. https://issues.apache.org/cayenne/browse/CAY-732 On 6/12/07, Fredrik Liden [EMAIL PROTECTED] wrote: What is the status of self joins in v. 1.2.3? From the 2 posts I find in the archive seems like some people are using it. The documentation doesn't mention it. Just wondering if it's ok to use or if there are any limitations that discourages it's use? I'm have a set of nodes. I'm guessing the source node will have Source_node_id NULL or 0. And then the target nodes will refer back to the source nodes Node_id. Would it be worth using self joins here or should I just look up the target nodes based on the source nodes using regular queries and not worry about the relations? NODE Node_id (pk) Text Source_node_id (fk) Thanks! Fredrik
Re: AW: paged query slow when fetching big lists
To be fair this depends on the kind of issue and on the user effort to prove to the developers that a given fix is actually going to make things better. Andrus On Jun 28, 2007, at 11:18 AM, Peter Schröder wrote: the speed of fixing things is amaizing... i wish that tapestry would have such a support! -Ursprüngliche Nachricht- Von: Andrus Adamchik [mailto:[EMAIL PROTECTED] Gesendet: Donnerstag, 28. Juni 2007 10:11 An: user@cayenne.apache.org Betreff: Re: paged query slow when fetching big lists Fixed. Now the things are fast on the client as well. Andrus On Jun 28, 2007, at 12:18 AM, Andrus Adamchik wrote: On Jun 27, 2007, at 6:38 AM, Marcin Skladaniec wrote: There is one but: fix does work only for queries executed on server, when I executed the query on (ROP) client, the query takes the same amount of time ! Is it possible that the remote calls are using a different constructor ? or maybe the isFetchingCustomAttributes() returns true for 'remote' SelectQueries, and therefore the constructor works as before ? Doh! Yeah, I found the reason - client wraps paginated SelectQuery in a IncrementalQuery wrapper (needed for server-side caching), and the optimization code inside IncrementalFaultList is hardcoded to look for SelectQuery. I don't have an immediate solution - I have to think about it a bit, and test a few possibilities. But at least we've identified the problem. Andrus
Re: getting started
You don't have to remove the GNU Java, just install Sun Java somewhere and make sure that all the executables from Sun JDK are in the path. I usually do it with the alternatives command. E.g. (assuming Sun JDK is installed under /usr/lib/jvm/jdk1.5.0_10/): alternatives --install /usr/bin/java java /usr/lib/jvm/jdk1.5.0_10/ bin/java 1 alternatives --install /usr/bin/javac javac /usr/lib/jvm/jdk1.5.0_10/ bin/javac 1 alternatives --install /usr/bin/jar jar /usr/lib/jvm/jdk1.5.0_10/bin/ jar 1 alternatives --install /opt/java java-home /usr/lib/jvm/jdk1.5.0_10 1 Haven't used Core 7 yet, but I assume the configuration steps above should work as well. Andrus On Jun 28, 2007, at 1:02 PM, Jack O'Connor wrote: java -version java version 1.5.0 gij (GNU libgcj) version 4.1.2 20070502 (Red Hat 4.1.2-12) Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Do you think I should remove the java package from the fedora software manager, and manually install the JDK? Thanks, Jack Andrus Adamchik wrote: Hi Jack, All this is *very* strange. Are you using JDK that comes with Fedora, or did you install Sun JDK? To check do this: $ java -version I know in the past the open source Java port included with Fedora was unusable (especially with the GUI apps), so Sun Linux JDK must be installed. Andrus On Jun 28, 2007, at 12:33 AM, Jack O'Connor wrote: Then change DB URL to jdbc:mysql://localhost/jackdb (where jackdb is the name of a MySQL DB I have created), and Enter my Username and Password for it. Now, if I click Test..., I get: Error connecting to DB: Invalid authorization specification message form server: Access denied for user 'nobody'@'localhost' (using password: NO) If I continue, and click save, then New Project, the main window is divided into 2 parts as in the tutorial; on the right is the normal default screen as in the tutorial, but on the left is on long line: [EMAIL PROTECTED] [name=UntitledDomain] NB/ each time I go back into ToolsPreferencesLocal DataSources, DB URL has reset to jdbc:mysql://localhost/database, and Username and Password are blank again.
Re: ERROR No property for arcId toXyz...
On Jun 29, 2007, at 8:49 AM, David Norwood wrote: BeanUtils.copyProperties(aDetail, aPlanItem); I suspect this line copes ObjectId from another object, so Cayenne is confused about the nature of the object. Andrus
Re: Cayenne in a Cluster environment ends up in NullPointerException [RESOLVED]
Cool, I was gonna suggest to try a few random things, but sometimes its worth waiting for the issue to resolve itself :-) Andrus On Jul 3, 2007, at 7:08 PM, Eric BIANCHI wrote: Hello list, Cayenne was sending me a NullPointerException in a Cluster because I had 2 differents datacontexts on 2 differents Configurations. I merged my configurations and I end up with only one DataContext with 2 Nodes and 2 Maps. Everything works like a charm now. Regards -- Eric BIANCHI --- [EMAIL PROTECTED] http://www.rodanotech.ch Skype: erbianchi
Re: paged query slow when fetching big lists
3.0 (SVN trunk), which will hopefully be released fairly soon as 3.0M1 Andrus On Jul 5, 2007, at 3:06 PM, Borut Bolčina wrote: Hello, which version includes this corrections? 2.0.3 or 3.0? Thanks, Borut On 26.6.2007 20:32, Andrus Adamchik wrote: Hi Marcin, I have good news (I think). Fetching just id columns inside the IncrementalFaultList indeed speeds things up significantly. I just committed the change to optimize SelectQueries to do just that. Please let me know how does it work for you. Now the profiling details... * I profiled on Derby and MySQL. In both cases fetching a table with 25 columns and 10 rows took between 3-4 seconds (not as long as in your case, but what's important is relative times I guess) * YourKit clearly showed the bottleneck: ~95% of the 'fillIn' method is spent in the driver code, rewinding the result set (i.e. brining the data from db to the client). * After my change the query time went down to 0.2-0.5 second (0.8 if you consider the second query needed to fault the first page). Not bad! * ResultSet reading still remained a bottleneck, but it became faster in absolute terms. And now finally Cayenne-related code (such as DataRow creation) started to show up on the radar (e.g. DataRow constructor taking 3% of the 'fillIn' method time). Andrus On Jun 26, 2007, at 10:55 AM, Marcin Skladaniec wrote: Hi Andrus ! Many thanks for that ! Marcin On 26/06/2007, at 5:39 PM, Andrus Adamchik wrote: Hi Marcin, 1) SelectQuery(Student.class) with page size 10 takes 30-50 seconds. 2) SQLTemplate(Student.class, SELECT #result('id' 'int') from STUDENT) without paging takes 100 sec. 3) SQLTemplate(Student.class, SELECT #result('id' 'int') from STUDENT) with page size 10 takes 5 sec. 4) SQLTemplate(Student.class, SELECT #result('id' 'int') from STUDENT) with page size 10 and fetching row data rows takes 4.5 sec. I see you still didn't use profiler, but the data you provided seems to finally confirm that at least on Derby not fetching all columns does result in significant speedup (#1 vs. #3). So now it is a question of implementing the right algorithm for the IncrementalFaultList. Andrus, you mentioned using addCustomDbAttribute to fetch only part of the data. I tried to use addCustomDbAttribute(id) on client, it resulted in returning the raw dataRows, is there something I can do to fetch faulted objects ? We should encapsulate this logic inside IncrementalFaultList on the server. Our application was designed to use the SelectQuery. If we have to change that and use the SQLTemplate instead, there is a lot of work for us, including: Same thing - the right thing to do is to fix it on the server. Let me try to find a spare minute later tonight and implement id- only fetch. I have some large tables in a MySQL5 so I can test the performance in a slightly different environment. Andrus On Jun 26, 2007, at 9:26 AM, Marcin Skladaniec wrote: Hi I have done some more profiling and testing. executing queries on table with 10 records, directly on server (not on client) gave results as listed below: 1) SelectQuery(Student.class) with page size 10 takes 30-50 seconds. 2) SQLTemplate(Student.class, SELECT #result('id' 'int') from STUDENT) without paging takes 100 sec. 3) SQLTemplate(Student.class, SELECT #result('id' 'int') from STUDENT) with page size 10 takes 5 sec. 4) SQLTemplate(Student.class, SELECT #result('id' 'int') from STUDENT) with page size 10 and fetching row data rows takes 4.5 sec. what more, I found that executing the SQLTemplate does allow to fault the objects (I sometimes discover the simplest things last), so I did try to check how long it takes for the objects to be faulted: 1) first object on every page (except first) 30-200ms, rest = 0ms 2) objects is faulted in 20ms (average) 3) on first page first object faulted in 200ms, rest ~20 ms, on any following page first object faulted in 30-200ms, rest 0ms (interesting that the first page does not seem to be faulted at all) 4) no point testing. Also I did check if the resizing of the ArrayList which is keeping the results does affect the speed, and it does not. (Tried to make the ArrayList initial size = 150,000). My conclusion is that SelectQuery with paging is usable only for fetching less than, say 10,000 records, otherwise the performance is to low. With SQLTemplate the performance is much greater. It applies to both ROP and 'normal' cayenne, since I made those tests on server. Andrus, you mentioned using addCustomDbAttribute to fetch only part of the data. I tried to use addCustomDbAttribute(id) on client, it resulted in returning the raw dataRows, is there something I can do to fetch faulted objects ? Our application was designed to use the SelectQuery. If we have to change that and use the SQLTemplate instead, there is a lot of work for us, including: - dealing with adding
Re: How to create cayenne datamap on the fly
Hi there, Actually Cayenne is one of the few ORM engines where you can define both your metadata, and persistent objects on the fly if you want to. So... 1. While I never tried loading DataMap XML from a remote URL, it should work. Just subclass 'org.objectstyle.cayenne.conf.DefaultConfiguration', overriding 'getMapConfiguration' method to open a remote URL. You may find this page useful when doing that: http://cayenne.apache.org/doc20/customizing-configuration.html 2. Yes, you can totally do that using generic persistent classes: http://cayenne.apache.org/doc20/generic-persistent-class.html The main trick is to access the objects via DataObject interface methods instead of concrete setters and getters. Andrus On Jul 7, 2007, at 1:12 AM, mr.abanjo wrote: Hi all, i'm writing an application that try to be indipendent from the business logic required. The main idea behind this project is to use reflection to create on the fly the bean (CayenneDataObject) that normally i must write for map the databese structure. What i need is: 1) load cayenne data map xml from a URL. Basically this URL point to a servlet that generate it on the fly. Normally this is the configuration in cayenne.xml: map name=datamap-foo location=META-INF/cayenne-datamap- foo.map.xml / whant i need is something like this: map name=datamap-foo location= http://somedomain/cayenne-datamap-foo.map.xml; / is it possible? 2) i need to generate some DataObject on the fly. So i'm thinking to use Reflection. Do you think that is possible? The main idea is that at runtime i don't know the structure of my entity. For example, user can be composed only by name and surname attribute... or... have also address.. and so on. I don't want to create every time the corresponding DataObject. I want to implements an engine that create them on demand. I don't know if this is a right approch on the problem. Maybe cayenne has some API for doing this type of activity. Thanks in advance, for help. D.