You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@cayenne.apache.org by Scott Anderson <sa...@airvana.com> on 2008/05/13 00:25:26 UTC

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

Re: one-to-many problem

Posted by Andrus Adamchik <an...@objectstyle.org>.
On May 12, 2008, at 10:18 PM, Scott Anderson wrote:

> Seems like a pointless annotation; vaguely equivalent to the reverse  
> of the relationship being ON DELETE CASCADE.

Not really. It tells Cayenne which table owns the PK and which table  
borrows it from master. E.g. consider many-to-many cases with a join  
table.

Andrus

RE: one-to-many problem

Posted by Scott Anderson <sa...@airvana.com>.
Also worth noting: I still can't seem to crack my original problem. Can
anyone reproduce it?

-----Original Message-----
From: Scott Anderson [mailto:sanderson@airvana.com] 
Sent: Tuesday, May 13, 2008 5:16 PM
To: user@cayenne.apache.org
Subject: RE: one-to-many problem

That makes sense, but I still don't see how it's more than an
annotation. If a relationship exists, an instance of that relationship
is, by definition, where the values on each side of the relationship are
equal.

Can you provide an example of when the field makes a difference? Why
does Cayenne care which table is the master/slave? I can't see how
Cayenne's behavior would change in either a one-to-one or a many-to-many
relationship.

-----Original Message-----
From: Mike Kienenberger [mailto:mkienenb@gmail.com] 
Sent: Tuesday, May 13, 2008 1:03 PM
To: user@cayenne.apache.org
Subject: Re: one-to-many problem

It tells the Cayenne Runtime where to find/generate the value for the
PK.

Normally, they're generated by some "strategy" specified in the model,
or sometimes they are explicitly assigned by the application.

However, a dependent primary key (like a join table) has its primary
key value set with the value of the master primary key.

Ie,

a User/Account join table composed of USER_ID and ACCOUNT_ID, both
primary keys, needs to get the value for each from the primary key of
the USER table and the ACCOUNT table.   We don't want to generate one.
  We don't want to assign one.   We want it to pick up the existing
value and reuse it.

Hope this helps explain dependent primary keys better.

On 5/12/08, Scott Anderson <sa...@airvana.com> wrote:
> Seems like a pointless annotation; vaguely equivalent to the reverse
of the relationship being ON DELETE CASCADE.
>
>
>
>  -----Original Message-----
>  From: Mike Kienenberger [mailto:mkienenb@gmail.com]
>
> Sent: Mon 5/12/2008 7:16 PM
>  To: user@cayenne.apache.org
>  Subject: Re: one-to-many problem
>
>  Yeah, in retrospect it won't work because command.name isn't a pk.
>
>  http://cayenne.apache.org/doc12/to-dep-pk-checkbox.html should
explain
>  it fairly well.
>
>  On 5/12/08, Scott Anderson <sa...@airvana.com> wrote:
>  > Can't check the box. Can you explain what that does? I read the
>  >  documentation for it about 100 times and I still can't make heads
or
>  >  tails of it.
>  >
>  >
>  >  -----Original Message-----
>  >  From: Mike Kienenberger [mailto:mkienenb@gmail.com]
>  >  Sent: Monday, May 12, 2008 6:57 PM
>  >  To: user@cayenne.apache.org
>  >  Subject: Re: one-to-many problem
>  >
>  >  One thing you could try is to make command.name ->
command_alias.name
>  >  to-dependent-key=true if it's not already set that way.  Don't
know if
>  >  it'll help, though.
>  >
>  >
>  >  On 5/12/08, Scott Anderson <sa...@airvana.com> wrote:
>  >  > 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"/>
>  >  >
>  >
>
>

RE: one-to-many problem

Posted by Scott Anderson <sa...@airvana.com>.
That makes sense, but I still don't see how it's more than an
annotation. If a relationship exists, an instance of that relationship
is, by definition, where the values on each side of the relationship are
equal.

Can you provide an example of when the field makes a difference? Why
does Cayenne care which table is the master/slave? I can't see how
Cayenne's behavior would change in either a one-to-one or a many-to-many
relationship.

-----Original Message-----
From: Mike Kienenberger [mailto:mkienenb@gmail.com] 
Sent: Tuesday, May 13, 2008 1:03 PM
To: user@cayenne.apache.org
Subject: Re: one-to-many problem

It tells the Cayenne Runtime where to find/generate the value for the
PK.

Normally, they're generated by some "strategy" specified in the model,
or sometimes they are explicitly assigned by the application.

