Re: Get PK value of a previously generated object

From: mr.abanjo (mr.abanj..mail.com)
Date: Wed Aug 11 2010 - 09:36:02 UTC

  • Next message: mr.abanjo: "Re: Get PK value of a previously generated object"

    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 - 09:36:35 UTC