You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@cayenne.apache.org by JR Ruggentaler <JR...@mpv.com> on 2007/02/20 07:56:24 UTC

Model many to many

I am having some trouble modeling many to many relationships with
Cayenne Modeler:

Author<<--AuthorBook-->>Book

I am using MySQL 5.x inoDB. The schema defines the foreign keys but when
I generate classes with CayenneModeler the output code seems to be
missing the to many accessor and setter. Shouldn't Modeler generate a
method in _Author to allow adding Books to Author? Instead Modeler
generated method addToAuthorBookArray(com.test.app.AuthorBook obj) which
adds objects from the join table instead. Does reversengineering the
database with Cayenne modeler work for to many relationships or do I
need to edit/update the model after "Reengineer Database Schema"? I
downloaded 2.0.2 and looked in the source for and example of many to
many but didn't find any example. Is there an example model for many to
many? Below I appended _Author, the model and the DDL.

package com.test.app.auto;

import java.util.List;

/** Class _Author was generated by Cayenne.
  * It is probably a good idea to avoid changing this class manually, 
  * since it may be overwritten next time code is regenerated. 
  * If you need to make any customizations, please use subclass. 
  */
public class _Author extends org.apache.cayenne.CayenneDataObject {

    public static final String NAME_PROPERTY = "name";
    public static final String AUTHOR_BOOK_ARRAY_PROPERTY =
"authorBookArray";

    public static final String AUTHOR_ID_PK_COLUMN = "AUTHOR_ID";

    public void setName(String name) {
        writeProperty("name", name);
    }
    public String getName() {
        return (String)readProperty("name");
    }
    
    
    public void addToAuthorBookArray(com.test.app.AuthorBook obj) {
        addToManyTarget("authorBookArray", obj, true);
    }
    public void removeFromAuthorBookArray(com.test.app.AuthorBook obj) {
        removeToManyTarget("authorBookArray", obj, true);
    }
    public List getAuthorBookArray() {
        return (List)readProperty("authorBookArray");
    }
    
    
}

Model
<?xml version="1.0" encoding="utf-8"?>
<data-map project-version="2.0">
	<property name="defaultPackage" value="com.test.app"/>
	<db-entity name="author" catalog="test">
		<db-attribute name="AUTHOR_ID" type="BIGINT"
isPrimaryKey="true" isMandatory="true" length="10"/>
		<db-attribute name="NAME" type="VARCHAR"
isMandatory="true" length="45"/>
	</db-entity>
	<db-entity name="author_book" catalog="test">
		<db-attribute name="AUTHOR_ID" type="BIGINT"
isPrimaryKey="true" isMandatory="true" length="10"/>
		<db-attribute name="BOOK_ID" type="BIGINT"
isPrimaryKey="true" isMandatory="true" length="10"/>
	</db-entity>
	<db-entity name="book" catalog="test">
		<db-attribute name="BOOK_ID" type="BIGINT"
isPrimaryKey="true" isMandatory="true" length="10"/>
		<db-attribute name="TITLE" type="VARCHAR"
isMandatory="true" length="45"/>
	</db-entity>
	<obj-entity name="Author" className="com.test.app.Author"
dbEntityName="author">
		<obj-attribute name="name" type="java.lang.String"
db-attribute-path="NAME"/>
	</obj-entity>
	<obj-entity name="AuthorBook"
className="com.test.app.AuthorBook" dbEntityName="author_book">
	</obj-entity>
	<obj-entity name="Book" className="com.test.app.Book"
dbEntityName="book">
		<obj-attribute name="title" type="java.lang.String"
db-attribute-path="TITLE"/>
	</obj-entity>
	<db-relationship name="authorBookArray" source="author"
target="author_book" toDependentPK="true" toMany="true">
		<db-attribute-pair source="AUTHOR_ID"
target="AUTHOR_ID"/>
	</db-relationship>
	<db-relationship name="toAuthor" source="author_book"
target="author" toMany="false">
		<db-attribute-pair source="AUTHOR_ID"
target="AUTHOR_ID"/>
	</db-relationship>
	<db-relationship name="toBook" source="author_book"
target="book" toMany="false">
		<db-attribute-pair source="BOOK_ID" target="BOOK_ID"/>
	</db-relationship>
	<db-relationship name="authorBookArray" source="book"
target="author_book" toDependentPK="true" toMany="true">
		<db-attribute-pair source="BOOK_ID" target="BOOK_ID"/>
	</db-relationship>
	<obj-relationship name="authorBookArray" source="Author"
target="AuthorBook" db-relationship-path="authorBookArray"/>
	<obj-relationship name="toAuthor" source="AuthorBook"