However, a dependent primary key (like a join table) has its primary
key value set with the value of the master primary key.

Ie,

a User/Account join table composed of USER_ID and ACCOUNT_ID, both
primary keys, needs to get the value for each from the primary key of
the USER table and the ACCOUNT table.   We don't want to generate one.
  We don't want to assign one.   We want it to pick up the existing
value and reuse it.

Hope this helps explain dependent primary keys better.

On 5/12/08, Scott Anderson <sa...@airvana.com> wrote:
> Seems like a pointless annotation; vaguely equivalent to the reverse
of the relationship being ON DELETE CASCADE.
>
>
>
>  -----Original Message-----
>  From: Mike Kienenberger [mailto:mkienenb@gmail.com]
>
> Sent: Mon 5/12/2008 7:16 PM
>  To: user@cayenne.apache.org
>  Subject: Re: one-to-many problem
>
>  Yeah, in retrospect it won't work because command.name isn't a pk.
>
>  http://cayenne.apache.org/doc12/to-dep-pk-checkbox.html should
explain
>  it fairly well.
>
>  On 5/12/08, Scott Anderson <sa...@airvana.com> wrote:
>  > Can't check the box. Can you explain what that does? I read the
>  >  documentation for it about 100 times and I still can't make heads
or
>  >  tails of it.
>  >
>  >
>  >  -----Original Message-----
>  >  From: Mike Kienenberger [mailto:mkienenb@gmail.com]
>  >  Sent: Monday, May 12, 2008 6:57 PM
>  >  To: user@cayenne.apache.org
>  >  Subject: Re: one-to-many problem
>  >
>  >  One thing you could try is to make command.name ->
command_alias.name
>  >  to-dependent-key=true if it's not already set that way.  Don't
know if
>  >  it'll help, though.
>  >
>  >
>  >  On 5/12/08, Scott Anderson <sa...@airvana.com> wrote:
>  >  > 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"/>
>  >  >
>  >
>
>

Re: one-to-many problem

Posted by Mike Kienenberger <mk...@gmail.com>.
It tells the Cayenne Runtime where to find/generate the value for the PK.

Normally, they're generated by some "strategy" specified in the model,
or sometimes they are explicitly assigned by the application.

However, a dependent primary key (like a join table) has its primary
key value set with the value of the master primary key.

Ie,

a User/Account join table composed of USER_ID and ACCOUNT_ID, both
primary keys, needs to get the value for each from the primary key of
the USER table and the ACCOUNT table.   We don't want to generate one.
  We don't want to assign one.   We want it to pick up the existing
value and reuse it.

Hope this helps explain dependent primary keys better.

On 5/12/08, Scott Anderson <sa...@airvana.com> wrote:
> Seems like a pointless annotation; vaguely equivalent to the reverse of the relationship being ON DELETE CASCADE.
>
>
>
>  -----Original Message-----
>  From: Mike Kienenberger [mailto:mkienenb@gmail.com]
>
> Sent: Mon 5/12/2008 7:16 PM
>  To: user@cayenne.apache.org
>  Subject: Re: one-to-many problem
>
>  Yeah, in retrospect it won't work because command.name isn't a pk.
>
>  http://cayenne.apache.org/doc12/to-dep-pk-checkbox.html should explain
>  it fairly well.
>
>  On 5/12/08, Scott Anderson <sa...@airvana.com> wrote:
>  > Can't check the box. Can you explain what that does? I read the
>  >  documentation for it about 100 times and I still can't make heads or
>  >  tails of it.
>  >
>  >
>  >  -----Original Message-----
>  >  From: Mike Kienenberger [mailto:mkienenb@gmail.com]
>  >  Sent: Monday, May 12, 2008 6:57 PM
>  >  To: user@cayenne.apache.org
>  >  Subject: Re: one-to-many problem
>  >
>  >  One thing you could try is to make command.name -> command_alias.name
>  >  to-dependent-key=true if it's not already set that way.  Don't know if
>  >  it'll help, though.
>  >
>  >
>  >  On 5/12/08, Scott Anderson <sa...@airvana.com> wrote:
>  >  > 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"/>
>  >  >
>  >
>
>

RE: one-to-many problem

Posted by Scott Anderson <sa...@airvana.com>.
Seems like a pointless annotation; vaguely equivalent to the reverse of the relationship being ON DELETE CASCADE.


-----Original Message-----
From: Mike Kienenberger [mailto:mkienenb@gmail.com]
Sent: Mon 5/12/2008 7:16 PM
To: user@cayenne.apache.org
Subject: Re: one-to-many problem
 
