Re: Get PK value of a previously generated object

From: mr.abanjo (mr.abanj..mail.com)
Date: Wed Aug 11 2010 - 10:20:14 UTC

  • Next message: Laurent Marchal: "Velocity parsing error with "##""

    Hi all,
    i found the problem.
    It was my fault!
    In datamap i miss to declare that the PK generation strategy is
    "Database-Generated".
    Now also with "DataObjectUtils.pkForObject" i receive the value for PK.
    Thanks for support and sorry for time you missed!
    :-)
    Davide

    On Wed, Aug 11, 2010 at 11:36 AM, mr.abanjo <mr.abanj..mail.com> wrote:

    > Hi Andrus,
    > i don't use the modeler for generate class and xml file.
    > I tried it and after "Reenginer database schema" of the database ( with the
    > FK on the two table ) i run the script that import the data.
    > ...but i receive another error:
    >
    > INFO QueryLogger: *** error.
    > org.apache.cayenne.CayenneRuntimeException: [v.2.0.4 October 8 2007] Can't
    > extract a master key. Missing key (id), master ID (<ObjectId:Transitlines,
    > id=null>)
    > at
    > org.apache.cayenne.access.DataDomainSyncBucket$PropagatedValueFactory.create(DataDomainSyncBucket.java:209)
    > at org.apache.cayenne.query.BatchQuery.getValue(BatchQuery.java:220)
    > at
    > org.apache.cayenne.query.InsertBatchQuery.getValue(InsertBatchQuery.java:61)
    > at
    > org.apache.cayenne.access.trans.InsertBatchQueryBuilder.getParameterValues(InsertBatchQueryBuilder.java:82)
    > at
    > org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(BatchAction.java:182)
    > at
    > org.apache.cayenne.access.jdbc.BatchAction.performAction(BatchAction.java:81)
    > 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:810)
    > at org.apache.cayenne.access.DataDomain$2.transform(DataDomain.java:781)
    > at
    > org.apache.cayenne.access.DataDomain.runInTransaction(DataDomain.java:836)
    > at org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:778)
    > at
    > org.apache.cayenne.access.DataContext.flushToParent(DataContext.java:1234)
    > at
    > org.apache.cayenne.access.DataContext.commitChanges(DataContext.java:1138)
    >
    > So it is correct that the key id is empty.. i never setted it. I put only
    > the "main" object as attribute of the "child" with this code:
    >
    > public void setToTMainObject(MainObject toMainObject) {
    > setToOneTarget("toMainObject", toMainObject, true);
    > }
    >
    > and the configuration in xml datamap is:
    >
    > <db-relationship name="toMainObject" source="ChildObject"
    > target="MainObject" toMany="false">
    > <db-attribute-pair source="mainid" target="id"/>
    > </db-relationship>
    > <obj-relationship name="toMainObject" source="ChildObject"
    > target="MainObject" deleteRule="Nullify"
    > db-relationship-path="toMainObject"/>
    >
    >
    > I really don't know witch is the problem.
    > You have any suggest?
    > Thanks!
    > Davide
    >
    >
    > On Tue, Aug 10, 2010 at 1:47 PM, Andrus Adamchik <andru..bjectstyle.org>wrote:
    >
    >> Are there any warnings in the Modeler when you save the project?
    >>
    >> Andrus
    >>
    >>
    >> On Aug 10, 2010, at 2:37 PM, mr.abanjo wrote:
    >>
    >> Hi,
    >>> in the meanwhile i tried to map the relation between the two objects, but
    >>> when i commit i receive this error:
    >>>
    >>> Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0,
    >>> Size: 0
    >>> at java.util.ArrayList.RangeCheck(Unknown Source)
    >>> at java.util.ArrayList.get(Unknown Source)
    >>> at java.util.Collections$UnmodifiableList.get(Unknown Source)
    >>> at
    >>>
    >>> org.apache.cayenne.map.ObjRelationship.isToDependentEntity(ObjRelationship.java:259)
    >>> at
    >>>
    >>> org.apache.cayenne.map.ObjRelationship.isSourceIndependentFromTargetChange(ObjRelationship.java:252)
    >>> at
    >>>
    >>> org.apache.cayenne.CayenneDataObject.validateForSave(CayenneDataObject.java:587)
    >>> at
    >>>
    >>> org.apache.cayenne.CayenneDataObject.validateForInsert(CayenneDataObject.java:658)
    >>> at
    >>>
    >>> org.apache.cayenne.access.ObjectStoreGraphDiff.validateAndCheckNoop(ObjectStoreGraphDiff.java:100)
    >>> at
    >>>
    >>> org.apache.cayenne.access.DataContext.flushToParent(DataContext.java:1217)
    >>> at
    >>>
    >>> org.apache.cayenne.access.DataContext.commitChanges(DataContext.java:1138)
    >>>
    >>> I think that the error is located at this line:
    >>>
    >>> public boolean isToDependentEntity() {
    >>> return ((DbRelationship)
    >>> getDbRelationships().get(0)).isToDependentPK();
    >>> }
    >>>
    >>> ..seems that cayenne don't know the relation but i've configured it in a
    >>> datamap:
    >>>
    >>> <db-relationship name="relationname" source="ChildDBEntity"
    >>> target="MainDBEntity" toMany="false">
    >>> <db-attribute-pair source="mainid" target="id"/>
    >>> </db-relationship>
    >>> <obj-relationship name="relationname" source="ChildOBJEntity"
    >>> target="MainOBJEntity" deleteRule="Nullify"
    >>> db-relationship-path="relationname"/>
    >>>
    >>> Thanks for any support.
    >>>
    >>> Davide
    >>>
    >>>
    >>>
    >>> On Tue, Aug 10, 2010 at 10:46 AM, mr.abanjo <mr.abanj..mail.com> wrote:
    >>>
    >>> Hi Mike,
    >>>> if i understand correctly i must configure in cayenne datamap xml file
    >>>> the
    >>>> relation between the two objects, and than declare an attribute in the
    >>>> main
    >>>> object that contains the "child".
    >>>> I know that this is the best way ( if i want to model a database the
    >>>> relations must be declared ) but why with the DataObjectUtils i don't
    >>>> receive the value?
    >>>> There is something i do in a wrong way?
    >>>>
    >>>> Thanks
    >>>> Davide
    >>>>
    >>>> P.S. I wrote this code in a wrong way in my previous email :
    >>>>
    >>>> DataContext...registerNewObject(MainObject);
    >>>>
    >>>> Obviously the "MainObject" is the isntance and not the class :-)
    >>>>
    >>>>
    >>>>
    >>>>
    >>>> On Mon, Aug 9, 2010 at 6:18 PM, Mike Kienenberger <mkienen..mail.com
    >>>> >wrote:
    >>>>
    >>>> It's actually much easier than that.
    >>>>>
    >>>>>
    >>>>> // Create main object
    >>>>> // Create child object
    >>>>>
    >>>>> mainObj.setChild(childObj);
    >>>>>
    >>>>> This will automatically set the correct PK and FK values.
    >>>>>
    >>>>> You can also commit both changes at the same time rather than
    >>>>> separately.
    >>>>>
    >>>>> On Mon, Aug 9, 2010 at 12:11 PM, mr.abanjo <mr.abanj..mail.com>
    >>>>> wrote:
    >>>>>
    >>>>>> Hi,
    >>>>>> my application need to generate a "parent" object and then create a
    >>>>>>
    >>>>> "child"
    >>>>>
    >>>>>> object that contains the PK value of the parent.
    >>>>>> I'm using MySQL and the colum "id" is "autoincrement". ( both tables )
    >>>>>>
    >>>>>> So first i create the main object (it extends DataObject ):
    >>>>>>
    >>>>>> MainObject mainObj = new MainObject();
    >>>>>> //setting properties... without id.. it's generated by mysql
    >>>>>> mainObj.set......
    >>>>>> ....
    >>>>>> ...
    >>>>>> DataContext...registerNewObject(MainObject);
    >>>>>> DataContext...commitChanges();
    >>>>>>
    >>>>>> The record is succesfully inserted in the database!
    >>>>>>
    >>>>>> Then i need to get the PK... in this case a single column ( Long ).
    >>>>>>
    >>>>>> If i insepct the corresponding filed it is empty, so i see in the
    >>>>>> documentation that there are two ways to perform this task:
    >>>>>> http://cayenne.apache.org/doc30/accessing-pk-and-fk-values.html
    >>>>>> public Long getMainObjectId() {
    >>>>>> return (getObjectId() != null && !getObjectId().isTemporary()) ?
    >>>>>> (Long)
    >>>>>> getObjectId().getIdSnapshot().get(ID) : null;
    >>>>>> }
    >>>>>>
    >>>>>> http://cayenne.apache.org/doc30/dataobjectutils.html
    >>>>>> long myId = (Long)DataObjectUtils.pkForObject(MainObject);
    >>>>>>
    >>>>>>
    >>>>>> but, with both techniques the value returned is "null"!
    >>>>>>
    >>>>>> What is wrong?
    >>>>>>
    >>>>>> Thansk for support.
    >>>>>>
    >>>>>> Davide
    >>>>>>
    >>>>>>
    >>>>>
    >>>>
    >>>>
    >>
    >



    This archive was generated by hypermail 2.0.0 : Wed Aug 11 2010 - 10:20:53 UTC