Kodo 3.3.3, InverseManager, 1:1 Relation

Hi,
I am evaluating Kodo at the moment and have a problem with the inverse
manager. I have a class 'BaseClassPC' which has a reference to a class
'ReferencedClassPC'. It is a simple 1:1 bidirectional relation, so in
the table for class 'BaseclassPC' I have a column
'REFERENCEDCLASS_JDOID' which points to the JDOID of the referenced
class. I have no foreign key back from REFERENCEDCLASS to BASECLASS.
Now, when I want to set the association between the two objects in my
code this only works when I call baseclass.setReferencedClass(...). When
I try to do it the other way round (referencedclass.setBaseclass(..)) I
get an exception on commit, even though I set kodo.InverseManager=true
in my kodo.properties. The error only occurs when I create both objects
and set the reference within one transaction. Excerpt from the stacktrace:
NestedThrowablesStackTrace:
kodo.util.FatalUserException: Attempt to set column
"BASECLASSPC.REFERENCEDCLASS_JDOID" to two different values:
(null)"null", (class java.lang.Long)"251" This can occur when you fail
to set both sides of a two-sided relation between objects, or when you
map different fields to the same column, but you do not keep the values
of these fields in synch.
     at kodo.jdbc.sql.PrimaryRow.setObject(PrimaryRow.java:215)
     at kodo.jdbc.sql.RowImpl.flushJoinValues(RowImpl.java:267)
     at kodo.jdbc.sql.RowImpl.flushForeignKey(RowImpl.java:189)
     at kodo.jdbc.sql.RowImpl.setForeignKey(RowImpl.java:158)
     at kodo.jdbc.sql.PrimaryRow.setForeignKey(PrimaryRow.java:128)
The doku for the inverse manager says 'Under this setting, Kodo detects
changes to either side of a bidirectional relation, and automatically
sets the other side appropriately on flush.' So I was expecting that it
does not matter on which side I set the relation, nor that I have to set
the relation in two separate transactions, am I wrong?
Here is the sample code, executed in a single transaction:
BaseclassPC base = new BaseclassPC();
ReferencedClassPC ref = new ReferencedClassPC();
//base.setRefClass(ref); <-- works
ref.setSubclass(base); <-- fails
getPersistenceManager().makePersistent(base);
getPersistenceManager().makePersistent(ref);
BTW: It does not matter in which order I make the calls to
makePersistent(...).
Thanks very much,
Jochen

Hi Stephen,
shame on me, I really forgot the put this attribute, sorry that I
bothered you. Another question about the inverse manager: Are there any
limitations that I have to take into account when mapping my classes?
E.g. I read somewhere in this forum that the IM does not work for
horizontal mappings. Background is that I want to switch from another
JDO vendor to Kodo, because the other vendor's implementation of inverse
management was damn buggy, and I want to make sure to have reliable
inverse management this time ;)
Thanks,
Jochen
Stephen Kim wrote:
Did you set the inverse-owner attribute? Kodo will only manasge
inverses which are marked as inverse relations.
Jochen Kressin wrote:
Hi,
I am evaluating Kodo at the moment and have a problem with the inverse
manager. I have a class 'BaseClassPC' which has a reference to a class
'ReferencedClassPC'. It is a simple 1:1 bidirectional relation, so in
the table for class 'BaseclassPC' I have a column
'REFERENCEDCLASS_JDOID' which points to the JDOID of the referenced
class. I have no foreign key back from REFERENCEDCLASS to BASECLASS.
Now, when I want to set the association between the two objects in my
code this only works when I call baseclass.setReferencedClass(...).
When I try to do it the other way round
(referencedclass.setBaseclass(..)) I get an exception on commit, even
though I set kodo.InverseManager=true in my kodo.properties. The error
only occurs when I create both objects and set the reference within
one transaction. Excerpt from the stacktrace:
NestedThrowablesStackTrace:
kodo.util.FatalUserException: Attempt to set column
"BASECLASSPC.REFERENCEDCLASS_JDOID" to two different values:
(null)"null", (class java.lang.Long)"251" This can occur when you fail
to set both sides of a two-sided relation between objects, or when you
map different fields to the same column, but you do not keep the
values of these fields in synch.
at kodo.jdbc.sql.PrimaryRow.setObject(PrimaryRow.java:215)
at kodo.jdbc.sql.RowImpl.flushJoinValues(RowImpl.java:267)
at kodo.jdbc.sql.RowImpl.flushForeignKey(RowImpl.java:189)
at kodo.jdbc.sql.RowImpl.setForeignKey(RowImpl.java:158)
at kodo.jdbc.sql.PrimaryRow.setForeignKey(PrimaryRow.java:128)
The doku for the inverse manager says 'Under this setting, Kodo
detects changes to either side of a bidirectional relation, and
automatically sets the other side appropriately on flush.' So I was
expecting that it does not matter on which side I set the relation,
nor that I have to set the relation in two separate transactions, am I
wrong?
Here is the sample code, executed in a single transaction:
BaseclassPC base = new BaseclassPC();
ReferencedClassPC ref = new ReferencedClassPC();
//base.setRefClass(ref); <-- works
ref.setSubclass(base); <-- fails
getPersistenceManager().makePersistent(base);
getPersistenceManager().makePersistent(ref);
BTW: It does not matter in which order I make the calls to
makePersistent(...).
Thanks very much,
Jochen

