I was able to work around this by removing command.id from the model and changing command.name to the PK. This seems to work transparently, since the id column is auto-generated by the DB in the existing schema.
In any case, it sounds like a bug to me. I definitely can't think of any reason why the way I had it shouldn't work. -----Original Message----- From: Scott Anderson [mailto:[EMAIL PROTECTED] Sent: Monday, May 12, 2008 6:25 PM To: [email protected] Subject: one-to-many problem I've got a table `command which has: `id` int PK `name` varchar(32) UNIQUE and a table `command_alias` which has `alias` varchar(32) PK `name` varchar(32) FK REF `command`.`name` Take special note how `command_alias`.`name` is a FK to `command`.`name` (unique field) and not `command`.`id` (the PK) The following code chokes: public static CommandAlias create(Command command, String alias) { CommandAlias ca = DatabaseContext.getContext().newObject(CommandAlias.class); ca.setAlias(alias); ca.setToCommand(command); command.addToAliases(ca); try { ca.updateRow(); return ca; } catch(Exception e) { Out.exception(e); return null; } } With the error: May 12, 2008 6:15:55 PM org.apache.cayenne.access.QueryLogger logQuery INFO: INSERT INTO command_alias (alias, name) VALUES (?, ?) INFO: [batch bind: 1->alias:'aa', 2->name:NULL] May 12, 2008 6:15:55 PM org.apache.cayenne.access.QueryLogger logQueryError INFO: *** error. java.sql.SQLIntegrityConstraintViolationException: Column 'NAME' cannot accept a NULL value. I am 100% sure that I am not sending a null Command object. I believe this stems from the fact that the relationship is not a FK-PK relationship, but a FK-UNIQUE relationship, as evidenced by the fact that if I make the `command_alias`.`name` field visible in the code, and set do ca.setName(command.getName()) then this error does not occur. I am using a 3.0 snapshot from March. And here's the relevant sections of my mapping file (I removed some unrelated fields from command): <db-entity name="command"> <db-attribute name="id" type="INTEGER" isPrimaryKey="true" isGenerated="true" isMandatory="true" length="11"/> <db-attribute name="name" type="VARCHAR" isMandatory="true" length="32"/> </db-entity> <db-entity name="command_alias"> <db-attribute name="alias" type="VARCHAR" isPrimaryKey="true" isMandatory="true" length="32"/> <db-attribute name="name" type="VARCHAR" length="32"/> </db-entity> <obj-entity name="Command" className="net.bnubot.db.Command" dbEntityName="command" superClassName="net.bnubot.db.CustomDataObject"> <obj-attribute name="name" type="java.lang.String" db-attribute-path="name"/> </obj-entity> <obj-entity name="CommandAlias" className="net.bnubot.db.CommandAlias" dbEntityName="command_alias" superClassName="net.bnubot.db.CustomDataObject"> <obj-attribute name="alias" type="java.lang.String" db-attribute-path="alias"/> </obj-entity> <db-relationship name="commandAliasArray" source="command" target="command_alias" toMany="true"> <db-attribute-pair source="name" target="name"/> </db-relationship> <db-relationship name="toCommand" source="command_alias" target="command" toMany="false"> <db-attribute-pair source="name" target="name"/> </db-relationship> <obj-relationship name="aliases" source="Command" target="CommandAlias" deleteRule="Deny" db-relationship-path="commandAliasArray"/> <obj-relationship name="toCommand" source="CommandAlias" target="Command" db-relationship-path="toCommand"/>
