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"/>
>

Reply via email to