target="Author" db-relationship-path="toAuthor"/>
	<obj-relationship name="toBook" source="AuthorBook"
target="Book" db-relationship-path="toBook"/>
	<obj-relationship name="authorBookArray" source="Book"
target="AuthorBook" db-relationship-path="authorBookArray"/>
</data-map>

-- DDL
CREATE TABLE author ( 
    AUTHOR_ID	int(10) AUTO_INCREMENT NOT NULL,
    NAME     	varchar(45) NOT NULL,
    PRIMARY KEY(AUTHOR_ID)
)
;
CREATE UNIQUE INDEX PRIMARY
    ON author(AUTHOR_ID)
;


CREATE TABLE book ( 
    BOOK_ID	int(10) AUTO_INCREMENT NOT NULL,
    TITLE  	varchar(45) NOT NULL,
    PRIMARY KEY(BOOK_ID)
)
;
CREATE UNIQUE INDEX PRIMARY
    ON book(BOOK_ID)
;


CREATE TABLE author_book ( 
    AUTHOR_ID	int(10) NOT NULL DEFAULT '0',
    BOOK_ID  	int(10) NOT NULL,
    PRIMARY KEY(AUTHOR_ID,BOOK_ID)
)
;
ALTER TABLE author_book
    ADD CONSTRAINT FK_AUTHOR_ID
	FOREIGN KEY(AUTHOR_ID)
	REFERENCES author(AUTHOR_ID)
;
ALTER TABLE author_book
    ADD CONSTRAINT FK_BOOK_ID
	FOREIGN KEY(BOOK_ID)
	REFERENCES book(BOOK_ID)
;
CREATE INDEX FK_BOOK_ID
    ON author_book(BOOK_ID)
;
CREATE UNIQUE INDEX PRIMARY
    ON author_book(AUTHOR_ID, BOOK_ID)
;

Re: Model many to many

Posted by Andrus Adamchik <an...@objectstyle.org>.
By default Cayenne creates "unflattened" view of the database. You  
will need to manually flatten the relationships:

http://cayenne.apache.org/doc/cayennemodeler-flattened- 
relationships.html

Andrus


On Feb 20, 2007, at 9:56 AM, JR Ruggentaler wrote:

