From catherine08@example.net Sat Mar 01 09:13:52 2008 Return-Path: <catherine08@example.net> Delivered-To: catherine08@example.net Received: (qmail 72206 invoked from network); 1 Mar 2008 09:13:52 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (83.161.120.155) by minotaur.apache.org with SMTP; 1 Mar 2008 09:13:52 -0000 Received: (qmail 67623 invoked by uid 500); 1 Mar 2008 09:13:47 -0000 Delivered-To: catherine08@example.net Received: (qmail 67417 invoked by uid 500); 1 Mar 2008 09:13:47 -0000 Mailing-List: contact catherine08@example.net; run by ezmlm Precedence: bulk List-Help: <mailto:catherine08@example.net> List-Unsubscribe: <mailto:catherine08@example.net> List-Post: <mailto:catherine08@example.net> List-Id: <user.cayenne.apache.org> Reply-To: catherine08@example.net Delivered-To: mailing list catherine08@example.net Received: (qmail 67407 invoked by uid 99); 1 Mar 2008 09:13:47 -0000 Received: from athena.apache.org (HELO athena.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 01 Mar 2008 01:13:47 -0800 X-ASF-Spam-Status: No, hits=0.1 required=10.0 tests=DNS_FROM_SECURITYSAGE,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: local policy) Received: from [83.161.120.155] (HELO flock1.newmail.ru) (83.161.120.155) by apache.org (qpsmtpd/0.29) with SMTP; Sat, 01 Mar 2008 09:13:12 +0000 Received: (qmail 4798 invoked by alias); 1 Mar 2008 09:13:19 -0000 Message-ID: <catherine08@example.net> From: Razumovsky Andrey <catherine08@example.net> To: catherine08@example.net Subject: Re: State of DataObjects (uncommitted but nonexistent on DB) X-Priority: 3 MIME-Version: 1.0 X-Mailer: DenMail v1.0 by ORC X-Uid: 1958545 X-RemoteIP: 83.161.120.155 Date: Sat, 01 Mar 2008 12:13:19 +0300 In-Reply-To: <catherine08@example.net> Content-type: text/plain; charset="koi8-r" x-dummy: 0 X-Virus-Checked: Checked by ClamAV on apache.org Hi Adrian, If i understood your message right, you're manually changing objects' state to COMMITED. Well, i too think this is not a good idea. What would i do in this cause is to make those still non-existing in DB objects using default constructor, so that they would bÕ TRANSIENT. After that (i think this should be done before calling 'commitChanges', if you don't want to mess with listeners) you should register user-modified objects with Cayenne using 'context.registerNewObject()'. The objects should be registered only if they are TRANSIENT and your-business-logic-modified. Once you do that, their state will change to NEW and they will normally persist. Those objects which are already in DB will normally work since they are COMMITED or MODIFIED. Still, if those objects have relationships you use, this would lead to exceptions during commit, since there is a problem in setting existent objects in relations for transient objects. About this i would write to list in my next question. However, sutuation will be even worse if you have falsely-commited objects, as you suggest. Hope this helps, Andrey > AW> AW> Hello list AW> AW> I have some kind of exotic question concerning state of DataObjects. In a AW> scenario I would like to create new DataObjects but keep them in a state AW> so that they only get committed if the user actively changes some default AW> value. AW> AW> Look at it like some lazy persist functionality. Let's say I have a AW> reporting application (which I have not :) ) where I display a matrix to AW> the user. X-axis are the days, y-axis are the projects. In every field in AW> the matrix the user could write the hours he worked on the said project on AW> the specific day. Which means I need to create DataObjects for all fields AW> in the matrix so that the databinding works and the user can enter values AW> into all of the fields. But I only want to persist those records which AW> actually contain a value. AW> AW> I thought I could do so creating new DataObjects, setting default values AW> and then immediately changing the state of the new DataObjects to AW> committed. While this generally works (DataObject changes to modified AW> once the user enters a value), the persist process of Cayenne is not AW> amused since it thinks it should update a record in the database which AW> does not already exist. AW> AW> So my question. Would there be another possible solution to my problem? AW> AW> Cheers, AW> Adrian AW> From catherine08@example.net Sat Mar 01 09:44:32 2008 Return-Path: <catherine08@example.net> Delivered-To: catherine08@example.net Received: (qmail 80337 invoked from network); 1 Mar 2008 09:44:32 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (83.161.120.155) by minotaur.apache.org with SMTP; 1 Mar 2008 09:44:32 -0000 Received: (qmail 77040 invoked by uid 500); 1 Mar 2008 09:44:27 -0000 Delivered-To: catherine08@example.net Received: (qmail 77025 invoked by uid 500); 1 Mar 2008 09:44:27 -0000 Mailing-List: contact catherine08@example.net; run by ezmlm Precedence: bulk List-Help: <mailto:catherine08@example.net> List-Unsubscribe: <mailto:catherine08@example.net> List-Post: <mailto:catherine08@example.net> List-Id: <user.cayenne.apache.org> Reply-To: catherine08@example.net Delivered-To: mailing list catherine08@example.net Received: (qmail 77016 invoked by uid 99); 1 Mar 2008 09:44:27 -0000 Received: from athena.apache.org (HELO athena.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 01 Mar 2008 01:44:27 -0800 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: local policy) Received: from [83.161.120.155] (HELO vorsha.objectstyle.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with SMTP; Sat, 01 Mar 2008 09:43:53 +0000 Received: (qmail 20102 invoked from network); 1 Mar 2008 09:44:03 -0000 Received: from unknown (HELO ?IPv888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4:1?) (83.161.120.155) by localhost with SMTP; 1 Mar 2008 09:44:03 -0000 Message-Id: <catherine08@example.net> From: Andrus Adamchik <catherine08@example.net> To: catherine08@example.net In-Reply-To: <catherine08@example.net> Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit Mime-Version: 1.0 (Apple Message framework v919.2) Subject: Re: EJBQLQuery and LEFT JOIN FETCH Date: Sat, 1 Mar 2008 11:44:02 +0200 References: <catherine08@example.net> <catherine08@example.net> <catherine08@example.net> X-Mailer: Apple Mail (2.919.2) X-Virus-Checked: Checked by ClamAV on apache.org Hi David, FETCH joins is one of the few features of EJBQL that are not yet supported. Working on it... Now, the error is of course totally confusing (what actually happens is Cayenne trying to treat the fetch join as a regular join). I just committed a small change to this code to simply throw UnsupportedOperationException on fetch joins. At least it makes it clear to the user what's going on. Thanks, Andrus On Feb 29, 2008, at 11:30 PM, David Marko wrote: > I have two tables (Issue and Reply) with 1:N relationship. I'm > trying to construct EJBQL query that would load issues and prefetch > replies. I tried this query: new EJBQLQuery("select a FROM Issue a > LEFT JOIN FETCH a.replyArray") > > .. but it throws error as below. Am I doing something wrong? > > David > > INFO - *** error. > java.lang.NullPointerException: Null entityId > at > org.apache.cayenne.access.jdbc.EJBQLTableId.<init>(EJBQLTableId.java: > 66) > at > org.apache.cayenne.access.jdbc.EJBQLTableId.<init>(EJBQLTableId.java: > 56) > at > org > .apache > .cayenne > .access > .jdbc.EJBQLFromTranslator.visitOuterJoin(EJBQLFromTranslator.java:91) > at > org > .apache > .cayenne > .access > .jdbc > .EJBQLFromTranslator.visitOuterFetchJoin(EJBQLFromTranslator.java:86) > at > org > .apache > .cayenne > .ejbql.parser.EJBQLOuterFetchJoin.visitNode(EJBQLOuterFetchJoin.java: > 35) > at org.apache.cayenne.ejbql.parser.SimpleNode.visit(SimpleNode.java: > 60) > at > org > .apache.cayenne.ejbql.parser.SimpleNode.visitChild(SimpleNode.java:84) > at > org.apache.cayenne.ejbql.parser.EJBQLFrom.visitChild(EJBQLFrom.java: > 40) > at org.apache.cayenne.ejbql.parser.SimpleNode.visit(SimpleNode.java: > 64) > at > org > .apache > .cayenne > .access > .jdbc.EJBQLSelectTranslator.visitFrom(EJBQLSelectTranslator.java:68) > at > org.apache.cayenne.ejbql.parser.EJBQLFrom.visitNode(EJBQLFrom.java:35) > at org.apache.cayenne.ejbql.parser.SimpleNode.visit(SimpleNode.java: > 60) > at > org > .apache.cayenne.ejbql.parser.SimpleNode.visitChild(SimpleNode.java:84) > at org.apache.cayenne.ejbql.parser.SimpleNode.visit(SimpleNode.java: > 64) > at org.apache.cayenne.access.jdbc.EJBQLAction > $1.visitSelect(EJBQLAction.java:73) > at > org > .apache.cayenne.ejbql.parser.EJBQLSelect.visitNode(EJBQLSelect.java: > 35) > at org.apache.cayenne.ejbql.parser.SimpleNode.visit(SimpleNode.java: > 60) > at > org > .apache > .cayenne.access.jdbc.EJBQLAction.performAction(EJBQLAction.java:67) > at > org > .apache > .cayenne > .access.DataNodeQueryAction.runQuery(DataNodeQueryAction.java:58) > at org.apache.cayenne.access.DataNode.performQueries(DataNode.java: > 230) > at > org > .apache > .cayenne > .access.DataDomainQueryAction.runQuery(DataDomainQueryAction.java:442) > at org.apache.cayenne.access.DataDomainQueryAction.access > $000(DataDomainQueryAction.java:67) > at org.apache.cayenne.access.DataDomainQueryAction > $2.transform(DataDomainQueryAction.java:415) > at > org > .apache.cayenne.access.DataDomain.runInTransaction(DataDomain.java: > 847) > at > org > .apache > .cayenne > .access > .DataDomainQueryAction > .runQueryInTransaction(DataDomainQueryAction.java:412) > at > org > .apache > .cayenne > .access.DataDomainQueryAction.execute(DataDomainQueryAction.java:119) > at org.apache.cayenne.access.DataDomain.onQuery(DataDomain.java:740) > at > org > .apache > .cayenne > .util > .ObjectContextQueryAction.runQuery(ObjectContextQueryAction.java:296) > at > org > .apache > .cayenne > .util.ObjectContextQueryAction.execute(ObjectContextQueryAction.java: > 84) > at org.apache.cayenne.access.DataContext.onQuery(DataContext.java: > 1331) > at > org.apache.cayenne.access.DataContext.performQuery(DataContext.java: > 1320) > at com.tcldig.citi_projects.setup.EjbTest1.main(EjbTest1.java:28) > From catherine08@example.net Sat Mar 01 09:55:47 2008 Return-Path: <catherine08@example.net> Delivered-To: catherine08@example.net Received: (qmail 81721 invoked from network); 1 Mar 2008 09:55:47 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (83.161.120.155) by minotaur.apache.org with SMTP; 1 Mar 2008 09:55:47 -0000 Received: (qmail 82647 invoked by uid 500); 1 Mar 2008 09:55:42 -0000 Delivered-To: catherine08@example.net Received: (qmail 82634 invoked by uid 500); 1 Mar 2008 09:55:42 -0000 Mailing-List: contact catherine08@example.net; run by ezmlm Precedence: bulk List-Help: <mailto:catherine08@example.net> List-Unsubscribe: <mailto:catherine08@example.net> List-Post: <mailto:catherine08@example.net> List-Id: <user.cayenne.apache.org> Reply-To: catherine08@example.net Delivered-To: mailing list catherine08@example.net Received: (qmail 82624 invoked by uid 99); 1 Mar 2008 09:55:42 -0000 Received: from athena.apache.org (HELO athena.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 01 Mar 2008 01:55:42 -0800 X-ASF-Spam-Status: No, hits=0.1 required=10.0 tests=DNS_FROM_SECURITYSAGE,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: local policy) Received: from [83.161.120.155] (HELO flock1.newmail.ru) (83.161.120.155) by apache.org (qpsmtpd/0.29) with SMTP; Sat, 01 Mar 2008 09:55:08 +0000 Received: (qmail 12686 invoked by alias); 1 Mar 2008 09:55:15 -0000 Message-ID: <catherine08@example.net> From: Razumovsky Andrey <catherine08@example.net> To: catherine08@example.net Subject: Expressions & objects state X-Priority: 3 MIME-Version: 1.0 X-Mailer: DenMail v1.0 by ORC X-Uid: 1958545 X-RemoteIP: 83.161.120.155 Date: Sat, 01 Mar 2008 12:55:15 +0300 Content-type: text/plain; charset="koi8-r" x-dummy: 0 X-Virus-Checked: Checked by ClamAV on apache.org Hi all, these are actually two separate questions. First is about expressions. Suppose i have two entities, A and B. A has pk 'aid' and fk (non-mandatory) 'bid'. B has pk 'bid'. I want to build two separate expressions for A like those (1) 'aid=1' and (2) 'bid=2'. Since 'aid' and 'bid' are not properties of A class, statements like this: Expression.fromString("aid=1") results in exception. With 'bid' the sutiation is event harder, because while i write something like 'b.bid=2', b relation target might event not exist. I know i can do this using 'db:' prefix, but this is not a solution for me, because i'm using ROP and 'db:' do not work on client since DBEntities are not being sent through hessian. So how i can create such queries (note than i prefer using SelectQuery, because there might be other qualifiers in my expression)?? Other thing i discovered about expresions is they are type-dependent, so that if 'count' is integer property, Expression.fromString("count='1'").match(...) (note quotes here!) will never work because it will search for string 'count' property. This is no good because all databases i know support such automatic type conversion. So SelectQuery will work ok, but simple match() will not. Reading comments in 'ASTEqual', 'ASTLess' and other, i saw i'm not the first to ask this. But i think this is quite easy to implement (at least converting from String to Number), so i'd ask for this feature. ========== Second, about state of objects. I create new transient object 'A' and then set some EXISTING relation target of B class: //b is persistent in db and fetched using SelectQuery or something else A a = new A(); a.setB(b); The reason i do this is somewhat like the previuos question in the list. I need to persist objects only when user presses 'Save', not when my data object is created. So, when i do this, several things occur. First, 'b' state is changed to MODIFIED since relationship affects both sides. But note that 'b' now refers to unexisting and non-'NEW' object. Second, a's temp id is added to ObjectContextStateLog's dirtyIds! So right now these functions will definitely crash in NPE: -context.commitChanges() -context.newObjects, since temp id presents in dirtyIds but node is not registered in GraphManager. In my local version of cayenne i managed to do some workaround by changing ObjectContextStateLog and ObjectContextChangeLog so that they will not mark dirty anything while working with transient objects. However, probably context.registerObject(a) will not work correctly, but i don't need that, instead i create 'new' object and fill it with 'transient' one properties: A a2 = (A)context.newObject(A.class); a2.setB(a.getB()) context.commitChanges(). This works fine for me, but i think something must be done around collapsing 'transient' and 'in-scope' (registered) objects. Thanks, Andrey) From catherine08@example.net Sat Mar 01 11:05:18 2008 Return-Path: <catherine08@example.net> Delivered-To: catherine08@example.net Received: (qmail 95896 invoked from network); 1 Mar 2008 11:05:18 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (83.161.120.155) by minotaur.apache.org with SMTP; 1 Mar 2008 11:05:18 -0000 Received: (qmail 11610 invoked by uid 500); 1 Mar 2008 11:05:12 -0000 Delivered-To: catherine08@example.net Received: (qmail 11596 invoked by uid 500); 1 Mar 2008 11:05:12 -0000 Mailing-List: contact catherine08@example.net; run by ezmlm Precedence: bulk List-Help: <mailto:catherine08@example.net> List-Unsubscribe: <mailto:catherine08@example.net> List-Post: <mailto:catherine08@example.net> List-Id: <user.cayenne.apache.org> Reply-To: catherine08@example.net Delivered-To: mailing list catherine08@example.net Received: (qmail 11587 invoked by uid 99); 1 Mar 2008 11:05:12 -0000 Received: from athena.apache.org (HELO athena.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 01 Mar 2008 03:05:12 -0800 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: local policy) Received: from [83.161.120.155] (HELO vorsha.objectstyle.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with SMTP; Sat, 01 Mar 2008 11:04:38 +0000 Received: (qmail 12462 invoked from network); 1 Mar 2008 11:04:47 -0000 Received: from unknown (HELO ?IPv888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4:1?) (83.161.120.155) by localhost with SMTP; 1 Mar 2008 11:04:47 -0000 Message-Id: <catherine08@example.net> From: Andrus Adamchik <catherine08@example.net> To: catherine08@example.net In-Reply-To: <catherine08@example.net> Content-Type: text/plain; charset=UTF-8; format=flowed; delsp=yes Content-Transfer-Encoding: quoted-printable Mime-Version: 1.0 (Apple Message framework v919.2) Subject: Re: State of DataObjects (uncommitted but nonexistent on DB) X-Priority: 3 Date: Sat, 1 Mar 2008 13:04:46 +0200 References: <catherine08@example.net> X-Mailer: Apple Mail (2.919.2) X-Virus-Checked: Checked by ClamAV on apache.org Andrey, This is a correct assessment of the situation: (1) setting persistence =20= state manually is very likely to confuse Cayenne and (2) transient =20 objects can't have relationships. Another way around it is to create =20 NEW objects, and delete them before commit: MyObject o =3D context.newObject(MyObject.class); ... for(Object o : context.newObjects()) { if(somecondition) { context.deleteObject((Persistent) o); } } context.commitChanges(); Andrus On Mar 1, 2008, at 11:13 AM, Razumovsky Andrey wrote: > Hi Adrian, > > If i understood your message right, you're manually changing =20 > objects' state to COMMITED. Well, i too think this is not a good idea. > What would i do in this cause is to make those still non-existing in =20= > DB objects using default constructor, so that they would b=D1=83 =20 > TRANSIENT. After that (i think this should be done before calling =20 > 'commitChanges', if you don't want to mess with listeners) you =20 > should register user-modified objects with Cayenne using =20 > 'context.registerNewObject()'. The objects should be registered only =20= > if they are TRANSIENT and your-business-logic-modified. Once you do =20= > that, their state will change to NEW and they will normally persist. =20= > Those objects which are already in DB will normally work since they =20= > are COMMITED or MODIFIED. > Still, if those objects have relationships you use, this would lead =20= > to exceptions during commit, since there is a problem in setting =20 > existent objects in relations for transient objects. About this i =20 > would write to list in my next question. However, sutuation will be =20= > even worse if you have falsely-commited objects, as you suggest. > Hope this helps, > Andrey > >> > AW> > AW> Hello list > AW> > AW> I have some kind of exotic question concerning state of =20 > DataObjects. In a > AW> scenario I would like to create new DataObjects but keep them in =20= > a state > AW> so that they only get committed if the user actively changes =20 > some default > AW> value. > AW> > AW> Look at it like some lazy persist functionality. Let's say I =20 > have a > AW> reporting application (which I have not :) ) where I display a =20 > matrix to > AW> the user. X-axis are the days, y-axis are the projects. In every =20= > field in > AW> the matrix the user could write the hours he worked on the said =20= > project on > AW> the specific day. Which means I need to create DataObjects for =20 > all fields > AW> in the matrix so that the databinding works and the user can =20 > enter values > AW> into all of the fields. But I only want to persist those records =20= > which > AW> actually contain a value. > AW> > AW> I thought I could do so creating new DataObjects, setting =20 > default values > AW> and then immediately changing the state of the new DataObjects to > AW> committed. While this generally works (DataObject changes to =20 > modified > AW> once the user enters a value), the persist process of Cayenne is =20= > not > AW> amused since it thinks it should update a record in the database =20= > which > AW> does not already exist. > AW> > AW> So my question. Would there be another possible solution to my =20 > problem? > AW> > AW> Cheers, > AW> Adrian > AW> > From catherine08@example.net Sat Mar 01 11:28:03 2008 Return-Path: <catherine08@example.net> Delivered-To: catherine08@example.net Received: (qmail 721 invoked from network); 1 Mar 2008 11:28:03 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (83.161.120.155) by minotaur.apache.org with SMTP; 1 Mar 2008 11:28:03 -0000 Received: (qmail 31993 invoked by uid 500); 1 Mar 2008 11:27:58 -0000 Delivered-To: catherine08@example.net Received: (qmail 31984 invoked by uid 500); 1 Mar 2008 11:27:58 -0000 Mailing-List: contact catherine08@example.net; run by ezmlm Precedence: bulk List-Help: <mailto:catherine08@example.net> List-Unsubscribe: <mailto:catherine08@example.net> List-Post: <mailto:catherine08@example.net> List-Id: <user.cayenne.apache.org> Reply-To: catherine08@example.net Delivered-To: mailing list catherine08@example.net Received: (qmail 31975 invoked by uid 99); 1 Mar 2008 11:27:58 -0000 Received: from athena.apache.org (HELO athena.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 01 Mar 2008 03:27:58 -0800 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: local policy) Received: from [83.161.120.155] (HELO vorsha.objectstyle.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with SMTP; Sat, 01 Mar 2008 11:27:24 +0000 Received: (qmail 18187 invoked from network); 1 Mar 2008 11:27:33 -0000 Received: from unknown (HELO ?IPv888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4:1?) (83.161.120.155) by localhost with SMTP; 1 Mar 2008 11:27:33 -0000 Message-Id: <catherine08@example.net> From: Andrus Adamchik <catherine08@example.net> To: catherine08@example.net In-Reply-To: <catherine08@example.net> Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit Mime-Version: 1.0 (Apple Message framework v919.2) Subject: Re: Expressions & objects state X-Priority: 3 Date: Sat, 1 Mar 2008 13:27:32 +0200 References: <catherine08@example.net> X-Mailer: Apple Mail (2.919.2) X-Virus-Checked: Checked by ClamAV on apache.org On Mar 1, 2008, at 11:55 AM, Razumovsky Andrey wrote: > First is about expressions. Suppose i have two entities, A and B. A > has pk 'aid' and fk (non-mandatory) 'bid'. B has pk 'bid'. > I want to build two separate expressions for A like those (1) > 'aid=1' and (2) 'bid=2'. Since 'aid' and 'bid' are not properties of > A class, statements like this: > Expression.fromString("aid=1") results in exception. With 'bid' the > sutiation is event harder, because while i write something like > 'b.bid=2', b relation target might event not exist. > I know i can do this using 'db:' prefix, but this is not a solution > for me, because i'm using ROP and 'db:' do not work on client since > DBEntities are not being sent through hessian. > So how i can create such queries (note than i prefer using > SelectQuery, because there might be other qualifiers in my > expression)?? The whole point of hiding PK/FK is to remove references to them from the code, and operate in object property terms. I don't see any reason to break this paradigm in your case. To find objects by PK, you can use ObjectIdQuery: http://cayenne.apache.org/doc/objectidquery.html to find objects by FK you can match against a relationship target object ObjectId: ExpressionFactory.matchExp("relationshipName", new ObjectId("TargetEntity", "pk", 2); > Other thing i discovered about expresions is they are type- > dependent, so that if 'count' is integer property, > Expression.fromString("count='1'").match(...) (note quotes here!) > will never work because it will search for string 'count' property. > This is no good because all databases i know support such automatic > type conversion. So SelectQuery will work ok, but simple match() > will not. > Reading comments in 'ASTEqual', 'ASTLess' and other, i saw i'm not > the first to ask this. But i think this is quite easy to implement > (at least converting from String to Number), so i'd ask for this > feature. I am +1 on adding type converters. Especially if there are volunteers to help us with it ;-) One may argue whether "1" equals 1, but it is worse than that. Long(1) is not equal to Integer(1) according to the current comparison algorithm, which is much more confusing. As a side note, "reflect" package already has a non-public type converter class. We may want to extend this to Expressions. > ========== > Second, about state of objects. > I create new transient object 'A' and then set some EXISTING > relation target of B class: > > //b is persistent in db and fetched using SelectQuery or something > else > A a = new A(); > a.setB(b); > > The reason i do this is somewhat like the previuos question in the > list. I need to persist objects only when user presses 'Save', not > when my data object is created. > > So, when i do this, several things occur. First, 'b' state is > changed to MODIFIED since relationship affects both sides. But note > that 'b' now refers to unexisting and non-'NEW' object. Second, a's > temp id is added to ObjectContextStateLog's dirtyIds! > So right now these functions will definitely crash in NPE: > -context.commitChanges() > -context.newObjects, > since temp id presents in dirtyIds but node is not registered in > GraphManager. > > In my local version of cayenne i managed to do some workaround by > changing ObjectContextStateLog and ObjectContextChangeLog so that > they will not mark dirty anything while working with transient > objects. However, probably context.registerObject(a) will not work > correctly, but i don't need that, instead i create 'new' object and > fill it with 'transient' one properties: > A a2 = (A)context.newObject(A.class); > a2.setB(a.getB()) > context.commitChanges(). > > This works fine for me, but i think something must be done around > collapsing 'transient' and 'in-scope' (registered) objects. That's how Cayenne works... context.newObject(A.class) is always preferrable to A a = new A(); We are going to implement relationships between transient objects, but relationships between transient and persistent objects simply don't make sense... From the object graph maintenance perspective, the solution that I suggested in reply to the "State of DataObjects" thread is actually more cleaner than a hypothetical solution that would mix transient and persistent objects in a single graph. Andrus From catherine08@example.net Sat Mar 01 11:53:13 2008 Return-Path: <catherine08@example.net> Delivered-To: catherine08@example.net Received: (qmail 3718 invoked from network); 1 Mar 2008 11:53:13 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (83.161.120.155) by minotaur.apache.org with SMTP; 1 Mar 2008 11:53:13 -0000 Received: (qmail 44121 invoked by uid 500); 1 Mar 2008 11:53:08 -0000 Delivered-To: catherine08@example.net Received: (qmail 44102 invoked by uid 500); 1 Mar 2008 11:53:08 -0000 Mailing-List: contact catherine08@example.net; run by ezmlm Precedence: bulk List-Help: <mailto:catherine08@example.net> List-Unsubscribe: <mailto:catherine08@example.net> List-Post: <mailto:catherine08@example.net> List-Id: <user.cayenne.apache.org> Reply-To: catherine08@example.net Delivered-To: mailing list catherine08@example.net Received: (qmail 44093 invoked by uid 99); 1 Mar 2008 11:53:08 -0000 Received: from athena.apache.org (HELO athena.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 01 Mar 2008 03:53:08 -0800 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: local policy) Received: from [83.161.120.155] (HELO vorsha.objectstyle.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with SMTP; Sat, 01 Mar 2008 11:52:34 +0000 Received: (qmail 21477 invoked from network); 1 Mar 2008 11:52:44 -0000 Received: from unknown (HELO ?IPv888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4:1?) (83.161.120.155) by localhost with SMTP; 1 Mar 2008 11:52:44 -0000 Message-Id: <catherine08@example.net> From: Andrus Adamchik <catherine08@example.net> To: catherine08@example.net In-Reply-To: <catherine08@example.net> Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit Mime-Version: 1.0 (Apple Message framework v919.2) Subject: Re: Expressions & objects state X-Priority: 3 Date: Sat, 1 Mar 2008 13:52:42 +0200 References: <catherine08@example.net> <catherine08@example.net> X-Mailer: Apple Mail (2.919.2) X-Virus-Checked: Checked by ClamAV on apache.org On Mar 1, 2008, at 1:27 PM, Andrus Adamchik wrote: >> I know i can do this using 'db:' prefix, but this is not a solution >> for me, because i'm using ROP and 'db:' do not work on client since >> DBEntities are not being sent through hessian. So how i can create >> such queries (note than i prefer using SelectQuery, because there >> might be other qualifiers in my expression)?? I'd say other qualifiers won't do much if you a matching on a PK (except for excluding an object that matched a PK, but not some other condition, which you can do in memory too)... Still if you want to use a SelectQuery, you can still do it. While there are no DbEntities on the client, "db:xyz" expressions can still be created and passed to the server. This should work with ROP. Andrus From catherine08@example.net Sat Mar 01 17:31:29 2008 Return-Path: <catherine08@example.net> Delivered-To: catherine08@example.net Received: (qmail 65863 invoked from network); 1 Mar 2008 17:31:29 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (83.161.120.155) by minotaur.apache.org with SMTP; 1 Mar 2008 17:31:29 -0000 Received: (qmail 29196 invoked by uid 500); 1 Mar 2008 17:31:24 -0000 Delivered-To: catherine08@example.net Received: (qmail 29186 invoked by uid 500); 1 Mar 2008 17:31:24 -0000 Mailing-List: contact catherine08@example.net; run by ezmlm Precedence: bulk List-Help: <mailto:catherine08@example.net> List-Unsubscribe: <mailto:catherine08@example.net> List-Post: <mailto:catherine08@example.net> List-Id: <user.cayenne.apache.org> Reply-To: catherine08@example.net Delivered-To: mailing list catherine08@example.net Received: (qmail 29175 invoked by uid 99); 1 Mar 2008 17:31:24 -0000 Received: from athena.apache.org (HELO athena.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 01 Mar 2008 09:31:24 -0800 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: local policy) Received: from [83.161.120.155] (HELO vorsha.objectstyle.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with SMTP; Sat, 01 Mar 2008 17:30:49 +0000 Received: (qmail 27793 invoked from network); 1 Mar 2008 17:30:59 -0000 Received: from unknown (HELO ?IPv888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4:1?) (83.161.120.155) by localhost with SMTP; 1 Mar 2008 17:30:59 -0000 Message-Id: <catherine08@example.net> From: Andrus Adamchik <catherine08@example.net> To: catherine08@example.net In-Reply-To: <catherine08@example.net> Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit Mime-Version: 1.0 (Apple Message framework v919.2) Subject: Re: ROP listener semantics Date: Sat, 1 Mar 2008 19:30:52 +0200 References: <catherine08@example.net> <catherine08@example.net> X-Mailer: Apple Mail (2.919.2) X-Virus-Checked: Checked by ClamAV on apache.org On Feb 26, 2008, at 8:20 PM, Andrus Adamchik wrote: >> Moreover, any modifications made at the server >> level will be reflected back in the client? > > This is actually a separate issue from callbacks/listeners. And we > need to fix it .. badly... The object diff exchange protocol > supports sending server-side changes back to the client (and in fact > we are using that - for generated primary keys), but we also need to > capture and send back the changes that happened to objects as a > result of callbacks. IMO this is a major task that we'd rather do > sooner than later. I just implemented this on SVN trunk per CAY-789. I'd appreciate if somebody could test it in production and report how it works. To make things easier for those not setup to build Cayenne, here are the fresh server and client binaries: http://people.apache.org/~aadamchik/nightly/03012008/ Andrus From catherine08@example.net Sun Mar 02 17:26:13 2008 Return-Path: <catherine08@example.net> Delivered-To: catherine08@example.net Received: (qmail 5888 invoked from network); 2 Mar 2008 17:26:13 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (83.161.120.155) by minotaur.apache.org with SMTP; 2 Mar 2008 17:26:13 -0000 Received: (qmail 44264 invoked by uid 500); 2 Mar 2008 17:26:08 -0000 Delivered-To: catherine08@example.net Received: (qmail 44257 invoked by uid 500); 2 Mar 2008 17:26:08 -0000 Mailing-List: contact catherine08@example.net; run by ezmlm Precedence: bulk List-Help: <mailto:catherine08@example.net> List-Unsubscribe: <mailto:catherine08@example.net> List-Post: <mailto:catherine08@example.net> List-Id: <user.cayenne.apache.org> Reply-To: catherine08@example.net Delivered-To: mailing list catherine08@example.net Received: (qmail 44248 invoked by uid 99); 2 Mar 2008 17:26:08 -0000 Received: from nike.apache.org (HELO nike.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 02 Mar 2008 09:26:08 -0800 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of catherine08@example.net designates 83.161.120.155 as permitted sender) Received: from [83.161.120.155] (HELO opera.etc.to) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 02 Mar 2008 17:25:20 +0000 Received: from localhost (localhost [83.161.120.155]) by opera.etc.to (Postfix) with ESMTP id 89453C7D8D for <catherine08@example.net>; Sun, 2 Mar 2008 17:55:49 +0100 (CET) X-Virus-Scanned: catherine08@example.net Received: from opera.etc.to ([83.161.120.155]) by localhost (opera.etc.to [83.161.120.155]) (amavisd-new, port 10024) with ESMTP id MgvbFqwRofIw for <catherine08@example.net>; Sun, 2 Mar 2008 17:55:46 +0100 (CET) Received: from [83.161.120.155] (home.etc.to [83.161.120.155]) by opera.etc.to (Postfix) with ESMTP id 1889CC7D8A for <catherine08@example.net>; Sun, 2 Mar 2008 17:55:46 +0100 (CET) Subject: Big list'o questions..... From: Frits Jalvingh <catherine08@example.net> Reply-To: catherine08@example.net To: catherine08@example.net Content-Type: text/plain Date: Sun, 02 Mar 2008 18:25:37 +0100 Message-Id: <1204478737.14703.6.camel@monceau> Mime-Version: 1.0 X-Mailer: Evolution 2.12.1 Content-Transfer-Encoding: 7bit X-Virus-Checked: Checked by ClamAV on apache.org Hello there, I am evaluating Cayenne for use in a new project. I have read the documentation and experimented a bit but I'm left with a few questions. I hope I can get some answers here ;-) 1. When Cayenne accesses the database, are PreparedStatements used (and cached) within a single DataContext? That is: if code causes 100x the same SQL to be generated and executed (select xxx from yyy where id=?) is this prepare once, cached and only executed multiple time or is it fully created every time? 2. When Cayenne executes updates does it update the entire record or does it only update the fields that changed? If it's the latter case: can it be disabled to always update the full record (to allow for statement caching - if available)? 3. The documentation states that when you call rollbackChanges() a transaction the DataContext state is restored to the state it had before. Does it do this by using "copies" of the objects it has read or is the database re-queried? 4. What happens if data gets commited to the database and a SQLException occurs (like "duplicate key", "null in non-null column" etc? Specifically: 4.a Is the state of the DataContext once such an error occurs still usable? 4.b Are the values of a persistent object in that DataContext changed during the commit or rolled back to some earlier state? 4.c Would it be possible to "fix" the values on just the objects that "failed" in the same context and commit again? 5. When using "nested" DataContext, if you commit to the "upper" DataContext I expect that the changes are only propagated to the Object Store in that upper context, not to the database. Is that correct? 6. The current implementation uses generated base classes to contain Cayenne-specific code. JPA implementations need something like bytecode-generation (proxies) to add code to persistent classes as JPA-defined classes need no platform-specific base class. So I assume that the JPA variant of Cayenne will have something like that. Are there plans to extend this to the Cayenne-specific interface? I would not want to use JPA because it sucks bigtime, but having clean classes is a wish. 7. The project is currently busy supporting the JPA standard. Is it the vision of this project to become a JPA provider mainly and deprecate the own interfaces? If Cayenne would become a JPA implementation only it would not be the correct choice for my project since that standard is a lousy one. 8. If I would select Cayenne for my project I would need to add some features to it. The reason is that I will access an already-existing legacy database with lots of oddities like triggers and stuff. Specifically: a. I would need to add an alternative version of "Optimistic locking" where a specific field in the database would hold a timestamp or version number. This number should be maintained by Cayenne i.e. incremented as soon as Cayenne inserts/updates the record. It would also be used in the where for updates/deletes exactly like the current optimistic locking mechanism to check for changes at that time. This also has another consequence (8.c) b. I would need support for database-generated fields at update and insert time. I must be able to mark fields as "generated at update, generated at insert or both". Cayenne should retrieve these fields after inserting/updating a record to keep the Object representation in-sync with the database. For some databases this would require a "select after update"; other databases (Oracle, Postgresql) can return the changed fields in the same statement (insert xxxx returning yyy). This also requires 8.c: c. Both these changes require that all generated fields get copied and stored within a database commit so that the original values (before the commit) can be restored when flushing data to the database fails; this is needed to keep the DataContext consistent after a commit failure. Are these extensions doable without rewriting the entire implementation;-)? Would these changes be acceptable to be incorporated in Cayenne? Lots of questions,I know.. I hope someone can find some time to help me by answering them!!! Thanks in advance for your time, Frits Jalvingh From catherine08@example.net Sun Mar 02 19:11:45 2008 Return-Path: <catherine08@example.net> Delivered-To: catherine08@example.net Received: (qmail 33651 invoked from network); 2 Mar 2008 19:11:45 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (83.161.120.155) by minotaur.apache.org with SMTP; 2 Mar 2008 19:11:45 -0000 Received: (qmail 88040 invoked by uid 500); 2 Mar 2008 19:11:40 -0000 Delivered-To: catherine08@example.net Received: (qmail 88026 invoked by uid 500); 2 Mar 2008 19:11:40 -0000 Mailing-List: contact catherine08@example.net; run by ezmlm Precedence: bulk List-Help: <mailto:catherine08@example.net> List-Unsubscribe: <mailto:catherine08@example.net> List-Post: <mailto:catherine08@example.net> List-Id: <user.cayenne.apache.org> Reply-To: catherine08@example.net Delivered-To: mailing list catherine08@example.net Received: (qmail 88014 invoked by uid 99); 2 Mar 2008 19:11:40 -0000 Received: from athena.apache.org (HELO athena.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 02 Mar 2008 11:11:40 -0800 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: local policy) Received: from [83.161.120.155] (HELO vorsha.objectstyle.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with SMTP; Sun, 02 Mar 2008 19:11:05 +0000 Received: (qmail 12543 invoked from network); 2 Mar 2008 19:11:14 -0000 Received: from unknown (HELO ?IPv888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4:1?) (83.161.120.155) by localhost with SMTP; 2 Mar 2008 19:11:14 -0000 Message-Id: <catherine08@example.net> From: Andrus Adamchik <catherine08@example.net> To: catherine08@example.net In-Reply-To: <1204478737.14703.6.camel@monceau> Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit Mime-Version: 1.0 (Apple Message framework v919.2) Subject: Re: Big list'o questions..... Date: Sun, 2 Mar 2008 21:11:13 +0200 References: <1204478737.14703.6.camel@monceau> X-Mailer: Apple Mail (2.919.2) X-Virus-Checked: Checked by ClamAV on apache.org On Mar 2, 2008, at 7:25 PM, Frits Jalvingh wrote: > > 1. When Cayenne accesses the database, are PreparedStatements used > (and > cached) within a single DataContext? That is: if code causes 100x the > same SQL to be generated and executed (select xxx from yyy where > id=?) > is this prepare once, cached and only executed multiple time or is it > fully created every time? PreparedStatement caching can be configured outside Cayenne at the DataSource level. Cayenne by itself doesn't do PreparedStatement caching and doesn't care about it. > 2. When Cayenne executes updates does it update the entire record or > does it only update the fields that changed? If it's the latter case: > can it be disabled to always update the full record (to allow > for statement caching - if available)? The later. This is not configurable in Cayenne. I strongly suspect that PreparedStatement caching is never a bottleneck in the case of update (and in any event, if we issue a set of different UPDATE queries for each entity, each variation can be cached just as well). If somebody can prove me wrong with some profiling data, we can reconsider the update approach. > 3. The documentation states that when you call rollbackChanges() a > transaction the DataContext state is restored to the state it had > before. Does it do this by using "copies" of the objects it has read > or is the database re-queried? Rollback is a local operation. No DB access is performed. > 4. What happens if data gets commited to the database and a > SQLException > occurs (like "duplicate key", "null in non-null column" etc? > Specifically: > 4.a Is the state of the DataContext once such an error occurs still > usable? Yes. > 4.b Are the values of a persistent object in that DataContext changed > during the commit or rolled back to some earlier state? No, but the user has a choice to do that if he wants. > 4.c Would it be possible to "fix" the values on just the objects that > "failed" in the same context and commit again? Yes. > 5. When using "nested" DataContext, if you commit to the "upper" > DataContext I expect that the changes are only propagated to the > Object > Store in that upper context, not to the database. Is that correct? It can be done both ways. 'commitChangesToParent' vs. 'commitChanges'. > 6. The current implementation uses generated base classes to contain > Cayenne-specific code. JPA implementations need something like > bytecode-generation (proxies) to add code to persistent classes > as JPA-defined classes need no platform-specific base class. So I > assume > that the JPA variant of Cayenne will have something like that. Yes. > Are there > plans to extend this to the Cayenne-specific interface? > I would not want to use JPA because it sucks bigtime, but having clean > classes is a wish. (enhanced) POJO without JPA is in the plans (and partially works already). But this is not a high priority. > 7. The project is currently busy supporting the JPA standard. Is it > the > vision of this project to become a JPA provider mainly and deprecate > the > own interfaces? No, absolutely no plans to deprecate Cayenne API. The goal is to keep both API's on top of the same (existing) Cayenne stack as first class citizens. > 8. If I would select Cayenne for my project I would need to add some > features to it. The reason is that I will access an already-existing > legacy database with lots of oddities like triggers and stuff. > Specifically: > a. I would need to add an alternative version of "Optimistic locking" > where a specific field in the database would hold a timestamp or > version > number. This number should be maintained by Cayenne i.e. incremented > as > soon as Cayenne inserts/updates the record. It would also be used in > the > where for updates/deletes exactly like the current optimistic locking > mechanism to check for changes at that time. We are implementing an auto-incrementing version as a part of JPA alignment. So this is coming. > b. I would need support for database-generated fields at update and > insert time. I must be able to mark fields as "generated at update, > generated at insert or both". Cayenne should retrieve these fields > after inserting/updating a record to keep the Object representation > in-sync with the database. For some databases this would require a > "select after update"; You can achieve that with JPA-like lifecycle callbacks (that are available in Cayenne outside JPA) - POST_UPDATE, POST_PERSIST. > other databases (Oracle, Postgresql) can return > the changed fields in the same statement (insert xxxx returning yyy). Hmm... does it get passed over JDBC back to the client, and if so, do you have a JDBC example? (I know that even the standard callback via 'Statement.getGeneratedKeys()' still doesn't work with many drivers). > c. Both these changes require that all generated fields get copied and > stored within a database commit so that the original values (before > the > commit) can be restored when flushing data to the database fails; this > is needed to keep the DataContext consistent after a commit failure. As far as restoring the DataContext state, Cayenne should be able to that. Andrus From catherine08@example.net Sun Mar 02 19:53:09 2008 Return-Path: <catherine08@example.net> Delivered-To: catherine08@example.net Received: (qmail 46052 invoked from network); 2 Mar 2008 19:53:09 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (83.161.120.155) by minotaur.apache.org with SMTP; 2 Mar 2008 19:53:09 -0000 Received: (qmail 13984 invoked by uid 500); 2 Mar 2008 19:53:05 -0000 Delivered-To: catherine08@example.net Received: (qmail 13744 invoked by uid 500); 2 Mar 2008 19:53:04 -0000 Mailing-List: contact catherine08@example.net; run by ezmlm Precedence: bulk List-Help: <mailto:catherine08@example.net> List-Unsubscribe: <mailto:catherine08@example.net> List-Post: <mailto:catherine08@example.net> List-Id: <user.cayenne.apache.org> Reply-To: catherine08@example.net Delivered-To: mailing list catherine08@example.net Received: (qmail 13735 invoked by uid 99); 2 Mar 2008 19:53:04 -0000 Received: from athena.apache.org (HELO athena.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 02 Mar 2008 11:53:04 -0800 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: local policy) Received: from [83.161.120.155] (HELO vorsha.objectstyle.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with SMTP; Sun, 02 Mar 2008 19:52:30 +0000 Received: (qmail 19961 invoked from network); 2 Mar 2008 19:52:39 -0000 Received: from unknown (HELO ?IPv888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4:1?) (83.161.120.155) by localhost with SMTP; 2 Mar 2008 19:52:39 -0000 Message-Id: <catherine08@example.net> From: Andrus Adamchik <catherine08@example.net> To: catherine08@example.net In-Reply-To: <catherine08@example.net> Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit Mime-Version: 1.0 (Apple Message framework v919.2) Subject: Re: Big list'o questions..... Date: Sun, 2 Mar 2008 21:52:38 +0200 References: <1204478737.14703.6.camel@monceau> <catherine08@example.net> X-Mailer: Apple Mail (2.919.2) X-Virus-Checked: Checked by ClamAV on apache.org On Mar 2, 2008, at 9:11 PM, Andrus Adamchik wrote: >> >> 3. The documentation states that when you call rollbackChanges() a >> transaction the DataContext state is restored to the state it had >> before. Does it do this by using "copies" of the objects it has read >> or is the database re-queried? > > Rollback is a local operation. No DB access is performed. This requires a bit of explanation. While rollback operation does not perform any DB queries, modified objects are turned into "hollow" objects. I.e. they will be re-read from the DB lazily on the first access... Now, with DataDomain object snapshot caching underneath the DataContext, this still means no DB access in most cases. Still some internal Cayenne activity will happen to restore the state. Andrus From catherine08@example.net Sun Mar 02 23:37:49 2008 Return-Path: <catherine08@example.net> Delivered-To: catherine08@example.net Received: (qmail 29880 invoked from network); 2 Mar 2008 23:37:49 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (83.161.120.155) by minotaur.apache.org with SMTP; 2 Mar 2008 23:37:49 -0000 Received: (qmail 37576 invoked by uid 500); 2 Mar 2008 23:37:44 -0000 Delivered-To: catherine08@example.net Received: (qmail 37335 invoked by uid 500); 2 Mar 2008 23:37:44 -0000 Mailing-List: contact catherine08@example.net; run by ezmlm Precedence: bulk List-Help: <mailto:catherine08@example.net> List-Unsubscribe: <mailto:catherine08@example.net> List-Post: <mailto:catherine08@example.net> List-Id: <user.cayenne.apache.org> Reply-To: catherine08@example.net Delivered-To: mailing list catherine08@example.net Received: (qmail 37326 invoked by uid 99); 2 Mar 2008 23:37:44 -0000 Received: from nike.apache.org (HELO nike.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 02 Mar 2008 15:37:44 -0800 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of catherine08@example.net designates 83.161.120.155 as permitted sender) Received: from [83.161.120.155] (HELO opera.etc.to) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 02 Mar 2008 23:36:56 +0000 Received: from localhost (localhost [83.161.120.155]) by opera.etc.to (Postfix) with ESMTP id 47330C7DA3 for <catherine08@example.net>; Mon, 3 Mar 2008 00:07:21 +0100 (CET) X-Virus-Scanned: catherine08@example.net Received: from opera.etc.to ([83.161.120.155]) by localhost (opera.etc.to [83.161.120.155]) (amavisd-new, port 10024) with ESMTP id 9U+fyjwdlycw for <catherine08@example.net>; Mon, 3 Mar 2008 00:07:18 +0100 (CET) Received: from [83.161.120.155] (home.etc.to [83.161.120.155]) by opera.etc.to (Postfix) with ESMTP id 1AC76C7D7D for <catherine08@example.net>; Mon, 3 Mar 2008 00:07:18 +0100 (CET) Subject: Re: Big list'o questions..... From: Frits Jalvingh <catherine08@example.net> Reply-To: catherine08@example.net To: catherine08@example.net In-Reply-To: <catherine08@example.net> References: <1204478737.14703.6.camel@monceau> <catherine08@example.net> Content-Type: text/plain Date: Mon, 03 Mar 2008 00:37:12 +0100 Message-Id: <1204501032.14703.73.camel@monceau> Mime-Version: 1.0 X-Mailer: Evolution 2.12.1 Content-Transfer-Encoding: 7bit X-Virus-Checked: Checked by ClamAV on apache.org Hi Andrus, Thanks for your swift reply!!! > PreparedStatement caching can be configured outside Cayenne at the > DataSource level. Cayenne by itself doesn't do PreparedStatement > caching and doesn't care about it. Check. > > > 2. When Cayenne executes updates does it update the entire record or > > does it only update the fields that changed? If it's the latter case: > > can it be disabled to always update the full record (to allow > > for statement caching - if available)? > > The later. This is not configurable in Cayenne. I strongly suspect > that PreparedStatement caching is never a bottleneck in the case of > update (and in any event, if we issue a set of different UPDATE > queries for each entity, each variation can be cached just as well). > If somebody can prove me wrong with some profiling data, we can > reconsider the update approach. Ok. It will be a bottleneck though for tasks doing lots of repetitive work: preparing a statement in Oracle easily takes 100x (!!) as much time as executing it. And sending lots of different statements to the DataSource's cache does not work- it caches only some of them to prevent open cursor troubles so if you send it too many it does not work. Finally, sending lots of statements to Oracle means the database's SQL cache (SGA) which holds the database's cached execution plans will loose efficiency. This will add up to quite large costs when the application is used by many people. This means I would not use Cayenne for any kind of work that handles large amounts of objects; something that is not advisable anyway for the current generation of ORM's. If I decide to go with Cayenne I'll do some database profiling. > > 3. The documentation states that when you call rollbackChanges() a > > transaction the DataContext state is restored to the state it had > > before. Does it do this by using "copies" of the objects it has read > > or is the database re-queried? > > Rollback is a local operation. No DB access is performed. > This requires a bit of explanation. While rollback operation does not > perform any DB queries, modified objects are turned into "hollow" > objects. I.e. they will be re-read from the DB lazily on the first > access... Now, with DataDomain object snapshot caching underneath > the DataContext, this still means no DB access in most cases. > Still some internal Cayenne activity will happen to restore the state. Crystal clear ;-) This means you have no "previous" state in memory to restore the objects to pristine state? > > > 4. What happens if data gets commited to the database and a > > SQLException > > occurs (like "duplicate key", "null in non-null column" etc? > > Specifically: > > 4.a Is the state of the DataContext once such an error occurs still > > usable? > > Yes. That's great!! > > > 4.b Are the values of a persistent object in that DataContext changed > > during the commit or rolled back to some earlier state? > > No, but the user has a choice to do that if he wants. > > > 4.c Would it be possible to "fix" the values on just the objects that > > "failed" in the same context and commit again? > > Yes. That looks just great! Way better than Hibernate which completely buggers it's internal state after an exception. This makes it hell to code for proper error handling in the UI. > > > 5. When using "nested" DataContext, if you commit to the "upper" > > DataContext I expect that the changes are only propagated to the > > Object > > Store in that upper context, not to the database. Is that correct? > > It can be done both ways. 'commitChangesToParent' vs. 'commitChanges'. Ok. Just to be clear: would commitChanges() commit all of the changes including the changes of all parents into the database? Or does it only commit the changes in the child context to the DB and updates the parent context? > > > 6. The current implementation uses generated base classes to contain > > Cayenne-specific code. JPA implementations need something like > > bytecode-generation (proxies) to add code to persistent classes > > as JPA-defined classes need no platform-specific base class. So I > > assume > > that the JPA variant of Cayenne will have something like that. > > Yes. > > > Are there > > plans to extend this to the Cayenne-specific interface? > > I would not want to use JPA because it sucks bigtime, but having clean > > classes is a wish. > > (enhanced) POJO without JPA is in the plans (and partially works > already). But this is not a high priority. Check. > > > 7. The project is currently busy supporting the JPA standard. Is it > > the > > vision of this project to become a JPA provider mainly and deprecate > > the > > own interfaces? > > No, absolutely no plans to deprecate Cayenne API. The goal is to keep > both API's on top of the same (existing) Cayenne stack as first class > citizens. Ah, good. > > > 8. If I would select Cayenne for my project I would need to add some > > features to it. The reason is that I will access an already-existing > > legacy database with lots of oddities like triggers and stuff. > > Specifically: > > a. I would need to add an alternative version of "Optimistic locking" > > where a specific field in the database would hold a timestamp or > > version > > number. This number should be maintained by Cayenne i.e. incremented > > as > > soon as Cayenne inserts/updates the record. It would also be used in > > the > > where for updates/deletes exactly like the current optimistic locking > > mechanism to check for changes at that time. > > We are implementing an auto-incrementing version as a part of JPA > alignment. So this is coming. > > > b. I would need support for database-generated fields at update and > > insert time. I must be able to mark fields as "generated at update, > > generated at insert or both". Cayenne should retrieve these fields > > after inserting/updating a record to keep the Object representation > > in-sync with the database. For some databases this would require a >
{'source': 'Apache Software Foundation Public Mail Archives'}