You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@cayenne.apache.org by Michael Shea <mi...@nitido.com> on 2008/11/20 00:10:32 UTC

Order of commits?

Hi guys -

I am wondering if there is any way to tell cayenne what order to commit 
new objects in.

My issue is basically like this:

Suppose I have Category objects and Item objects.

A user can pass in a CategoryDescriptor, which contains a list of 
ItemDescriptors. I want cayenne to generate, from these descriptors, the 
corresponding database-model objects and rows in the database. So I do 
something like this:

public Category createCategory( CategoryDescriptor categoryDescriptor )
{
    Context context = ...; // do something to get the context here.
    Category category = context.newObject( Category.class );
    .... // fill in stuff about the category object here.
    for ( ItemDescriptor itemDescriptor : 
categoryDescriptor.getItemDescriptors() )
    {
       Item item = context.newObject( Item.class );
       ... // fill in stuff about the item object here.
    }
    context.commitChanges();
    return Category;
}

The problem I am having is that both Category and Item have primary keys 
which are autogenerated by database (I am using MySQL, the ID's are 
generated via AUTO_INCREMENT columns). It looks like cayenne is 
attempting to create the Item objects before creating the Category 
object, and then it's giving me a commit exception like this:

org.apache.cayenne.CayenneRuntimeException: [v.3.0M4 May 18 2008 
16:32:02] Commit Exception
    at 
org.apache.cayenne.access.DataContext.flushToParent(DataContext.java:1192)
    at 
org.apache.cayenne.access.DataContext.commitChanges(DataContext.java:1066)
    at com.nitido.rss.RSSNugget.createCategory(RSSNugget.java:294)
    ...
Caused by: com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: Table 
'rss.AUTO_PK_SUPPORT' doesn't exist
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1026)
   ...

It looks like, since the ID on the Item is null and the Category object 
hasn't been initialized yet, Cayenne is trying to generate an ID for the 
row. I don't see any other INSERT commands from the logger after I call 
context.commitChanges(), so the attempt to insert a row for the Item 
object looks to be the first thing that it's trying to do.

So, my questions are:
1. Is this normal? Or does this sound like it could be a problem caused 
by me screwing up the mapping.xml?
3. Is it a good idea to work around this by using either AUTO_PK_SUPPORT 
or a custom database sequence, and forget about the AUTO_INCREMENT 
feature? I have control over the database schema, so I could do this 
instead. Alternately, I could just generate my own ID's without using 
cayenne, but I'd rather not.
4. Is it normal to do this by committing the Category objects before 
attempting to create Item objects related to them? That seems somewhat 
hacky to me, though.

BTW, I'm using Cayenne 3.0M4.

Thanks!


Shea.

RE: Order of commits?

Posted by Scott Anderson <sa...@airvana.com>.
I had a similar issue back in April in the past. I believe you can work
around this limitation by committing the parent of the relationship (the
"one" of the "one-to-many") before committing the children (the "many").

http://cayenne.markmail.org/message/6nazm7w4kaxxhj7m

-----Original Message-----
From: Michael Shea [mailto:mike@nitido.com] 
Sent: Wednesday, November 19, 2008 6:11 PM
To: user@cayenne.apache.org
Subject: Order of commits?

Hi guys -

I am wondering if there is any way to tell cayenne what order to commit 
new objects in.

My issue is basically like this:

Suppose I have Category objects and Item objects.

A user can pass in a CategoryDescriptor, which contains a list of 
ItemDescriptors. I want cayenne to generate, from these descriptors, the

corresponding database-model objects and rows in the database. So I do 
something like this:

public Category createCategory( CategoryDescriptor categoryDescriptor )
{
    Context context = ...; // do something to get the context here.
    Category category = context.newObject( Category.class );
    .... // fill in stuff about the category object here.
    for ( ItemDescriptor itemDescriptor : 
categoryDescriptor.getItemDescriptors() )
    {
       Item item = context.newObject( Item.class );
       ... // fill in stuff about the item object here.
    }
    context.commitChanges();
    return Category;
}

The problem I am having is that both Category and Item have primary keys

which are autogenerated by database (I am using MySQL, the ID's are 
generated via AUTO_INCREMENT columns). It looks like cayenne is 
attempting to create the Item objects before creating the Category 
object, and then it's giving me a commit exception like this:

org.apache.cayenne.CayenneRuntimeException: [v.3.0M4 May 18 2008 
16:32:02] Commit Exception
    at 