Similar Messages

  • Relation table columns

    Does KODO support additional persistent columns in a relation table?
    Examples would be a timestamp or an additional flag. Currently the
    relation table is updated automatically by the objects in the
    relationship, but there is no object representing the relation table
    itself.

    <!doctype html public "-//w3c//dtd html 4.0 transitional//en">
    <html>
    Hi,
    <br>we faced the same need and have gone ahead with a slew of relation
    classes/subclasses with rules in them to manage their rightness. the default
    relation table is not amenable to model complex associations.
    <br>shridhar
    <br>
    <hr WIDTH="100%">
    <br> 
    <p>Patrick Linskey wrote:
    <blockquote TYPE=CITE>Currently, the only way to implement this is to write
    your own relation
    <br>class. We plan on implementing something along these lines down the
    road,
    <br>but it's not high on our new feature list at this point.
    <p>-Patrick
    <p>On 6/11/02 5:44 PM, "Todd Bowker" <[email protected]> wrote:
    <p>> Does KODO support additional persistent columns in a relation table?
    <br>> Examples would be a timestamp or an additional flag. Currently the
    <br>> relation table is updated automatically by the objects in the
    <br>> relationship, but there is no object representing the relation table
    <br>> itself.
    <p>--
    <br>Patrick Linskey      [email protected]
    <br>SolarMetric Inc.     http://www.solarmetric.com</blockquote>
    </html>

  • When primary table is also join table and you have NOT NULL constraints

    Hi,
    Me again. This is similar to the message titled "Problem with an
    optional 1 to 1 relationship modelled using a link table". Whats
    different about this case is we are dealing with a one to many relationship.
    Given this SQL:
    create table person (
    pid INTEGER(10) NOT NULL,
    language_code VARCHAR(3) NOT NULL
    create table language_person (
    pid INTEGER(10) NOT NULL REFERENCES person(pid),
    language_code VARCHAR(3) NOT NULL,
    first_name VARCHAR(20) NOT NULL
    I wrote these classes (abbreviated)
    Person:
    * @jdo:persist
    * @jdo:identity-type application
    * @jdo:objectid-class PersonId
    * @jdo:requires-extent false
    * @jdo:extension vendor-name="kodo" key="table"
    * value="PERSON"
    * @jdo:extension vendor-name="kodo" key="lock-column"
    * value="none"
    * @jdo:extension vendor-name="kodo" key="class-column"
    * value="none"
    public class Person {
    * @jdo:primary-key true
    * @jdo:extension vendor-name="kodo" key="data-column"
    * value="PID"
    private int pid;
    * @jdo:extension vendor-name="kodo" key="data-column"
    * value="LANGUAGE_CODE"
    private String languageCode;
    * @jdo:collection element-type="LanguagePerson"
    * @jdo:extension vendor-name="kodo" key="pid-data-column"
    * value="PID"
    * @jdo:extension vendor-name="kodo" key="table"
    * value="LANGUAGE_PERSON"
    * @jdo:extension vendor-name="kodo" key="pid-ref-column"
    * value="PID"
    * @jdo:extension vendor-name="kodo"
    key="languageCode-data-column"
    * value="LANGUAGE_CODE"
    * @jdo:extension vendor-name="kodo"
    key="languageCode-ref-column"
    * value="LANGUAGE_CODE"
    private Set languagePersons = new HashSet();
    public Person(int pid, String languageCode) {
    this.pid = pid;
    this.languageCode = languageCode;
    public void addLanguagePerson(LanguagePerson languagePerson) {
    languagePersons.add(languagePerson);
    public Set getLanguagePersons() {
    return languagePersons;
    LANGUAGE_PERSON
    * @jdo:persist
    * @jdo:identity-type application
    * @jdo:objectid-class LanguagePersonId
    * @jdo:requires-extent false
    * @jdo:extension vendor-name="kodo" key="table"
    * value="LANGUAGE_PERSON"
    * @jdo:extension vendor-name="kodo" key="lock-column"
    * value="none"
    * @jdo:extension vendor-name="kodo" key="class-column"
    * value="none"
    public class LanguagePerson {
    * @jdo:primary-key true
    * @jdo:extension vendor-name="kodo" key="data-column"
    * value="PID"
    private int pid;
    * @jdo:primary-key true
    * @jdo:extension vendor-name="kodo" key="data-column"
    * value="LANGUAGE_CODE"
    private String languageCode;
    * @jdo:extension vendor-name="kodo" key="data-column"
    * value="FIRST_NAME"
    private String firstName;
    public LanguagePerson(int pid, String languageCode, String firstName) {
    this.pid = pid;
    this.languageCode = languageCode;
    this.firstName = firstName;
    And then I do this:
         PersistenceManager pm = JDOFactory.getPersistenceManager();
    pm.currentTransaction().begin();
    final Person person = new Person(1,"EN");
    final LanguagePerson languagePerson = new
              LanguagePerson(1,"EN","Mike");
    person.addLanguagePerson(languagePerson);
    pm.makePersistent(person);
    pm.currentTransaction().commit();
    The SQL that issues forth is this:
    1125 [main] INFO jdbc.SQL - [ C:6588476; T:6166426; D:2891371 ]
    preparing statement <17089909>: INSERT INTO PERSON(LANGUAGE_CODE, PID)
    VALUES (?, ?)
    1125 [main] INFO jdbc.SQL - [ C:6588476; T:6166426; D:2891371 ]
    executing statement <17089909>: [reused=1;params={(String)EN,(int)1}]
    1125 [main] INFO jdbc.SQL - [ C:6588476; T:6166426; D:2891371 ]
    preparing statement <9818046>: INSERT INTO
    LANGUAGE_PERSON(LANGUAGE_CODE, PID) VALUES (?, ?)
    1125 [main] INFO jdbc.SQL - [ C:6588476; T:6166426; D:2891371 ]
    executing statement <9818046>: [reused=1;params={(String)EN,(int)1}]
    1140 [main] INFO jdbc.SQL - [ C:6588476; T:6166426; D:2891371 ]
    preparing statement <24763620>: INSERT INTO LANGUAGE_PERSON(FIRST_NAME,
    LANGUAGE_CODE, PID) VALUES (?, ?, ?)
    1140 [main] INFO jdbc.SQL - [ C:6588476; T:6166426; D:2891371 ]
    executing statement <24763620>:
    [reused=1;params={(String)Mike,(String)EN,(int)1}]
    And the second INSERT fails on Oracle because FIRST_NAME is null, and
    the table definition requires it to be NOT NULL.
    Is there anyway I can get Kodo to figure out its dealing with the same
    table for inserting the link columns and the full row, and optimize
    accordingly i.e do one INSERT for LANGUAGE_PERSON?
    I guess my only other options are a) introduce an explicit link table or
    b) define a custom mapping?
    Thanks,
    Mike.

    There are examples of 1-Many mappings in the documentation:
    http://www.solarmetric.com/Software/Documentation/latest/docs/
    ref_guide_meta_examples.html
    The important point I think you've missed is that right now, 1-many
    mappings always require an inverse 1-1 mapping. Again, see the docs
    above.
    So your LanguagePerson needs a field of type Person, and whenever you add
    a LanguagePerson to a Person, make sure to set that LanguagePerson's
    Person too. LanguagePerson.person will use the same PID column as
    LanguagePeson.pid. Kodo has no problem with having 2 mappings
    mapped to the same column.
    Kodo 3.0 will allow 1-Many relations without an inverse 1-1.

  • URGENT help !! 1-n relationship

    Hi ,
    i'm evaluation kodo (first impression : extremely powerful!)
    I'm trying to test a 1:n relationship with a join query between two tables
    (mysql database) , but i can't generate (by kodo) a single sql join
    statement. When i run the following code i have a query for
    TCatalogorisorse (obtaining a collection) and then automatically N query
    (for each element in the collection) on the TTiporisorsa table.....The
    results are correct...but i want a single join statement!!! help me, please
    This is the relationship followed by the columns:
    TCatalogorisorse (N) -------- (1) TTiporisorsa
    TCatalogorisorse [car_Code, car_Descrizione, car_Unitamisura ]
    TTiporisorsa[tpr_code,tpr_descrizione]
    Java code:
    public class TCatalogorisorse
    private int carCode;
    private String carDescrizione;
    private int carUnitamisura;
    private TTiporisorsa risorsa;
    public class TTiporisorsa
    private int tprCode;
    private String tprDescrizione;
    private Collection risorse ;
    Query:
    PersistenceManagerFactory pmf = new JDBCPersistenceManagerFactory ();
    PersistenceManager pm = pmf.getPersistenceManager ();
    Query query = pm.newQuery (provajdo.business.TCatalogorisorse.class);
    Collection results = (Collection) query.execute ();
    Metadata:
    <class name="TCatalogorisorse" objectid-class="TCatalogorisorseId">
    <extension key="class-column" value="none" vendor-name="kodo"/>
    <extension key="lock-column" value="none" vendor-name="kodo"/>
    <extension key="table" value="t_catalogorisorse"
    vendor-name="kodo"/>
    <field name="carCode" primary-key="true">
    <extension key="data-column" value="CAR_CODE"
    vendor-name="kodo"/>
    </field>
    <field name="carDescrizione">
    <extension key="data-column" value="CAR_DESCRIZIONE"
    vendor-name="kodo"/>
    </field>
    <field name="carUnitamisura">
    <extension key="data-column" value="CAR_UNITAMISURA"
    vendor-name="kodo"/>
    </field>
    <field name="risorsa">
    <extension key="tprCode-data-column" value="TPR_CODE"
    vendor-name="kodo"/>
    </field>
    </class>
    <class name="TTiporisorsa" objectid-class="TTiporisorsaId">
    <extension key="class-column" value="none" vendor-name="kodo"/>
    <extension key="lock-column" value="none" vendor-name="kodo"/>
    <extension key="table" value="t_tiporisorsa"
    vendor-name="kodo"/>
    <field name="tprCode" primary-key="true">
    <extension key="data-column" value="TPR_CODE"
    vendor-name="kodo"/>
    </field>
    <field name="tprDescrizione">
    <extension key="data-column" value="TPR_DESCRIZIONE"
    vendor-name="kodo"/>
    </field>
    <field name="risorse">
    <collection element-type="TCatalogorisorse"/>
    <extension vendor-name="kodo" key="element-inverse"
    value="risorsa"/>
    </field>
    </class>

    Thanks Abe,
    so are you saying me that kodo doesnt't currently generate dynamic sql
    with outer joins?
    can't i have
    select a.X,b.Y
    from a,b
    where
    a.Z=b.K
    please confirm my (last)
    conclusion!!
    thanks
    for the support... yes i would like an unique sql statement like this :
    select *
    from t_catalogorisorse cr , t_tiporisorsa tr
    where cr.tpr_code=tr.tpr_code;
    ....are you saying me that actually is not possible and so i must wait for
    kodo 3? (when it will be available?)...
    i am testing kodo to change the way to access databases (manually
    constructing queries :-( ) and this could be a big limitation, for big
    tables/databases this could be non good (i think).
    please reply with the definitive affermation.
    thanks
    Abe White wrote:
    Currently Kodo does not perform eager loading of relations. Kodo 3.0
    will support eager loading via outer joins (for 1-1) and batched selects
    (for 1-M/M-M). It lseems you're looking for a way to prevent extra
    queries for each TTiporisorsa when you read the set of all
    TCatalogorisorses. One way to accomplish this is to do a query for all
    the TTiporisorsas that will be loaded before you do your query for the
    related TCatalogorisorses. When you traverse the collection of
    TTiporisorsas, they will become cached. Then when each TCatalogorisorse
    loads its related TTiporisorsa, it will find it in the cache, and won't
    have to make a data store trip. So you end up with 2 queries instaed of
    (1 + #TCatalogorisorses).

  • Problem creating non-persistent Child Objects

    I have the need to create a non persistable child object in the
    jdoPreStore of a parent object. I then perform some tests on the parent
    to determine if the child object needs to be persisted or not. If I leave
    the child non persistent it still writes to the database.
    I was performing the follwoing piece of code
    Class Parent {
    // The relationship is a 0 to many
    public Child createChild() {
    Child child = .....//create non persistent object
    child.setParent(this);
    getChild().add(child);
    It appears that if I remove the getChild().add(child). It does not
    persist (as desired).
    Is this correct behaviour?? I dont think that it should be, but if it is
    then I have a further problem.
    If that child object inherits from another object and you remove the
    getChild().add(child) kodo outputs an invalid object to the database. It
    doesnt insert a row to the child table. But it inserts a row to the
    childs inherited object table. This is now an invalid object and will
    fail upon loading.
    Any help on this would be appreciated.
    Thanks
    Luke.

    JDO has something called persistence by reachability. This means that
    objects do not have to explicitly be marked as to be persistent as JDO
    will traverse the object graph to ensure that all nodes are persistent.
    I think you are seeing this behavior combined with another side
    behavior: Kodo requires that both sides of a relation be set.
    Basically, keep your objects in synch (set both sides of the relation).
    And if you want to hold onto a reference to non-persistent object
    before you decide what to do with it, add a transient field or a field
    marked "persistence-modifier="none"" in your metadata and then process
    those transient fields in jdoPreStore ().
    i.e.
    if (//businessLogic is true)
    persistentField = transientField;
    Luke wrote:
    I have the need to create a non persistable child object in the
    jdoPreStore of a parent object. I then perform some tests on the parent
    to determine if the child object needs to be persisted or not. If I leave
    the child non persistent it still writes to the database.
    I was performing the follwoing piece of code
    Class Parent {
    // The relationship is a 0 to many
    public Child createChild() {
    Child child = .....//create non persistent object
    child.setParent(this);
    getChild().add(child);
    It appears that if I remove the getChild().add(child). It does not
    persist (as desired).
    Is this correct behaviour?? I dont think that it should be, but if it is
    then I have a further problem.
    If that child object inherits from another object and you remove the
    getChild().add(child) kodo outputs an invalid object to the database. It
    doesnt insert a row to the child table. But it inserts a row to the
    childs inherited object table. This is now an invalid object and will
    fail upon loading.
    Any help on this would be appreciated.
    Thanks
    Luke.
    Steve Kim
    [email protected]
    SolarMetric Inc.
    http://www.solarmetric.com

  • Support for "Interface Based Design"

    I would like two PC classes that implement a common interface, but the two
    PC classes are not related by inheritance, and would not be stored in the
    same table. For example,
    public interface VersionNumber {
    int getNumber();
    boolean isComparableTo( VersionNumber vn );
    /** PC class **/
    public class BasicVersionNumber implements VersionNumber {
    /** PC class **/
    public class CustomVersionNumber implements VersionNumber {
    /** PC class **/
    public class Paper {
    VersionNumber vn;
    Since "BasicVersionNumber" and "CustomVersionNumber" are not related via
    inheritance, they would not generally reside in the same database table.
    It would mean that the table containing "Paper" would need both the target
    table for this instance of "vn", and the primary key for "vn". It appears
    that KODO assumes the target table is available in the Meta-Data file, but
    with interface-based design, that is not known until run time and could be
    different for different instances of class "Paper".
    Is it possible to do this with KODO? Where can I go to understand how.
    Keith L. Musser
    Integrated Dynamics, Inc.
    812-371-7777
    email: [email protected]
    Disclaimer - This email, and any files transmitted with it, are confidential
    and may contain privileged or copyright information. If you are not the
    intended recipient you must not copy, distribute or use this email, or the
    information contained herein, for any purpose other than to notify us. If
    you received this email in error, please notify the sender immediately, and
    delete this email from your system.

    Kodo supports interfaces as fields (in Kodo 3, we support interfaces for
    more relation types). Kodo will store the toString () of the JDO
    identity for the actual concrete instance in the column as there is no
    formal O/R relation between the table and the interface field type.
    Keith Musser wrote:
    I would like two PC classes that implement a common interface, but the two
    PC classes are not related by inheritance, and would not be stored in the
    same table. For example,
    public interface VersionNumber {
    int getNumber();
    boolean isComparableTo( VersionNumber vn );
    /** PC class **/
    public class BasicVersionNumber implements VersionNumber {
    /** PC class **/
    public class CustomVersionNumber implements VersionNumber {
    /** PC class **/
    public class Paper {
    VersionNumber vn;
    Since "BasicVersionNumber" and "CustomVersionNumber" are not related via
    inheritance, they would not generally reside in the same database table.
    It would mean that the table containing "Paper" would need both the target
    table for this instance of "vn", and the primary key for "vn". It appears
    that KODO assumes the target table is available in the Meta-Data file, but
    with interface-based design, that is not known until run time and could be
    different for different instances of class "Paper".
    Is it possible to do this with KODO? Where can I go to understand how.
    Steve Kim
    [email protected]
    SolarMetric Inc.
    http://www.solarmetric.com

  • Relational queries through JDBC with the help of Kodo's metadata for O/R mapping

    Due to JDOQL's limitations (inability to express joins, when relationships
    are not modeled as object references), I find myself needing to drop down to
    expressing some queries in SQL through JDBC. However, I still want my Java
    code to remain independent of the O/R mapping. I would like to be able to
    formulate the SQL without hardcoding any knowledge of the relational table
    and column names, by using Kodo's metadata. After poking around the Kodo
    Javadocs, it appears as though the relevant calls are as follows:
    ClassMetaData cmd = ClassMetaData.getInstance(MyPCObject.class, pm);
    FieldMetaData fmd = cmd.getDeclaredField( "myField" );
    PersistenceManagerFactory pmf = pm.getPersistenceManagerFactory();
    JDBCConfiguration conf = (JDBCConfiguration)
    ((EEPersistenceManagerFactory)pmf).getConfiguration();
    ClassResolver resolver = pm.getClassResolver(MyPCObject.class);
    Connector connector = new PersistenceManagerConnector(
    (PersistenceManagerImpl) pm );
    DBDictionary dict = conf.getDictionary( connector );
    FieldMapping fm = ClassMapping.getFieldMapping(fmd, conf, resolver, dict);
    Column[] cols = fm.getDataColumns();
    Does that look about right?
    Here's what I'm trying to do:
    class Foo
    String name; // application identity
    String bar; // foreign key to Bar
    class Bar
    String name; // application identity
    int weight;
    Let's say I want to query for all Foo instances for which its bar.weight >
    100. Clearly this is trivial to do in JDOQL, if Foo.bar is an object
    reference to Bar. But there are frequently good reasons for modeling
    relationships as above, for example when Foo and Bar are DTOs exposed by the
    remote interface of an EJB. (Yeah, yeah, I'm lazy, using my
    PersistenceCapable classes as both the DAOs and the DTOs.) But I still want
    to do queries that navigate the relationship; it would be nice to do it in
    JDOQL directly. I will also want to do other weird-ass queries that would
    definitely only be expressible in SQL. Hence, I'll need Kodo's O/R mapping
    metadata.
    Is there anything terribly flawed with this logic?
    Ben

    I have a one point before I get to this:
    There is nothing wrong with using PC instances as both DAO and DTO
    objects. In fact, I strongly recommend this for most J2EE/JDO design.
    However, there should be no need to expose the foreign key values... use
    application identity to quickly reconstitute an object id (which can in
    turn find the persistent version), or like the j2ee tutorial, store the
    object id in some form (Object or String) and use that to re-find the
    matching persistent instance at the EJB tier.
    Otherwise, there is a much easier way of finding ClassMapping instances
    and in turn FieldMapping instances (see ClassMapping.getInstance () in
    the JavaDocs).
    Ben Eng wrote:
    Due to JDOQL's limitations (inability to express joins, when relationships
    are not modeled as object references), I find myself needing to drop down to
    expressing some queries in SQL through JDBC. However, I still want my Java
    code to remain independent of the O/R mapping. I would like to be able to
    formulate the SQL without hardcoding any knowledge of the relational table
    and column names, by using Kodo's metadata. After poking around the Kodo
    Javadocs, it appears as though the relevant calls are as follows:
    ClassMetaData cmd = ClassMetaData.getInstance(MyPCObject.class, pm);
    FieldMetaData fmd = cmd.getDeclaredField( "myField" );
    PersistenceManagerFactory pmf = pm.getPersistenceManagerFactory();
    JDBCConfiguration conf = (JDBCConfiguration)
    ((EEPersistenceManagerFactory)pmf).getConfiguration();
    ClassResolver resolver = pm.getClassResolver(MyPCObject.class);
    Connector connector = new PersistenceManagerConnector(
    (PersistenceManagerImpl) pm );
    DBDictionary dict = conf.getDictionary( connector );
    FieldMapping fm = ClassMapping.getFieldMapping(fmd, conf, resolver, dict);
    Column[] cols = fm.getDataColumns();
    Does that look about right?
    Here's what I'm trying to do:
    class Foo
    String name; // application identity
    String bar; // foreign key to Bar
    class Bar
    String name; // application identity
    int weight;
    Let's say I want to query for all Foo instances for which its bar.weight >
    100. Clearly this is trivial to do in JDOQL, if Foo.bar is an object
    reference to Bar. But there are frequently good reasons for modeling
    relationships as above, for example when Foo and Bar are DTOs exposed by the
    remote interface of an EJB. (Yeah, yeah, I'm lazy, using my
    PersistenceCapable classes as both the DAOs and the DTOs.) But I still want
    to do queries that navigate the relationship; it would be nice to do it in
    JDOQL directly. I will also want to do other weird-ass queries that would
    definitely only be expressible in SQL. Hence, I'll need Kodo's O/R mapping
    metadata.
    Is there anything terribly flawed with this logic?
    Ben
    Steve Kim
    [email protected]
    SolarMetric Inc.
    http://www.solarmetric.com

  • 1xM relation working in Hibernate doesn't work in Kodo and EclipseLink

    Greetings,
    I'm migrating some applications from JBoss/Hibernate to WebLogic 10gR3 and I found lots of JPA problems. In order to simplify the context, I used a very simple one to many bidirectional relationship between 2 entities. Using the following persistence.xml file:
    <?xml version="1.0"?>
    <persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
    version="1.0">
    <persistence-unit name="ww204-jpa" transaction-type="JTA">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>cgDataSource</jta-data-source>
    <class>fr.simplex_software.jpa.Employee</class>
    <class>fr.simplex_software.jpa.Department</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
    <property name="hibernate.hbm2ddl.auto" value="create-drop" />
    <property name="hibernate.transaction.factory_class"
    value="org.hibernate.transaction.JTATransactionFactory" />
    <property name="hibernate.transaction.manager_lookup_class"
    value="org.hibernate.transaction.WeblogicTransactionManagerLookup" />
    <property name="jta.UserTransaction" value="java:comp/UserTransaction" />
    </properties>
    </persistence-unit>
    </persistence>
    the test works correctly on WebLogic 10gR3. Now, I'm modifying the persistence.xml to read:
    <?xml version="1.0"?>
    <persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
    version="1.0">
    <persistence-unit name="ww204-jpa" transaction-type="JTA">
    <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
    <jta-data-source>cgDataSource</jta-data-source>
    <class>fr.simplex_software.jpa.Employee</class>
    <class>fr.simplex_software.jpa.Department</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
    <property name="kodo.jdbc.SynchronizeMappings" value="refresh" />
    </properties>
    </persistence-unit>
    </persistence>
    The test raises the following exception:
    Exception in thread "Main Thread" java.lang.ClassCastException: fr.simplex_software.jpa.Department
         at fr.simplex_software.slsb.Facade_7ky0ac_FacadeRemoteImpl_WLSkel.invoke(Unknown Source)
         at weblogic.rmi.internal.BasicServerRef.invoke(BasicServerRef.java:589)
         at weblogic.rmi.cluster.ClusterableServerRef.invoke(ClusterableServerRef.java:230)
         at weblogic.rmi.internal.BasicServerRef$1.run(BasicServerRef.java:477)
         at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
         at weblogic.security.service.SecurityManager.runAs(Unknown Source)
         at weblogic.rmi.internal.BasicServerRef.handleRequest(BasicServerRef.java:473)
         at weblogic.rmi.internal.wls.WLSExecuteRequest.run(WLSExecuteRequest.java:118)
         at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)
         at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)
    If I modify the persistence.xml to read:
    <?xml version="1.0" encoding="UTF-8"?>
    <persistence version="1.0"
    xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
    <persistence-unit name="ww204-jpa" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider </provider>
    <jta-data-source>cgDataSource</jta-data-source>
    <class>fr.simplex_software.jpa.Employee</class>
    <class>fr.simplex_software.jpa.Department</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
    <property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
    <property name="eclipselink.ddl-generation.output-mode"
    value="database" />
    </properties>
    </persistence-unit>
    </persistence>
    the test raises the same exception. If I come back to the first persistence.xml file, the test works properly again. Is there something I'm doing wrong ?
    Many thanks in advance for any help.
    Nicolas

    Performing the following operations after having changed the persistence.xml file solve the problem:
    1. Undeploy the application.
    2. Run appc to re-generate stubs and copy them on the client CLASSPATH (see also How to run a Java EE client application ?
    3. Stop the server.
    4. Start the server.
    5. Re-deploy the application.
    All the above operations are purhaps not absolutely required but the whole procedure is sufficient to provide the expected result.
    Kind regards,
    Nicolas

  • Kodo & non relational data storage

    I noticed you are working on LDAP adapter for Kodo. That's nice
    I was wondering why didn't you try to have support for Oracle Objects. It
    should be relatively easy to map JDO onto oracle objects. JDQL might be
    tricky but mapping itself should be pretty straightforward
    I think the primary reason people do not use oracle objects much because
    oracle did not provide any reasonable client binding mechanism. Their
    JPublisher is pretty useless but given JDO frontent it will be nice
    Alex

    Alex,
    Kodo supports Versant object database as persistent storage in
    Kodo/Versant JDO version.
    Pinaki
    Alex Roytman wrote:
    I noticed you are working on LDAP adapter for Kodo. That's nice
    I was wondering why didn't you try to have support for Oracle Objects. It
    should be relatively easy to map JDO onto oracle objects. JDQL might be
    tricky but mapping itself should be pretty straightforward
    I think the primary reason people do not use oracle objects much because
    oracle did not provide any reasonable client binding mechanism. Their
    JPublisher is pretty useless but given JDO frontent it will be nice
    Alex

  • (Managed) Inverse relations and map mapping

    Hi.
    Is there any limitation in using (managed) inverse relations together
    with map mapping? I've tried to setup my test model like this: a single
    City object holds references to many Street objects. City has "name"
    attribute , collection named "streetsList" (1-n with Streets) and map
    named "streetsMap"(n-to-many map with Streets). Street objects have just
    simple "name" attribute and single "city" reference to City object.
    What I'd like to achieve is have Kodo to set inverse relation on Street
    object (relation "city") when I put Street object into City's
    "streetsMap". This works fine when using collection ("streetsList") but
    doesn't seems to be working when map-mapped relation field is in use.
    How do I use Kodo's inverse relations manager with map fields?
    Everything is OK when I set the inverse side of relation manually
    (setting Street.city field when putting Street to City.streetsMap) - but
    I'd like InverseManager to do it!
    My configuration:
    - kodo.properties:
    kodo.InverseManager: true(ManageLRS=true)
    - package.mapping:
    <class name="City">
    <jdbc-class-map type="base" pk-column="JDOID"
    table="TEST_CITY"/>
    <jdbc-class-ind type="metadata-value" column="JDOTYPE"/>
    <field name="name">
    <jdbc-field-map type="value" column="CITY_NAME"/>
    </field>
         <field name="streetsMap">
         <jdbc-field-map type="n-many-map" key-column="MAP_KEY"
    table="TEST_STREET_MAP"
         value-column.JDOID="STREET_JDOID"
    ref-column.JDOID="CITY_JDOID"/>
         </field>
    <field name="streetsList">
              <jdbc-field-map type="one-many" ref-column.JDOID="CITY_JDOID"
    table="TEST_STREET"/>
    </field>
    </class>
    <class name="Street">
    <jdbc-class-map type="base" pk-column="JDOID"
    table="TEST_STREET"/>
    <jdbc-version-ind type="version-number" column="JDOVERSION"/>
    <jdbc-class-ind type="metadata-value" column="JDOTYPE"/>
    <field name="name">
    <jdbc-field-map type="value" column="NAME"/>
    </field>
    <field name="city">
              <jdbc-field-map type="one-one" column.JDOID="CITY_JDOID"/>
         </field>
    </class>
    - package.jdo:
    <class name="City">
              <extension key="jdbc-class-ind-value" vendor-name="kodo" value="1"/>
              <field name="streetsMap">
                   <map key-type="String" value-type="Street"/>
                   <extension vendor-name="kodo" key="inverse-owner" value="city"/>
                   <extension vendor-name="kodo" key="lock-group" value="none"/>
              </field>
              <field name="streetsList">
                   <collection element-type="Street"/>
                   <extension vendor-name="kodo" key="inverse-owner" value="city"/>
                   <extension vendor-name="kodo" key="lock-group" value="none"/>
              </field>
              <field name="name">
              </field>
         </class>
         <class name="Street">
              <extension key="jdbc-class-ind-value" vendor-name="kodo" value="2"/>
              <field name="name">
              </field>
         </class>
    Regards,
    Pawe____ ____wierszcz

    Unfortunately, inverse management is not available for Maps. We hope to
    make it available in a future release.

  • Unit test fails after upgrading to Kodo 4.0.0 from 4.0.0-EA4

    I have a group of 6 unit tests failing after upgrading to the new Kodo
    4.0.0 (with BEA) from Kodo-4.0.0-EA4 (with Solarmetric). I'm getting
    exceptions like the one at the bottom of this email. It seems to be an
    interaction with the PostgreSQL driver, though I can't be sure. I
    haven't changed my JDO configuration or the related classes in months
    since I've been focusing on using the objects that have already been
    defined. The .jdo, .jdoquery, and .java code are below the exception,
    just in case there's something wrong in there. Does anyone have advice
    as to how I might debug this?
    Thanks,
    Mark
    Testsuite: edu.ucsc.whisper.test.integration.UserManagerQueryIntegrationTest
    Tests run: 15, Failures: 0, Errors: 6, Time elapsed: 23.308 sec
    Testcase:
    testGetAllUsersWithFirstName(edu.ucsc.whisper.test.integration.UserManagerQueryIntegrationTest):
    Caused an ERROR
    The column index is out of range: 2, number of columns: 1.
    <2|false|4.0.0> kodo.jdo.DataStoreException: The column index is out of
    range: 2, number of columns: 1.
    at
    kodo.jdbc.sql.DBDictionary.newStoreException(DBDictionary.java:4092)
    at kodo.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:82)
    at kodo.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:66)
    at kodo.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:46)
    at
    kodo.jdbc.kernel.SelectResultObjectProvider.handleCheckedException(SelectResultObjectProvider.java:176)
    at
    kodo.kernel.QueryImpl$PackingResultObjectProvider.handleCheckedException(QueryImpl.java:2460)
    at
    com.solarmetric.rop.EagerResultList.<init>(EagerResultList.java:32)
    at kodo.kernel.QueryImpl.toResult(QueryImpl.java:1445)
    at kodo.kernel.QueryImpl.execute(QueryImpl.java:1136)
    at kodo.kernel.QueryImpl.execute(QueryImpl.java:901)
    at kodo.kernel.QueryImpl.execute(QueryImpl.java:865)
    at kodo.kernel.DelegatingQuery.execute(DelegatingQuery.java:787)
    at kodo.jdo.QueryImpl.executeWithArray(QueryImpl.java:210)
    at kodo.jdo.QueryImpl.execute(QueryImpl.java:137)
    at
    edu.ucsc.whisper.core.dao.JdoUserDao.findAllUsersWithFirstName(JdoUserDao.java:232)
    at
    edu.ucsc.whisper.core.manager.DefaultUserManager.getAllUsersWithFirstName(DefaultUserManager.java:252)
    NestedThrowablesStackTrace:
    org.postgresql.util.PSQLException: The column index is out of range: 2,
    number of columns: 1.
    at
    org.postgresql.core.v3.SimpleParameterList.bind(SimpleParameterList.java:57)
    at
    org.postgresql.core.v3.SimpleParameterList.setLiteralParameter(SimpleParameterList.java:101)
    at
    org.postgresql.jdbc2.AbstractJdbc2Statement.bindLiteral(AbstractJdbc2Statement.java:2085)
    at
    org.postgresql.jdbc2.AbstractJdbc2Statement.setInt(AbstractJdbc2Statement.java:1133)
    at
    com.solarmetric.jdbc.DelegatingPreparedStatement.setInt(DelegatingPreparedStatement.java:390)
    at
    com.solarmetric.jdbc.PoolConnection$PoolPreparedStatement.setInt(PoolConnection.java:440)
    at
    com.solarmetric.jdbc.DelegatingPreparedStatement.setInt(DelegatingPreparedStatement.java:390)
    at
    com.solarmetric.jdbc.DelegatingPreparedStatement.setInt(DelegatingPreparedStatement.java:390)
    at
    com.solarmetric.jdbc.DelegatingPreparedStatement.setInt(DelegatingPreparedStatement.java:390)
    at
    com.solarmetric.jdbc.LoggingConnectionDecorator$LoggingConnection$LoggingPreparedStatement.setInt(LoggingConnectionDecorator.java:1
    257)
    at
    com.solarmetric.jdbc.DelegatingPreparedStatement.setInt(DelegatingPreparedStatement.java:390)
    at
    com.solarmetric.jdbc.DelegatingPreparedStatement.setInt(DelegatingPreparedStatement.java:390)
    at kodo.jdbc.sql.DBDictionary.setInt(DBDictionary.java:980)
    at kodo.jdbc.sql.DBDictionary.setUnknown(DBDictionary.java:1299)
    at kodo.jdbc.sql.SQLBuffer.setParameters(SQLBuffer.java:638)
    at kodo.jdbc.sql.SQLBuffer.prepareStatement(SQLBuffer.java:539)
    at kodo.jdbc.sql.SQLBuffer.prepareStatement(SQLBuffer.java:512)
    at kodo.jdbc.sql.SelectImpl.execute(SelectImpl.java:332)
    at kodo.jdbc.sql.SelectImpl.execute(SelectImpl.java:301)
    at kodo.jdbc.sql.Union$UnionSelect.execute(Union.java:642)
    at kodo.jdbc.sql.Union.execute(Union.java:326)
    at kodo.jdbc.sql.Union.execute(Union.java:313)
    at
    kodo.jdbc.kernel.SelectResultObjectProvider.open(SelectResultObjectProvider.java:98)
    at
    kodo.kernel.QueryImpl$PackingResultObjectProvider.open(QueryImpl.java:2405)
    at
    com.solarmetric.rop.EagerResultList.<init>(EagerResultList.java:22)
    at kodo.kernel.QueryImpl.toResult(QueryImpl.java:1445)
    at kodo.kernel.QueryImpl.execute(QueryImpl.java:1136)
    at kodo.kernel.QueryImpl.execute(QueryImpl.java:901)
    at kodo.kernel.QueryImpl.execute(QueryImpl.java:865)
    at kodo.kernel.DelegatingQuery.execute(DelegatingQuery.java:787)
    at kodo.jdo.QueryImpl.executeWithArray(QueryImpl.java:210)
    at kodo.jdo.QueryImpl.execute(QueryImpl.java:137)
    at
    edu.ucsc.whisper.core.dao.JdoUserDao.findAllUsersWithFirstName(JdoUserDao.java:232)
    --- DefaultUser.java -------------------------------------------------
    public class DefaultUser
    implements User
    /** The account username. */
    private String username;
    /** The account password. */
    private String password;
    /** A flag indicating whether or not the account is enabled. */
    private boolean enabled;
    /** The authorities granted to this account. */
    private Set<Authority> authorities;
    /** Information about the user, including their name and text that
    describes them. */
    private UserInfo userInfo;
    /** The set of organizations where this user works. */
    private Set<Organization> organizations;
    --- DefaultUser.jdo --------------------------------------------------
    <?xml version="1.0"?>
    <!DOCTYPE jdo PUBLIC
    "-//Sun Microsystems, Inc.//DTD Java Data Objects Metadata 2.0//EN"
    "http://java.sun.com/dtd/jdo_2_0.dtd">
    <jdo>
    <package name="edu.ucsc.whisper.core">
    <sequence name="user_id_seq"
    factory-class="native(Sequence=user_id_seq)"/>
    <class name="DefaultUser" detachable="true"
    table="whisper_user" identity-type="datastore">
    <datastore-identity sequence="user_id_seq" column="userId"/>
    <field name="username">
    <column name="username" length="80" jdbc-type="VARCHAR" />
    </field>
    <field name="password">
    <column name="password" length="40" jdbc-type="CHAR" />
    </field>
    <field name="enabled">
    <column name="enabled" />
    </field>
    <field name="userInfo" persistence-modifier="persistent"
    default-fetch-group="true" dependent="true">
    <extension vendor-name="jpox"
    key="implementation-classes"
    value="edu.ucsc.whisper.core.DefaultUserInfo" />
    <extension vendor-name="kodo"
    key="type"
    value="edu.ucsc.whisper.core.DefaultUserInfo" />
    </field>
    <field name="authorities" persistence-modifier="persistent"
    table="user_authorities"
    default-fetch-group="true">
    <collection
    element-type="edu.ucsc.whisper.core.DefaultAuthority" />
    <join column="userId" delete-action="cascade"/>
    <element column="authorityId" delete-action="cascade"/>
    </field>
    <field name="organizations" persistence-modifier="persistent"
    table="user_organizations" mapped-by="user"
    default-fetch-group="true" dependent="true">
    <collection
    element-type="edu.ucsc.whisper.core.DefaultOrganization"
    dependent-element="true"/>
    <join column="userId"/>
    <!--<element column="organizationId"/>-->
    </field>
    </class>
    </package>
    </jdo>
    --- DefaultUser.jdoquery ---------------------------------------------
    <?xml version="1.0"?>
    <!DOCTYPE jdo PUBLIC
    "-//Sun Microsystems, Inc.//DTD Java Data Objects Metadata 2.0//EN"
    "http://java.sun.com/dtd/jdo_2_0.dtd">
    <jdo>
    <package name="edu.ucsc.whisper.core">
    <class name="DefaultUser">
    <query name="UserByUsername"
    language="javax.jdo.query.JDOQL"><![CDATA[
    SELECT UNIQUE FROM edu.ucsc.whisper.core.DefaultUser
    WHERE username==searchName
    PARAMETERS java.lang.String searchName
    ]]></query>
    <query name="DisabledUsers"
    language="javax.jdo.query.JDOQL"><![CDATA[
    SELECT FROM edu.ucsc.whisper.core.DefaultUser WHERE
    enabled==false
    ]]></query>
    <query name="EnabledUsers"
    language="javax.jdo.query.JDOQL"><![CDATA[
    SELECT FROM edu.ucsc.whisper.core.DefaultUser WHERE
    enabled==true
    ]]></query>
    <query name="CountUsers"
    language="javax.jdo.query.JDOQL"><![CDATA[
    SELECT count( this ) FROM edu.ucsc.whisper.core.DefaultUser
    ]]></query>
    </class>
    </package>
    </jdo>

    I'm sorry, I have no idea. I suggest sending a test case that
    reproduces the problem to support.

  • Bug - multiple related instances of same class

    We've discovered a rather subtle bug in the process by which Kodo
    searches for reachable related objects to persist. If an instance of a
    PC class (A) has two relationships to the same PC class (B), and both
    related instances of B have the same value for their PK-field, then only
    one of the related instances of B will be persisted.
    Obviously, this problem only occurs in the context of application
    identity. We've only encountered it when all the instances involved are
    newly created and being made persistent for the first time (else the
    instances would have different PK-values). It should also be noted that
    we're assigning PK-values in jdoPreStore(). Here's the specific
    situation we encountered:
    Class A has two relationships to class B, represented by fields "B b1"
    and "B b2". In our case, A.b1 is the many-side of a bidirectional
    one-to-many relationship; the one-side is implemented by a field "List
    aList" in B. A.b2 is the navigable side of a unidirectional
    relationship; there is no corresponding field in B. (We haven't checked
    whether or how the cardinality or navigability of the relationships
    affects the problem.)
    Let "a1" be the sole instance of A. If a1.b1 is set to an instance of B
    but a1.b2 is null, and makePersistent( a1 ) is called, then a1 and b1
    are persisted correctly and the relation field b2_id in TableA is NULL.
    However, if a1.b2 is set to a second instance of B and both instances of
    B have the same initial value of their PK-field, then a.b2 is not
    persisted. Only one record is added to TableB; it corresponds to A.b1.
    Interestingly, in this case the relation field b2_id in TableA is not
    NULL, but has the default value of b2's PK-field. jdoPreStore() is not
    called on b2 and b2 is not persisted, but its PK-field is read in the
    process of persisting a1.
    Since we've placed the jdoPreStore() callback in a common non-persistent
    adapter superclass, we're currently able to work around the problem with
    a static "seed" PK value that is incremented in the superclass default
    constructor to provide a unique initial value for each PK-field. If
    anyone would like the code for this approach we'll post it, although
    it'll become unnecessary when the problem is fixed.
    Jerry Pulley
    Sr. Developer
    Commerce Technologies, Inc.

    I'm curious what behavior, besides throwing an exception, could even be
    possible. If the pm discovers two object with the same id, it seems that it
    has to choose one of them to make persistent. How could it possibly resolve
    differences in the fields of the two instances in deciding which one is the
    correct one to put in the db? Additionally, allowing this behavior could
    lead to subtle, difficult to detect bugs in your program, since ( as Abe
    points out ) JDO promises that there will only be one instance of an object
    with a given primary key per PM. Other code may make decisions based on
    this expectation ( like refreshing one of the objects after making a change
    in a different PM ), that would lead to problems for code still hanging on
    to the second instance.
    IMHO, it should throw an exception.
    -Eric
    "Abe White" <[email protected]> wrote in message
    news:[email protected]...
    Thanks for the bug report! However, I'm not entirely sure that this is a
    bug (at least not the bug you think it is); either way it's an extremely
    interesting case. The reason I say it might not be a bug is thatassigning
    pk values in jdoPreStore seems suspect.
    We know that a single PM cannot at any time contain multiple instances
    with the same oid value, app id or otherwise. This is obvious from the
    getObjectById method -- only one object can have a particular oid.
    We also know that jdoPreStore is called only for instances managed by a
    PM (duh!).
    Thus it should not be possible to see a case where jdoPreStore is
    called for 2 objects with the same initial oid.
    Now, I realize that when you're dealing with persistence-by-reachability
    things become less clear. However, I think the general point stands: at
    the time that the objects are made persistent they all must have unique
    oid values, and objects must be made persistent before jdoPreStore is
    called.
    Technically we could get around this. The current
    persistence-by-reachability algorithm is something like:
    flushed = {}
    while flushed.size < persistent.size:
    for each persistent instance:
    if instance not in flushed:
    instance.jdoPreStore // may persist more instances
    instance.persistFirstClassFields // may persist more too
    flushed += instance
    In sum this is a breadth-first method of persisting relations. It could
    be changed to a depth-first system instead of persisting all first class
    fields each one is persisted and then immediately the algorithm is
    repeated for that object before the other fields are touched. However,
    this seems like it might lead to other unexpected behavior.
    Generally, it just seems like waiting till jdoPreStore to assign the oid
    of an object seems like a bad idea. I think the real bug is that Kodo is
    not throwing an exception as soon as 2 object with the same oid are
    detected (currently it just lets one overwrite the other in the cache,
    which results in the behavior you see).
    Does anyone else have an opinion on this? I'm certainly not fixed on my
    interpretation of things; if you disagree I'd be very interested in
    hearing other arguments.

  • SQL Batch doesn't seem to work; How to eager-fetch related objects?

    Hi,
    I have two technical questions with Kodo.
    1. SQL Batch doesn't seem to work. I have tried batch size of -1, 0, 1, 25.
    But the performance from batch creating objects is not affected by batch
    size.
    kodo.jdbc.DBDictionary: BatchLimit=25
    2. How to use custom fetch groups to eagerly fetch related persistable
    objects? Example only showed attributes, not relationships.
    Enviroment:
    * Kodo 3.1.0 RC1
    * Oracle 9i release 1.
    Qingshan Luo
    Senior Software Engineer
    Open Harbor
    1123 Industrial Road
    San Carlos, CA 94070
    Phone: 650-413-4251
    Fax: 650-413-4298

    try poracle 10g driver. At least they fixed terrible CLOB bug may be batch
    to. BTW 9.2.x has problem with batching with deferred constraints so be
    careful
    "Greg Campbell" <[email protected]> wrote in message
    news:c3dmnu$rmj$[email protected]..
    >
    "Qingshan Luo" <[email protected]> wrote in message
    news:c3dg7q$mdl$[email protected]..
    Hi,
    I have two technical questions with Kodo.
    1. SQL Batch doesn't seem to work. I have tried batch size of -1, 0, 1,25.
    But the performance from batch creating objects is not affected by batch
    size.
    kodo.jdbc.DBDictionary: BatchLimit=25You may be running into a bug in the Oracle 9.2 driver. That driverdoesn't
    reliably give update counts when using batching and prepared statement
    caching. By default, Kodo will turn off batching. You can manuallyenable
    batching by setting the BatchLimit on your DBDictionary, as you've done.If
    you do this, though, you may want to turn off prepared statement cachingby
    setting MaxCachedStatements to 0 (see
    http://www.solarmetric.com/Software/Documentation/3.1.0RC1/docs/ref_guide_dbsetup.html#ref_guide_dbsetup_builtin).
    >
    2. How to use custom fetch groups to eagerly fetch related persistable
    objects? Example only showed attributes, not relationships.You can find information on setting up eager fetching of relations at
    http://www.solarmetric.com/Software/Documentation/3.0.3/docs/ref_guide_
    perfpack_eager.html
    Basically, you'll need to add the relations to your fetch group, and
    set the eager fetching mode.
    Enviroment:
    * Kodo 3.1.0 RC1
    * Oracle 9i release 1.
    Qingshan Luo
    Senior Software Engineer
    Open Harbor
    1123 Industrial Road
    San Carlos, CA 94070
    Phone: 650-413-4251
    Fax: 650-413-4298

  • One to many relation doesn't work

    I tried without success to get a simple one to many relationship to work.
    The select works fine but
    I still have problems with insert.
    I have two tables on a existing schema:
    1     ANAG (ID_ANAG primary key,...)
    2     INDI (ID_INDI primary key, ID_ENTITA,...), where INDI.ID_ENTITA points
    to ANAG.ID_ANAG
    the two classes are:
    1     public class Anagrafica
         private int idAnag; //ID_ANAG
         private String ragSoc;
         private String ragSocFonet;
         private String codFisc;
         private String sesso;
         private Integer codTit;
         private Date dtNasc;
         private HashSet indis;
    2     public class Indirizzo
         private int idIndi; //ID_INDI
         private long idEntita; //ID_ENTITA
         private long tpEntita;
         private String indirizzo;
         private String localita;
         private String prov;
         private String cap;
         private Anagrafica anagrafica;
    the two metadata:
    1      anagrafica.jdo:
    <?xml version="1.0"?>
    <!-- This JDO Metadata file was auto-generated on 08/10/02 17.44.
    See http://www.solarmetric.com for Kodo JDO Documentation and examples. -->
    <jdo>
    <package name="domain">
    <class name="Anagrafica"
    identity-type="application"
    objectid-class="domain.AnagraficaPK">
    <extension key="table" value="ANAG" vendor-name="kodo"/>
    <extension key="class-column" value="none" vendor-name="kodo"/>
    <extension key="lock-column" value="none" vendor-name="kodo"/>
    <field name="idAnag" primary-key="true">
    <extension key="data-column" value="ID_ANAG"
    vendor-name="kodo"/>
    </field>
    <field name="ragSoc">
    <extension key="data-column" value="RAG_SOC"
    vendor-name="kodo"/>
    </field>
    <field name="ragSocFonet">
    <extension key="data-column" value="RAG_SOC_FONET"
    vendor-name="kodo"/>
    </field>
    <field name="codFisc">
    <extension key="data-column" value="COD_FISC"
    vendor-name="kodo"/>
    </field>
    <field name="sesso">
    <extension key="data-column" value="SESSO"
    vendor-name="kodo"/>
    </field>
    <field name="codTit">
    <extension key="data-column" value="COD_TIT"
    vendor-name="kodo"/>
    </field>
    <field name="dtNasc">
    <extension key="data-column" value="DT_NASC"
    vendor-name="kodo"/>
    </field>
    <field name="indis">
    <collection element-type="domain.Indirizzo"/>
    <extension vendor-name="kodo" key="table" value="INDI"/>
    <extension vendor-name="kodo" key="inverse"
    value="anagrafica"/>
    <extension vendor-name="kodo" key="idEntita-ref-column"
    value="ID_ANAG"/>
         </field>
    </class>
    </package>
    </jdo>
    2 Indirizzo.jdo
    <?xml version="1.0"?>
    <!-- This JDO Metadata file was auto-generated on 08/10/02 17.21.
    See http://www.solarmetric.com for Kodo JDO Documentation and examples. -->
    <jdo>
    <package name="domain">
    <class name="Indirizzo"
    identity-type="application" objectid-class="domain.IndiPK">
    <extension key="table" value="INDI" vendor-name="kodo"/>
    <extension key="class-column" value="none" vendor-name="kodo"/>
    <extension key="lock-column" value="none" vendor-name="kodo"/>
    <!--extension vendor-name="kodo" key="idEntita-data-column"
    value="ID_ENTITA"/-->
    <field name="idIndi" primary-key="true">
    <extension key="data-column" value="ID_INDI"
    vendor-name="kodo"/>
    </field>
    <field name="idEntita">
    <extension key="data-column" value="ID_ENTITA"
    vendor-name="kodo"/>
    </field>
    <field name="tpEntita">
    <extension key="data-column" value="TP_ENTITA"
    vendor-name="kodo"/>
    </field>
    <field name="indirizzo">
    <extension key="data-column" value="INDIRIZZO"
    vendor-name="kodo"/>
    </field>
    <field name="localita">
    <extension key="data-column" value="LOCALITA"
    vendor-name="kodo"/>
    </field>
    <field name="prov">
    <extension key="data-column" value="PROV"
    vendor-name="kodo"/>
    </field>
    <field name="cap">
    <extension key="data-column" value="CAP"
    vendor-name="kodo"/>
    </field>
    <field name="anagrafica">
    <extension vendor-name="kodo" key="idAnag-data-column"
    value="ID_ENTITA"/>
    </field>
    </class>
    </package>
    </jdo>
    The problem is:
    I create a new Anagrafica object and then I try to save it in the
    database. These are the SQL
    statements that are generated:
    INSERT INTO ANAG(DT_NASC, COD_FISC, RAG_SOC_FONET, SESSO, ID_ANAG,
    RAG_SOC, COD_TIT)
    VALUES (NULL, NULL, 'NATALE', NULL, 971963921, 'Natale', NULL)
    INSERT INTO INDI(TP_ENTITA, PROV, LOCALITA, ID_ENTITA, ID_INDI, INDIRIZZO,
    CAP)
    VALUES (0, NULL, NULL, 0, 971963921, 'via 25 dicembre', NULL)
    Why is the value of ID_ANAG (971963921) assigned to ID_INDI and not to
    ID_ENTITA?
    Regards
    Mirko

    Abe White wrote:
    <field name="indis">
    <collection element-type="domain.Indirizzo"/>
    <extension vendor-name="kodo" key="table" value="INDI"/>
    <extension vendor-name="kodo" key="inverse"
    value="anagrafica"/>
    <extension vendor-name="kodo" key="idEntita-ref-column"
    value="ID_ANAG"/>
         </field>
    Get rid of all extensions except the inverse:
    <field name="indis">
    <collection element-type="domain.Indirizzo"/>
    <extension vendor-name="kodo" key="inverse" value="anagrafica"/>
    </field>
    As in the examples in our documentation, all 1-many relations should only
    list their inverse 1-1 relation.
    Also, make sure your object model is consistent; i.e. make sure you'resetting
    both sides of the relation:
    indi.setAnagrafica (anag);
    anag.getIndis ().add (indi);
    Let us know if you continue to have problems.Hi Abe,
    I got rid of the unnecessary extensions and I set both sides of the
    relation as you suggest but I still have the same problem:
    INSERT INTO ANAG(ID_ANAG) VALUES (2088176453)
    INSERT INTO INDI(ID_INDI, ID_ENTITA) VALUES (2088176453, NULL)
    while I expect
    INSERT INTO ANAG(ID_ANAG) VALUES (2088176453)
    INSERT INTO INDI(ID_INDI, ID_ENTITA) VALUES (<some ID>, 2088176453)
    any ideas?
    regards

  • Cant't get one to many relation to work.

    I tried to without success to retrieve an object that represents a simple
    parent child relation in an existing database. (the object is supposed to
    represent one record of the parent table and contain a Collection of all
    records in the child table)
    I have these two tables:
    table "refrul" is the parent table (column "nr" is the primary key)
    table "reftab" is the child (column "refundrule" points to refrul.nr)
    This is my .jdo file
    <?xml version="1.0"?>
    <jdo>
    <package name="jdbctest">
    <class name="RefundRule" objectid-class="RefundRuleId">
    <extension vendor-name="kodo" key="table" value="refrul"/>
    <extension vendor-name="kodo" key="lock-column" value="none"/>
    <extension vendor-name="kodo" key="class-column" value="none"/>
    <field name="ruleNr" primary-key="true">
    <extension vendor-name="kodo" key="data-column" value="nr"/>
    </field>
    <field name="ruleName">
    <extension vendor-name="kodo" key="data-column"
    value="name"/>
    </field>
    <field name="minSalesAmount">
    <extension vendor-name="kodo" key="data-column"
    value="minsalesamount"/>
    </field>
    <field name="refundTable">
    <collection element-type="RefundTableRow"/>
    <extension vendor-name="kodo" key="table" value="reftab"/>
    <extension vendor-name="kodo" key="ruleNr-ref-column"
    value="refundrule"/>
    </field>
    </class>
    <class name="RefundTableRow" objectid-class="RefundTableRowId">
    <extension vendor-name="kodo" key="table" value="reftab"/>
    <extension vendor-name="kodo" key="lock-column" value="none"/>
    <extension vendor-name="kodo" key="class-column" value="none"/>
    <field name="ruleNr" primary-key="true">
    <extension vendor-name="kodo" key="data-column"
    value="refundrule"/>
    </field>
    <field name="vatRate" primary-key="true">
    <extension vendor-name="kodo" key="data-column"
    value="ustsatz"/>
    </field>
    <field name="fromSalesAmount" primary-key="true">
    <extension vendor-name="kodo" key="data-column"
    value="ab_betrag"/>
    </field>
    <field name="refundPercent">
    <extension vendor-name="kodo" key="data-column"
    value="refund_prozent"/>
    </field>
    <field name="refundAmount">
    <extension vendor-name="kodo" key="data-column"
    value="refund_betrag"/>
    </field>
    </class>
    </package>
    </jdo>
    I get an exception showing this query:
    [SQL=SELECT t0.ab_betrag, t0.refundrule, t0.ustsatz, t0.refund_betrag,
    t0.refund_prozent, t0.RULENAMEX
    FROM reftab t0 WHERE(t0.refundrule = 0 AND t0.ab_betrag =
    t0.FROMSALESAMOUNT_REFUNDTABLEX AND t0.refundrule = t0.RULENR_REFUNDTABLEX
    AND t0.ustsatz = t0.VATRATE_REFUNDTABLEX)]
    All columns in uppercase do not exist in my tables, so this must generate an
    exception.
    Also the join seems strange I would have expected only " ...
    WHERE(t0.refundrule = parenttableRuleNr)".
    Whats wrong?
    I am using kodo 2.3
    Regards,
    Bernhard

    Abe,
    the strange column names are gone now, but it still does not work
    This is my new .jdo file (Iadded the "inverse" line)
    <?xml version="1.0"?>
    <jdo>
    <package name="jdbctest">
    <class name="RefundRule" objectid-class="RefundRuleId">
    <extension vendor-name="kodo" key="table" value="refrul"/>
    <extension vendor-name="kodo" key="lock-column" value="none"/>
    <extension vendor-name="kodo" key="class-column" value="none"/>
    <field name="ruleNr" primary-key="true">
    <extension vendor-name="kodo" key="data-column" value="nr"/>
    </field>
    <field name="ruleName">
    <extension vendor-name="kodo" key="data-column"
    value="name"/>
    </field>
    <field name="minSalesAmount">
    <extension vendor-name="kodo" key="data-column"
    value="minsalesamount"/>
    </field>
    <field name="refundStep">
    <extension vendor-name="kodo" key="data-column"
    value="refundstep"/>
    </field>
    <field name="refundTable">
    <collection element-type="RefundTableRow"/>
    <extension vendor-name="kodo" key="table" value="reftab"/>
    <extension vendor-name="kodo" key="ruleNr-ref-column"
    value="refundrule"/>
    <extension vendor-name="kodo" key="inverse" value="ruleNr"/>
    </field>
    </class>
    <class name="RefundTableRow" objectid-class="RefundTableRowId">
    <extension vendor-name="kodo" key="table" value="reftab"/>
    <extension vendor-name="kodo" key="lock-column" value="none"/>
    <extension vendor-name="kodo" key="class-column" value="none"/>
    <field name="ruleNr" primary-key="true">
    <extension vendor-name="kodo" key="data-column"
    value="refundrule"/>
    </field>
    <field name="vatRate" primary-key="true">
    <extension vendor-name="kodo" key="data-column"
    value="ustsatz"/>
    </field>
    <field name="fromSalesAmount" primary-key="true">
    <extension vendor-name="kodo" key="data-column"
    value="ab_betrag"/>
    </field>
    <field name="refundPercent">
    <extension vendor-name="kodo" key="data-column"
    value="refund_prozent"/>
    </field>
    <field name="refundAmount">
    <extension vendor-name="kodo" key="data-column"
    value="refund_betrag"/>
    </field>
    </class>
    </package>
    </jdo>
    This the generated SQL:
    [SQL=SELECT t0.nr, t0.minsalesamount, t0.refundstep, t0.name FROM refrul t0,
    reftab t1 WHERE (t0.nr = t1.nr)]
    This throws an exception because t1.nr (reftab.nr) does not exist, it should
    be reftab.refundrule. This would be correct:
    SELECT t0.nr, t0.minsalesamount, t0.refundstep, t0.name FROM refrul t0,
    reftab t1 WHERE (t0.nr = t1.refundrule)]
    Regards,
    Bernhard

Maybe you are looking for

  • Internal error in IGS0, US. COMMUNICATION FAILURE (RFC: GIS_GEOCODE_DEST:G

    Hi when we are trying to update Communication data of an external candidate.. We are getting this error message... Internal error in IGS0, US. COMMUNICATION FAILURE (RFC: GIS_GEOCODE_DEST:Geocode) Please let me know how to fix this error... Thanks Ra

  • JCA Adapter Less than Symbol in OSB 11.1.1.5

    Hey everyone, When trying to create a Business Service based off of a JCA Adapter created in JDeveloper for a custom query database call, I am having issues if the query has the less than symbol in it. When generating the service, it gives me the fol

  • Embed a pdf?

    Hello, I would like to link to a pdf - but instead of opening up full screen and a new browser - is there way to open it up so it stay embedded with in the portlet? I want to constrain the size to the layout - so for a 3 column layout, with the pdf i

  • MWA/MSCA Customization ERROR

    Dear all, My requirement is to Customize a Page where i have FListener & Page file but not able to find Function File I have checked the the menu>function>it adress to a different Function File... where on condition it is pointing to different Page .

  • Macbook Air Case - HELP

    Hello! I had my macbook air for about a month when it was splashed with water and completely died the cost of repair was 1300 more then the actual laptop. With this being said dose anyone know of a good WATERPROOF hard shell case of soft sleeve. I ha