Yes, that also worked from a design perspective, but would have required fixing some otherwise broken application logic. Because the command_alias table is only touched upon user-input, and when that happens, it's only one SELECT, there is no performance argument, so I went the easier fix :)
In any case, I'd be happy to write a test case to prove the problem exists if someone could point me at an example of how you normally do it. -----Original Message----- From: Andrus Adamchik [mailto:[EMAIL PROTECTED] Sent: Friday, May 16, 2008 11:33 AM To: [email protected] Subject: Re: one-to-many problem Sorry I didn't have a chance to investigate this more deeply. I think you can also tag both columns as a compound PK. Andrus On May 16, 2008, at 11:28 AM, Scott Anderson wrote: > 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"/> >
