Can't add an element. Why?

From: Mike Elliott (hbredne..arthlink.net)
Date: Fri May 21 2004 - 14:27:23 EDT

  • Next message: Andrus Adamchik: "Re: Can't add an element. Why?"

    I've set up (using Cayenne 1.1M6) the canonical three-table database of artist (with name),
    exhibit (with name) and artist-exhibit link table. I created a flattened relationship between
    artist and exhibit. The Cayenne-generated classes are at the end of the message, but in
    summary what I think I _should_ be able to do is something like the following to add a link
    between Dali and Dallas:

    Artist dali = fetchArtist( "Dali" );
    Exhibit dallas = fetchExhibit( "Dallas" );
    dali.addToExhibitList( dallas );

    That, however, fails immediately with a message:

    Cannot set the read-only flattened relationship exhibitList

    OK, the relationship is read-only. Why? I didn't ask it to be read-only and indeed, a
    read-only relationship won't work for me, I need to be able to change it. Are all flattened
    relationships read-only? If so, how do they get created in the first place? if not, how
    do I get around this? If the relationship is read-only, why is a method generated solely
    for the modification of it which, whenever it is run, merely throws an exception saying
    it can't do anything?

    I then attempted to manually add a linkage as follows:

          List list = dali.getExhibitList();
          assertEquals( 0, list.size() );

          JoinArtistExhibit join = (JoinArtistExhibit)dali.getDataContext()
               .createAndRegisterNewObject( "JoinArtistExhibit" );
          join.setToArtist( dali );
          dali.addToToExhibitLink( join );
          join.setToExhibit( dallas );
          dallas.addToToArtistLink( join );
          join.getDataContext().commitChanges( Level.WARN );

          list = dali.getExhibitList();
          System.out.println( "list.size() is " + list.size() );

    When this is run, I get the following output:

    WARN QueryLogger: --- will run 1 query.
    WARN QueryLogger: INSERT INTO join_artist_exhibit (artist_pk, exhibit_pk, pk) VALUES (?, ?, ?)
    WARN QueryLogger: [batch bind: 820, 822, 640]
    WARN QueryLogger: === updated 1 row.
    list.size() is 0

    So, I can add a link table entry to the database (inspection confirms that the row in the link
    table was added) but when I try to fetch the list after adding an element I get a zero-length
    list. Do I have to do something extra to force synchronization? If I run the code a second
    time, the list comes back with length 1, presumably containing the correct exhibit.

    Shutting down the program then restarting in order to synchronize is obviously unworkable,
    so what do I need to do in order to be able to use these methods?

    ---------------------------------------------------------------------

    public class _Artist extends org.objectstyle.cayenne.CayenneDataObject {

        public static final String NAME_PROPERTY = "name";
        public static final String EXHIBIT_LIST_PROPERTY = "exhibitList";
        public static final String TO_EXHIBIT_LINK_PROPERTY = "toExhibitLink";

        public static final String PK_PK_COLUMN = "pk";

        public void setName(String name) {
            writeProperty("name", name);
        }
        public String getName() {
            return (String)readProperty("name");
        }
        
        
        public void addToExhibitList(flat.Exhibit obj) {
            addToManyTarget("exhibitList", obj, true);
        }
        public void removeFromExhibitList(flat.Exhibit obj) {
            removeToManyTarget("exhibitList", obj, true);
        }
        public List getExhibitList() {
            return (List)readProperty("exhibitList");
        }
        
        
        public void addToToExhibitLink(flat.JoinArtistExhibit obj) {
            addToManyTarget("toExhibitLink", obj, true);
        }
        public void removeFromToExhibitLink(flat.JoinArtistExhibit obj) {
            removeToManyTarget("toExhibitLink", obj, true);
        }
        public List getToExhibitLink() {
            return (List)readProperty("toExhibitLink");
        }
        
        
    }

    public class _Exhibit extends org.objectstyle.cayenne.CayenneDataObject {

        public static final String NAME_PROPERTY = "name";
        public static final String ARTIST_LIST_PROPERTY = "artistList";
        public static final String TO_ARTIST_LINK_PROPERTY = "toArtistLink";

        public static final String PK_PK_COLUMN = "pk";

        public void setName(String name) {
            writeProperty("name", name);
        }
        public String getName() {
            return (String)readProperty("name");
        }
        
        
        public void addToArtistList(flat.Artist obj) {
            addToManyTarget("artistList", obj, true);
        }
        public void removeFromArtistList(flat.Artist obj) {
            removeToManyTarget("artistList", obj, true);
        }
        public List getArtistList() {
            return (List)readProperty("artistList");
        }
        
        
        public void addToToArtistLink(flat.JoinArtistExhibit obj) {
            addToManyTarget("toArtistLink", obj, true);
        }
        public void removeFromToArtistLink(flat.JoinArtistExhibit obj) {
            removeToManyTarget("toArtistLink", obj, true);
        }
        public List getToArtistLink() {
            return (List)readProperty("toArtistLink");
        }
        
        
    }

    public class _JoinArtistExhibit extends org.objectstyle.cayenne.CayenneDataObject {

        public static final String TO_ARTIST_PROPERTY = "toArtist";
        public static final String TO_EXHIBIT_PROPERTY = "toExhibit";

        public static final String PK_PK_COLUMN = "pk";

        public void setToArtist(flat.Artist toArtist) {
            setToOneTarget("toArtist", toArtist, true);
        }

        public flat.Artist getToArtist() {
            return (flat.Artist)readProperty("toArtist");
        }
        
        
        public void setToExhibit(flat.Exhibit toExhibit) {
            setToOneTarget("toExhibit", toExhibit, true);
        }

        public flat.Exhibit getToExhibit() {
            return (flat.Exhibit)readProperty("toExhibit");
        }
        
        
    }

    <?xml version="1.0" encoding="utf-8"?>
    <data-map project-version="1.1">
            <db-entity name="artist">
                    <db-attribute name="name" type="VARCHAR" isMandatory="true" length="30"/>
                    <db-attribute name="pk" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
            </db-entity>
            <db-entity name="exhibit">
                    <db-attribute name="name" type="VARCHAR" isMandatory="true" length="30"/>
                    <db-attribute name="pk" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
            </db-entity>
            <db-entity name="join_artist_exhibit">
                    <db-attribute name="artist_pk" type="INTEGER" isMandatory="true"/>
                    <db-attribute name="exhibit_pk" type="INTEGER" isMandatory="true"/>
                    <db-attribute name="pk" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
            </db-entity>
            <obj-entity name="Artist" className="flat.Artist" dbEntityName="artist">
                    <obj-attribute name="name" type="java.lang.String" db-attribute-path="name"/>
            </obj-entity>
            <obj-entity name="Exhibit" className="flat.Exhibit" dbEntityName="exhibit">
                    <obj-attribute name="name" type="java.lang.String" db-attribute-path="name"/>
            </obj-entity>
            <obj-entity name="JoinArtistExhibit" className="flat.JoinArtistExhibit" dbEntityName="join_artist_exhibit">
            </obj-entity>
            <db-relationship name="toExhibitLink" source="artist" target="join_artist_exhibit" toDependentPK="false" toMany="true">
                    <db-attribute-pair source="pk" target="artist_pk"/>
            </db-relationship>
            <db-relationship name="toArtistLink" source="exhibit" target="join_artist_exhibit" toDependentPK="false" toMany="true">
                    <db-attribute-pair source="pk" target="exhibit_pk"/>
            </db-relationship>
            <db-relationship name="toArtist" source="join_artist_exhibit" target="artist" toDependentPK="false" toMany="false">
                    <db-attribute-pair source="artist_pk" target="pk"/>
            </db-relationship>
            <db-relationship name="toExhibit" source="join_artist_exhibit" target="exhibit" toDependentPK="false" toMany="false">
                    <db-attribute-pair source="exhibit_pk" target="pk"/>
            </db-relationship>
            <obj-relationship name="exhibitList" source="Artist" target="Exhibit">
                    <db-relationship-ref source="artist" target="join_artist_exhibit" name="toExhibitLink"/>
                    <db-relationship-ref source="join_artist_exhibit" target="exhibit" name="toExhibit"/>
            </obj-relationship>
            <obj-relationship name="toExhibitLink" source="Artist" target="JoinArtistExhibit">
                    <db-relationship-ref source="artist" target="join_artist_exhibit" name="toExhibitLink"/>
            </obj-relationship>
            <obj-relationship name="artistList" source="Exhibit" target="Artist">
                    <db-relationship-ref source="exhibit" target="join_artist_exhibit" name="toArtistLink"/>
                    <db-relationship-ref source="join_artist_exhibit" target="artist" name="toArtist"/>
            </obj-relationship>
            <obj-relationship name="toArtistLink" source="Exhibit" target="JoinArtistExhibit">
                    <db-relationship-ref source="exhibit" target="join_artist_exhibit" name="toArtistLink"/>
            </obj-relationship>
            <obj-relationship name="toArtist" source="JoinArtistExhibit" target="Artist">
                    <db-relationship-ref source="join_artist_exhibit" target="artist" name="toArtist"/>
            </obj-relationship>
            <obj-relationship name="toExhibit" source="JoinArtistExhibit" target="Exhibit">
                    <db-relationship-ref source="join_artist_exhibit" target="exhibit" name="toExhibit"/>
            </obj-relationship>
    </data-map>



    This archive was generated by hypermail 2.0.0 : Fri May 21 2004 - 14:27:28 EDT