> I am having some trouble modeling many to many relationships with
> Cayenne Modeler:
>
> Author<<--AuthorBook-->>Book
>
> I am using MySQL 5.x inoDB. The schema defines the foreign keys but  
> when
> I generate classes with CayenneModeler the output code seems to be
> missing the to many accessor and setter. Shouldn't Modeler generate a
> method in _Author to allow adding Books to Author? Instead Modeler
> generated method addToAuthorBookArray(com.test.app.AuthorBook obj)  
> which
> adds objects from the join table instead. Does reversengineering the
> database with Cayenne modeler work for to many relationships or do I
> need to edit/update the model after "Reengineer Database Schema"? I
> downloaded 2.0.2 and looked in the source for and example of many to
> many but didn't find any example. Is there an example model for  
> many to
> many? Below I appended _Author, the model and the DDL.
>
> package com.test.app.auto;
>
> import java.util.List;
>
> /** Class _Author was generated by Cayenne.
>   * It is probably a good idea to avoid changing this class manually,
>   * since it may be overwritten next time code is regenerated.
>   * If you need to make any customizations, please use subclass.
>   */
> public class _Author extends org.apache.cayenne.CayenneDataObject {
>
>     public static final String NAME_PROPERTY = "name";
>     public static final String AUTHOR_BOOK_ARRAY_PROPERTY =
> "authorBookArray";
>
>     public static final String AUTHOR_ID_PK_COLUMN = "AUTHOR_ID";
>
>     public void setName(String name) {
>         writeProperty("name", name);
>     }
>     public String getName() {
>         return (String)readProperty("name");
>     }
>
>
>     public void addToAuthorBookArray(com.test.app.AuthorBook obj) {
>         addToManyTarget("authorBookArray", obj, true);
>     }
>     public void removeFromAuthorBookArray(com.test.app.AuthorBook  
> obj) {
>         removeToManyTarget("authorBookArray", obj, true);
>     }
>     public List getAuthorBookArray() {
>         return (List)readProperty("authorBookArray");
>     }
>
>
> }
>
> Model
> <?xml version="1.0" encoding="utf-8"?>
> <data-map project-version="2.0">
> 	<property name="defaultPackage" value="com.test.app"/>
> 	<db-entity name="author" catalog="test">
> 		<db-attribute name="AUTHOR_ID" type="BIGINT"
> isPrimaryKey="true" isMandatory="true" length="10"/>
> 		<db-attribute name="NAME" type="VARCHAR"
> isMandatory="true" length="45"/>
> 	</db-entity>
> 	<db-entity name="author_book" catalog="test">
> 		<db-attribute name="AUTHOR_ID" type="BIGINT"
> isPrimaryKey="true" isMandatory="true" length="10"/>
> 		<db-attribute name="BOOK_ID" type="BIGINT"
> isPrimaryKey="true" isMandatory="true" length="10"/>
> 	</db-entity>
> 	<db-entity name="book" catalog="test">
> 		<db-attribute name="BOOK_ID" type="BIGINT"
> isPrimaryKey="true" isMandatory="true" length="10"/>
> 		<db-attribute name="TITLE" type="VARCHAR"
> isMandatory="true" length="45"/>
> 	</db-entity>
> 	<obj-entity name="Author" className="com.test.app.Author"
> dbEntityName="author">
> 		<obj-attribute name="name" type="java.lang.String"
> db-attribute-path="NAME"/>
> 	</obj-entity>
> 	<obj-entity name="AuthorBook"
> className="com.test.app.AuthorBook" dbEntityName="author_book">
> 	</obj-entity>
> 	<obj-entity name="Book" className="com.test.app.Book"
> dbEntityName="book">
> 		<obj-attribute name="title" type="java.lang.String"
> db-attribute-path="TITLE"/>
> 	</obj-entity>
> 	<db-relationship name="authorBookArray" source="author"
> target="author_book" toDependentPK="true" toMany="true">
> 		<db-attribute-pair source="AUTHOR_ID"
> target="AUTHOR_ID"/>
> 	</db-relationship>
> 	<db-relationship name="toAuthor" source="author_book"
> target="author" toMany="false">
> 		<db-attribute-pair source="AUTHOR_ID"
> target="AUTHOR_ID"/>
> 	</db-relationship>
> 	<db-relationship name="toBook" source="author_book"
> target="book" toMany="false">
> 		<db-attribute-pair source="BOOK_ID" target="BOOK_ID"/>
> 	</db-relationship>
> 	<db-relationship name="authorBookArray" source="book"
> target="author_book" toDependentPK="true" toMany="true">
> 		<db-attribute-pair source="BOOK_ID" target="BOOK_ID"/>
> 	</db-relationship>
> 	<obj-relationship name="authorBookArray" source="Author"
> target="AuthorBook" db-relationship-path="authorBookArray"/>
> 	<obj-relationship name="toAuthor" source="AuthorBook"
> target="Author" db-relationship-path="toAuthor"/>
> 	<obj-relationship name="toBook" source="AuthorBook"
> target="Book" db-relationship-path="toBook"/>
> 	<obj-relationship name="authorBookArray" source="Book"
> target="AuthorBook" db-relationship-path="authorBookArray"/>
> </data-map>
>
> -- DDL
> CREATE TABLE author (
>     AUTHOR_ID	int(10) AUTO_INCREMENT NOT NULL,
>     NAME     	varchar(45) NOT NULL,
>     PRIMARY KEY(AUTHOR_ID)
> )
> ;
> CREATE UNIQUE INDEX PRIMARY
>     ON author(AUTHOR_ID)
> ;
>
>
> CREATE TABLE book (
>     BOOK_ID	int(10) AUTO_INCREMENT NOT NULL,
>     TITLE  	varchar(45) NOT NULL,
>     PRIMARY KEY(BOOK_ID)
> )
> ;
> CREATE UNIQUE INDEX PRIMARY
>     ON book(BOOK_ID)
> ;
>
>
> CREATE TABLE author_book (
>     AUTHOR_ID	int(10) NOT NULL DEFAULT '0',
>     BOOK_ID  	int(10) NOT NULL,
>     PRIMARY KEY(AUTHOR_ID,BOOK_ID)
> )
> ;
> ALTER TABLE author_book
>     ADD CONSTRAINT FK_AUTHOR_ID
> 	FOREIGN KEY(AUTHOR_ID)
> 	REFERENCES author(AUTHOR_ID)
> ;
> ALTER TABLE author_book
>     ADD CONSTRAINT FK_BOOK_ID
> 	FOREIGN KEY(BOOK_ID)
> 	REFERENCES book(BOOK_ID)
> ;
> CREATE INDEX FK_BOOK_ID
>     ON author_book(BOOK_ID)
> ;
> CREATE UNIQUE INDEX PRIMARY
>     ON author_book(AUTHOR_ID, BOOK_ID)
> ;