org.apache.cayenne.access.DataContext.flushToParent(DataContext.java:119
2)
    at 
org.apache.cayenne.access.DataContext.commitChanges(DataContext.java:106
6)
    at com.nitido.rss.RSSNugget.createCategory(RSSNugget.java:294)
    ...
Caused by: com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: Table 
'rss.AUTO_PK_SUPPORT' doesn't exist
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1026)
   ...

It looks like, since the ID on the Item is null and the Category object 
hasn't been initialized yet, Cayenne is trying to generate an ID for the

row. I don't see any other INSERT commands from the logger after I call 
context.commitChanges(), so the attempt to insert a row for the Item 
object looks to be the first thing that it's trying to do.

So, my questions are:
1. Is this normal? Or does this sound like it could be a problem caused 
by me screwing up the mapping.xml?
3. Is it a good idea to work around this by using either AUTO_PK_SUPPORT

or a custom database sequence, and forget about the AUTO_INCREMENT 
feature? I have control over the database schema, so I could do this 
instead. Alternately, I could just generate my own ID's without using 
cayenne, but I'd rather not.
4. Is it normal to do this by committing the Category objects before 
attempting to create Item objects related to them? That seems somewhat 
hacky to me, though.

BTW, I'm using Cayenne 3.0M4.

Thanks!


Shea.

Re: Order of commits?

Posted by Andrus Adamchik <an...@objectstyle.org>.
The problem is likely in the mapping. At the minimum you'll need to  
check that PK Generation Strategy is set to "Database-Generated" to  
all entities in question.

Andrus

On Nov 20, 2008, at 1:10 AM, Michael Shea wrote:

> Hi guys -
>
> I am wondering if there is any way to tell cayenne what order to  
> commit new objects in.
>
> My issue is basically like this:
>
> Suppose I have Category objects and Item objects.
>
> A user can pass in a CategoryDescriptor, which contains a list of  
> ItemDescriptors. I want cayenne to generate, from these descriptors,  
> the corresponding database-model objects and rows in the database.  
> So I do something like this:
>
> public Category createCategory( CategoryDescriptor  
> categoryDescriptor )
> {
>   Context context = ...; // do something to get the context here.
>   Category category = context.newObject( Category.class );
>   .... // fill in stuff about the category object here.
>   for ( ItemDescriptor itemDescriptor :  
> categoryDescriptor.getItemDescriptors() )
>   {
>      Item item = context.newObject( Item.class );
>      ... // fill in stuff about the item object here.
>   }
>   context.commitChanges();
>   return Category;
> }
>
> The problem I am having is that both Category and Item have primary  
> keys which are autogenerated by database (I am using MySQL, the ID's  
> are generated via AUTO_INCREMENT columns). It looks like cayenne is  
> attempting to create the Item objects before creating the Category  
> object, and then it's giving me a commit exception like this:
>
> org.apache.cayenne.CayenneRuntimeException: [v.3.0M4 May 18 2008  
> 16:32:02] Commit Exception
>   at  
> org.apache.cayenne.access.DataContext.flushToParent(DataContext.java: 
> 1192)
>   at  
> org.apache.cayenne.access.DataContext.commitChanges(DataContext.java: 
> 1066)
>   at com.nitido.rss.RSSNugget.createCategory(RSSNugget.java:294)
>   ...
> Caused by: com.mysql.jdbc.exceptions.MySQLSyntaxErrorException:  
> Table 'rss.AUTO_PK_SUPPORT' doesn't exist
>   at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1026)
>  ...
>
> It looks like, since the ID on the Item is null and the Category  
> object hasn't been initialized yet, Cayenne is trying to generate an  
> ID for the row. I don't see any other INSERT commands from the  
> logger after I call context.commitChanges(), so the attempt to  
> insert a row for the Item object looks to be the first thing that  
> it's trying to do.
>
> So, my questions are:
> 1. Is this normal? Or does this sound like it could be a problem  
> caused by me screwing up the mapping.xml?
> 3. Is it a good idea to work around this by using either  
> AUTO_PK_SUPPORT or a custom database sequence, and forget about the  
> AUTO_INCREMENT feature? I have control over the database schema, so  
> I could do this instead. Alternately, I could just generate my own  
> ID's without using cayenne, but I'd rather not.
> 4. Is it normal to do this by committing the Category objects before  
> attempting to create Item objects related to them? That seems  
> somewhat hacky to me, though.
>
> BTW, I'm using Cayenne 3.0M4.
>
> Thanks!
>
>
> Shea.
>