Yeah, in retrospect it won't work because command.name isn't a pk.

http://cayenne.apache.org/doc12/to-dep-pk-checkbox.html should explain
it fairly well.

On 5/12/08, Scott Anderson <sa...@airvana.com> wrote:
> Can't check the box. Can you explain what that does? I read the
>  documentation for it about 100 times and I still can't make heads or
>  tails of it.
>
>
>  -----Original Message-----
>  From: Mike Kienenberger [mailto:mkienenb@gmail.com]
>  Sent: Monday, May 12, 2008 6:57 PM
>  To: user@cayenne.apache.org
>  Subject: Re: one-to-many problem
>
>  One thing you could try is to make command.name -> command_alias.name
>  to-dependent-key=true if it's not already set that way.  Don't know if
>  it'll help, though.
>
>
>  On 5/12/08, Scott Anderson <sa...@airvana.com> wrote:
>  > 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"/>
>  >
>


Re: one-to-many problem

Posted by Mike Kienenberger <mk...@gmail.com>.
Yeah, in retrospect it won't work because command.name isn't a pk.

http://cayenne.apache.org/doc12/to-dep-pk-checkbox.html should explain
it fairly well.

On 5/12/08, Scott Anderson <sa...@airvana.com> wrote:
> Can't check the box. Can you explain what that does? I read the
>  documentation for it about 100 times and I still can't make heads or
>  tails of it.
>
>
>  -----Original Message-----
>  From: Mike Kienenberger [mailto:mkienenb@gmail.com]
>  Sent: Monday, May 12, 2008 6:57 PM
>  To: user@cayenne.apache.org
>  Subject: Re: one-to-many problem
>
>  One thing you could try is to make command.name -> command_alias.name
>  to-dependent-key=true if it's not already set that way.  Don't know if
>  it'll help, though.
>
>
>  On 5/12/08, Scott Anderson <sa...@airvana.com> wrote:
>  > 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"/>
>  >
>

RE: one-to-many problem

Posted by Scott Anderson <sa...@airvana.com>.
Can't check the box. Can you explain what that does? I read the
documentation for it about 100 times and I still can't make heads or
tails of it.

-----Original Message-----
From: Mike Kienenberger [mailto:mkienenb@gmail.com] 
Sent: Monday, May 12, 2008 6:57 PM
To: user@cayenne.apache.org
Subject: Re: one-to-many problem

One thing you could try is to make command.name -> command_alias.name
to-dependent-key=true if it's not already set that way.  Don't know if
it'll help, though.


On 5/12/08, Scott Anderson <sa...@airvana.com> wrote:
> 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"/>
>

Re: one-to-many problem

Posted by Mike Kienenberger <mk...@gmail.com>.
One thing you could try is to make command.name -> command_alias.name
to-dependent-key=true if it's not already set that way.  Don't know if
it'll help, though.


On 5/12/08, Scott Anderson <sa...@airvana.com> wrote:
> 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"/>
>

Re: one-to-many problem

Posted by Andrus Adamchik <an...@objectstyle.org>.
I think a Jira along the lines of "Propagation of Dependent non-PK  
value doesn't work" that contains your mapping and a sample code would  
be a good start.

Andrus

On May 16, 2008, at 11:39 AM, Scott Anderson wrote:

> 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:andrus@objectstyle.org]
> Sent: Friday, May 16, 2008 11:33 AM
> To: user@cayenne.apache.org
> 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:sanderson@airvana.com]
>> Sent: Monday, May 12, 2008 6:25 PM
>> To: user@cayenne.apache.org
>> 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"/>
>>
>
>


RE: one-to-many problem

Posted by Scott Anderson <sa...@airvana.com>.
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:andrus@objectstyle.org] 
Sent: Friday, May 16, 2008 11:33 AM
To: user@cayenne.apache.org
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:sanderson@airvana.com]
> Sent: Monday, May 12, 2008 6:25 PM
> To: user@cayenne.apache.org
> 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"/>
>


Re: one-to-many problem

Posted by Andrus Adamchik <an...@objectstyle.org>.
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:sanderson@airvana.com]
> Sent: Monday, May 12, 2008 6:25 PM
> To: user@cayenne.apache.org
> 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"/>
>


RE: one-to-many problem

Posted by Scott Anderson <sa...@airvana.com>.
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:sanderson@airvana.com] 
Sent: Monday, May 12, 2008 6:25 PM
To: user@cayenne.apache.org
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"/>