You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@cayenne.apache.org by Bret Gregory <bm...@yahoo.com> on 2009/08/26 04:08:22 UTC

Newbie Question: Mapping a Collection of Strings

I have a DB that looks something like this:

Product
-ProductId 
-Description

Keyword
-ProductId
-Keyword 

Where Product -> Keyword is 1:N and Keyword has a FK rel back to Product.  

I would like the object model to look something like this:

Product
-(String) _description
-(List<String>) _keywords

Is it possible to map collections of simple objects and have them persisted by Cayenne?  Seems like this would be a pretty common request, but
I am not seeing a way to do this in the modeler.


      

Re: Newbie Question: Mapping a Collection of Strings

Posted by Michael Gentry <mg...@masslight.net>.
#1 yeah ... it is pseduocode.  Renaming the helper method would be
best since getKeywords() is the relationship.

Thanks,

mrg


On Wed, Aug 26, 2009 at 10:36 AM, Matt Kerr<ma...@centralparksoftware.com> wrote:
> Thank you Mr. Gentry for posting actual code.  This is always most helpful.
>
> I will add two small comments-
>
> #1 - please note: that code snippet is pseudo-code, and will likely
> explode w/OOM due to recursion .. since getKeywords() is calling
> itself.  adjust accordingly.
>
> #2 - matter of personal preference:
> If the structure is Product -> Keyword
> and therefore, aProduct.getKeywords() is defined in the model -
> which would return a List of Keyword objects, ie List<Keyword> ..
> Having an API called getKeywords() -- which returned List<String>
> *instead* of actual Keyword objects pretty darned misleading. :-?
> Since you will have an abstraction/class for a Keyword object (which
> has an ivar String) - don't mix and match Keyword vs. String.  They're
> not the same thing.
> If you want to provide the List<String> as a convenience on Product -
> call the api something like ..
>    public List<String> getKeywordStrings()
> or something to represent the fact that you're not dealing with
> Keyword objects, but plain old String objs(!)
>
>
> hope this makes sense.
> mk
>
>
>
> On Wed, Aug 26, 2009 at 9:48 AM, Michael Gentry<mg...@masslight.net> wrote:
>> Actually, Cayenne 3.x is pretty stable for the core features.
>>
>> What I would do in your Product.java class (the subclass of
>> _Product.java) is to write a few custom methods.  Something like:
>>
>> public List<String> getKeywords()
>> {
>>    List<String> keywords = new ArrayList<String>();
>>
>>    for (Keyword keyword : getKeywords())
>>        keywords.add(keyword.getKeyword());
>>
>>    return keywords;
>> }
>>
>> Your Keywords table/class could be rather complex and involved.
>> Cayenne normalizes the access to it, but you have the flexibility to
>> add custom accessors to make your application simpler and more natural
>> to develop.
>>
>> mrg
>>
>>
>> On Wed, Aug 26, 2009 at 9:36 AM, Bret Gregory<bm...@yahoo.com> wrote:
>>> Hey Matt,
>>>
>>> Thanks for the response.  These are exactly the steps that I took.  The problem that
>>> I am running into is that when I generate my classes the Product Class contains a List
>>> of Keyword.class not java.lang.String.
>>>
>>> I am guessing that since Cayenne 2.0.4 requires persistent classes to extend a base class
>>> that persisting simple classes/relationships like collections java.lang.String is not as simple.
>>> The big question is whether it is even possible.
>>>
>>> I have read a little on Cayenne 3.0 and it sounds like it is more inline, but the fact that it is not
>>> stable is a little disconcerting to me since I am writing something that will be in production before
>>> it is even gets into a release candidate stage.
>>>
>>> Any other ideas?
>>>
>>>
>>>
>>> ----- Original Message ----
>>> From: Matt Kerr <ma...@centralparksoftware.com>
>>> To: user@cayenne.apache.org; Bret Gregory <bm...@yahoo.com>
>>> Sent: Tuesday, August 25, 2009 10:55:15 PM
>>> Subject: Re: Newbie Question: Mapping a Collection of Strings
>>>
>>> Hey Bret -
>>>
>>> Unless I'm missing - yes, this is right on the mark for cayenne.
>>>
>>> If you have an existing database, the easiest is to create a new model
>>> and use Tools -> Re-engineer Databae Schema, ie
>>>    http://cayenne.apache.org/doc/reverse-engineer-database.html
>>>
>>> Note- I find there a few quirks in the Modeler, so pay attention to
>>> the fine print like this,
>>> "... you need to select either a DataDomain or one of its children on
>>> the project tree."
>>>
>>> If you're starting from scratch - hmm, I'd thought there'd be more
>>> info here, but I'm not seeing it :-?
>>>    http://cayenne.apache.org/doc/modeler-guide.html
>>>
>>> You'd need to do something *vaguely* like ..
>>>
>>> 1/ create a Database Entity for each of your tables: Product and
>>> Keyword.  This includes defining PK.
>>> 2/ then still in the Database Entity - add the Relationship from
>>> Product -> Keyword.  You have to open the Inspector (I) to define the
>>> columns which define the join.  Set the name of reverse relationship
>>> -which will use the FK you mention.
>>> 3/ when that's all set, I'd hit the "C+" (Create Object Entity) to
>>> define your classes.
>>> 4/ Tools -> Generate Classes
>>>
>>> Hope this helps for now.
>>> -mk
>>>
>>>
>>>
>>> On Tue, Aug 25, 2009 at 10:08 PM, Bret Gregory<bm...@yahoo.com> wrote:
>>>> I have a DB that looks something like this:
>>>>
>>>> Product
>>>> -ProductId
>>>> -Description
>>>>
>>>> Keyword
>>>> -ProductId
>>>> -Keyword
>>>>
>>>> Where Product -> Keyword is 1:N and Keyword has a FK rel back to Product.
>>>>
>>>> I would like the object model to look something like this:
>>>>
>>>> Product
>>>> -(String) _description
>>>> -(List<String>) _keywords
>>>>
>>>> Is it possible to map collections of simple objects and have them persisted by Cayenne?  Seems like this would be a pretty common request, but
>>>> I am not seeing a way to do this in the modeler.
>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>>
>>>
>>>
>>
>

Re: Newbie Question: Mapping a Collection of Strings

Posted by Matt Kerr <ma...@centralparksoftware.com>.
Thank you Mr. Gentry for posting actual code.  This is always most helpful.

I will add two small comments-

#1 - please note: that code snippet is pseudo-code, and will likely
explode w/OOM due to recursion .. since getKeywords() is calling
itself.  adjust accordingly.

#2 - matter of personal preference:
If the structure is Product -> Keyword
and therefore, aProduct.getKeywords() is defined in the model -
which would return a List of Keyword objects, ie List<Keyword> ..
Having an API called getKeywords() -- which returned List<String>
*instead* of actual Keyword objects pretty darned misleading. :-?
Since you will have an abstraction/class for a Keyword object (which
has an ivar String) - don't mix and match Keyword vs. String.  They're
not the same thing.
If you want to provide the List<String> as a convenience on Product -
call the api something like ..
    public List<String> getKeywordStrings()
or something to represent the fact that you're not dealing with
Keyword objects, but plain old String objs(!)


hope this makes sense.
mk



On Wed, Aug 26, 2009 at 9:48 AM, Michael Gentry<mg...@masslight.net> wrote:
> Actually, Cayenne 3.x is pretty stable for the core features.
>
> What I would do in your Product.java class (the subclass of
> _Product.java) is to write a few custom methods.  Something like:
>
> public List<String> getKeywords()
> {
>    List<String> keywords = new ArrayList<String>();
>
>    for (Keyword keyword : getKeywords())
>        keywords.add(keyword.getKeyword());
>
>    return keywords;
> }
>
> Your Keywords table/class could be rather complex and involved.
> Cayenne normalizes the access to it, but you have the flexibility to
> add custom accessors to make your application simpler and more natural
> to develop.
>
> mrg
>
>
> On Wed, Aug 26, 2009 at 9:36 AM, Bret Gregory<bm...@yahoo.com> wrote:
>> Hey Matt,
>>
>> Thanks for the response.  These are exactly the steps that I took.  The problem that
>> I am running into is that when I generate my classes the Product Class contains a List
>> of Keyword.class not java.lang.String.
>>
>> I am guessing that since Cayenne 2.0.4 requires persistent classes to extend a base class
>> that persisting simple classes/relationships like collections java.lang.String is not as simple.
>> The big question is whether it is even possible.
>>
>> I have read a little on Cayenne 3.0 and it sounds like it is more inline, but the fact that it is not
>> stable is a little disconcerting to me since I am writing something that will be in production before
>> it is even gets into a release candidate stage.
>>
>> Any other ideas?
>>
>>
>>
>> ----- Original Message ----
>> From: Matt Kerr <ma...@centralparksoftware.com>
>> To: user@cayenne.apache.org; Bret Gregory <bm...@yahoo.com>
>> Sent: Tuesday, August 25, 2009 10:55:15 PM
>> Subject: Re: Newbie Question: Mapping a Collection of Strings
>>
>> Hey Bret -
>>
>> Unless I'm missing - yes, this is right on the mark for cayenne.
>>
>> If you have an existing database, the easiest is to create a new model
>> and use Tools -> Re-engineer Databae Schema, ie
>>    http://cayenne.apache.org/doc/reverse-engineer-database.html
>>
>> Note- I find there a few quirks in the Modeler, so pay attention to
>> the fine print like this,
>> "... you need to select either a DataDomain or one of its children on
>> the project tree."
>>
>> If you're starting from scratch - hmm, I'd thought there'd be more
>> info here, but I'm not seeing it :-?
>>    http://cayenne.apache.org/doc/modeler-guide.html
>>
>> You'd need to do something *vaguely* like ..
>>
>> 1/ create a Database Entity for each of your tables: Product and
>> Keyword.  This includes defining PK.
>> 2/ then still in the Database Entity - add the Relationship from
>> Product -> Keyword.  You have to open the Inspector (I) to define the
>> columns which define the join.  Set the name of reverse relationship
>> -which will use the FK you mention.
>> 3/ when that's all set, I'd hit the "C+" (Create Object Entity) to
>> define your classes.
>> 4/ Tools -> Generate Classes
>>
>> Hope this helps for now.
>> -mk
>>
>>
>>
>> On Tue, Aug 25, 2009 at 10:08 PM, Bret Gregory<bm...@yahoo.com> wrote:
>>> I have a DB that looks something like this:
>>>
>>> Product
>>> -ProductId
>>> -Description
>>>
>>> Keyword
>>> -ProductId
>>> -Keyword
>>>
>>> Where Product -> Keyword is 1:N and Keyword has a FK rel back to Product.
>>>
>>> I would like the object model to look something like this:
>>>
>>> Product
>>> -(String) _description
>>> -(List<String>) _keywords
>>>
>>> Is it possible to map collections of simple objects and have them persisted by Cayenne?  Seems like this would be a pretty common request, but
>>> I am not seeing a way to do this in the modeler.
>>>
>>>
>>>
>>>
>>
>>
>>
>>
>>
>

Re: Newbie Question: Mapping a Collection of Strings

Posted by Michael Gentry <mg...@masslight.net>.
Actually, Cayenne 3.x is pretty stable for the core features.

What I would do in your Product.java class (the subclass of
_Product.java) is to write a few custom methods.  Something like:

public List<String> getKeywords()
{
    List<String> keywords = new ArrayList<String>();

    for (Keyword keyword : getKeywords())
        keywords.add(keyword.getKeyword());

    return keywords;
}

Your Keywords table/class could be rather complex and involved.
Cayenne normalizes the access to it, but you have the flexibility to
add custom accessors to make your application simpler and more natural
to develop.

mrg


On Wed, Aug 26, 2009 at 9:36 AM, Bret Gregory<bm...@yahoo.com> wrote:
> Hey Matt,
>
> Thanks for the response.  These are exactly the steps that I took.  The problem that
> I am running into is that when I generate my classes the Product Class contains a List
> of Keyword.class not java.lang.String.
>
> I am guessing that since Cayenne 2.0.4 requires persistent classes to extend a base class
> that persisting simple classes/relationships like collections java.lang.String is not as simple.
> The big question is whether it is even possible.
>
> I have read a little on Cayenne 3.0 and it sounds like it is more inline, but the fact that it is not
> stable is a little disconcerting to me since I am writing something that will be in production before
> it is even gets into a release candidate stage.
>
> Any other ideas?
>
>
>
> ----- Original Message ----
> From: Matt Kerr <ma...@centralparksoftware.com>
> To: user@cayenne.apache.org; Bret Gregory <bm...@yahoo.com>
> Sent: Tuesday, August 25, 2009 10:55:15 PM
> Subject: Re: Newbie Question: Mapping a Collection of Strings
>
> Hey Bret -
>
> Unless I'm missing - yes, this is right on the mark for cayenne.
>
> If you have an existing database, the easiest is to create a new model
> and use Tools -> Re-engineer Databae Schema, ie
>    http://cayenne.apache.org/doc/reverse-engineer-database.html
>
> Note- I find there a few quirks in the Modeler, so pay attention to
> the fine print like this,
> "... you need to select either a DataDomain or one of its children on
> the project tree."
>
> If you're starting from scratch - hmm, I'd thought there'd be more
> info here, but I'm not seeing it :-?
>    http://cayenne.apache.org/doc/modeler-guide.html
>
> You'd need to do something *vaguely* like ..
>
> 1/ create a Database Entity for each of your tables: Product and
> Keyword.  This includes defining PK.
> 2/ then still in the Database Entity - add the Relationship from
> Product -> Keyword.  You have to open the Inspector (I) to define the
> columns which define the join.  Set the name of reverse relationship
> -which will use the FK you mention.
> 3/ when that's all set, I'd hit the "C+" (Create Object Entity) to
> define your classes.
> 4/ Tools -> Generate Classes
>
> Hope this helps for now.
> -mk
>
>
>
> On Tue, Aug 25, 2009 at 10:08 PM, Bret Gregory<bm...@yahoo.com> wrote:
>> I have a DB that looks something like this:
>>
>> Product
>> -ProductId
>> -Description
>>
>> Keyword
>> -ProductId
>> -Keyword
>>
>> Where Product -> Keyword is 1:N and Keyword has a FK rel back to Product.
>>
>> I would like the object model to look something like this:
>>
>> Product
>> -(String) _description
>> -(List<String>) _keywords
>>
>> Is it possible to map collections of simple objects and have them persisted by Cayenne?  Seems like this would be a pretty common request, but
>> I am not seeing a way to do this in the modeler.
>>
>>
>>
>>
>
>
>
>
>

Re: Newbie Question: Mapping a Collection of Strings

Posted by Matt Kerr <ma...@centralparksoftware.com>.
I am biased, but I find 3.0M6 quite stable.

Personally, I find the 'development' labeling on apache.org misleading.

It's way more solid than that.  (We've had it in production for quite
some time - on large internet site.)

If you're starting from scratch - I would recommend 3.x
There's been a lot of great work that's gone into this branch.

If I'm missing something here - please feel free to set the record straight.
No worries.

2cents,
-Matt





On Wed, Aug 26, 2009 at 9:53 AM, Michael Gentry<mg...@masslight.net> wrote:
> BTW, I'm writing something I expect to go into production in the
> October time-frame.  I'm using 3.0M6 and have every expectation that
> it will work.  Especially since I'm sticking to the "Classic" Cayenne
> feature set, which is stable and has seen improvements in 3.x, too.
>
> mrg
>
> On Wed, Aug 26, 2009 at 9:36 AM, Bret Gregory<bm...@yahoo.com> wrote:
>> I have read a little on Cayenne 3.0 and it sounds like it is more inline, but the fact that it is not
>> stable is a little disconcerting to me since I am writing something that will be in production before
>> it is even gets into a release candidate stage
>

Re: Newbie Question: Mapping a Collection of Strings

Posted by Michael Gentry <mg...@masslight.net>.
BTW, I'm writing something I expect to go into production in the
October time-frame.  I'm using 3.0M6 and have every expectation that
it will work.  Especially since I'm sticking to the "Classic" Cayenne
feature set, which is stable and has seen improvements in 3.x, too.

mrg

On Wed, Aug 26, 2009 at 9:36 AM, Bret Gregory<bm...@yahoo.com> wrote:
> I have read a little on Cayenne 3.0 and it sounds like it is more inline, but the fact that it is not
> stable is a little disconcerting to me since I am writing something that will be in production before
> it is even gets into a release candidate stage

Re: Newbie Question: Mapping a Collection of Strings

Posted by Bret Gregory <bm...@yahoo.com>.
Hey Matt,

Thanks for the response.  These are exactly the steps that I took.  The problem that
I am running into is that when I generate my classes the Product Class contains a List
of Keyword.class not java.lang.String. 

I am guessing that since Cayenne 2.0.4 requires persistent classes to extend a base class
that persisting simple classes/relationships like collections java.lang.String is not as simple.  
The big question is whether it is even possible.  

I have read a little on Cayenne 3.0 and it sounds like it is more inline, but the fact that it is not
stable is a little disconcerting to me since I am writing something that will be in production before
it is even gets into a release candidate stage.  

Any other ideas?  



----- Original Message ----
From: Matt Kerr <ma...@centralparksoftware.com>
To: user@cayenne.apache.org; Bret Gregory <bm...@yahoo.com>
Sent: Tuesday, August 25, 2009 10:55:15 PM
Subject: Re: Newbie Question: Mapping a Collection of Strings

Hey Bret -

Unless I'm missing - yes, this is right on the mark for cayenne.

If you have an existing database, the easiest is to create a new model
and use Tools -> Re-engineer Databae Schema, ie
    http://cayenne.apache.org/doc/reverse-engineer-database.html

Note- I find there a few quirks in the Modeler, so pay attention to
the fine print like this,
"... you need to select either a DataDomain or one of its children on
the project tree."

If you're starting from scratch - hmm, I'd thought there'd be more
info here, but I'm not seeing it :-?
    http://cayenne.apache.org/doc/modeler-guide.html

You'd need to do something *vaguely* like ..

1/ create a Database Entity for each of your tables: Product and
Keyword.  This includes defining PK.
2/ then still in the Database Entity - add the Relationship from
Product -> Keyword.  You have to open the Inspector (I) to define the
columns which define the join.  Set the name of reverse relationship
-which will use the FK you mention.
3/ when that's all set, I'd hit the "C+" (Create Object Entity) to
define your classes.
4/ Tools -> Generate Classes

Hope this helps for now.
-mk



On Tue, Aug 25, 2009 at 10:08 PM, Bret Gregory<bm...@yahoo.com> wrote:
> I have a DB that looks something like this:
>
> Product
> -ProductId
> -Description
>
> Keyword
> -ProductId
> -Keyword
>
> Where Product -> Keyword is 1:N and Keyword has a FK rel back to Product.
>
> I would like the object model to look something like this:
>
> Product
> -(String) _description
> -(List<String>) _keywords
>
> Is it possible to map collections of simple objects and have them persisted by Cayenne?  Seems like this would be a pretty common request, but
> I am not seeing a way to do this in the modeler.
>
>
>
>



      

Re: Newbie Question: Mapping a Collection of Strings

Posted by Matt Kerr <ma...@centralparksoftware.com>.
Hey Bret -

Unless I'm missing - yes, this is right on the mark for cayenne.

If you have an existing database, the easiest is to create a new model
and use Tools -> Re-engineer Databae Schema, ie
    http://cayenne.apache.org/doc/reverse-engineer-database.html

Note- I find there a few quirks in the Modeler, so pay attention to
the fine print like this,
"... you need to select either a DataDomain or one of its children on
the project tree."

If you're starting from scratch - hmm, I'd thought there'd be more
info here, but I'm not seeing it :-?
    http://cayenne.apache.org/doc/modeler-guide.html

You'd need to do something *vaguely* like ..

1/ create a Database Entity for each of your tables: Product and
Keyword.  This includes defining PK.
2/ then still in the Database Entity - add the Relationship from
Product -> Keyword.  You have to open the Inspector (I) to define the
columns which define the join.  Set the name of reverse relationship
-which will use the FK you mention.
3/ when that's all set, I'd hit the "C+" (Create Object Entity) to
define your classes.
4/ Tools -> Generate Classes

Hope this helps for now.
-mk



On Tue, Aug 25, 2009 at 10:08 PM, Bret Gregory<bm...@yahoo.com> wrote:
> I have a DB that looks something like this:
>
> Product
> -ProductId
> -Description
>
> Keyword
> -ProductId
> -Keyword
>
> Where Product -> Keyword is 1:N and Keyword has a FK rel back to Product.
>
> I would like the object model to look something like this:
>
> Product
> -(String) _description
> -(List<String>) _keywords
>
> Is it possible to map collections of simple objects and have them persisted by Cayenne?  Seems like this would be a pretty common request, but
> I am not seeing a way to do this in the modeler.
>
>
>
>

Re: Newbie Question: Mapping a Collection of Strings

Posted by Andrus Adamchik <an...@objectstyle.org>.
Hi Brett,

You will have to map a Keyword class in both 2.0 and 3.0, and maybe  
create a cover method converting a list of Keywords to a list of  
Strings on the fly.

3.0 supports something called "flattened attributes", which is what  
you describe, but only for to-one relationships.

Andrus

On Aug 26, 2009, at 5:08 AM, Bret Gregory wrote:

> I have a DB that looks something like this:
>
> Product
> -ProductId
> -Description
>
> Keyword
> -ProductId
> -Keyword
>
> Where Product -> Keyword is 1:N and Keyword has a FK rel back to  
> Product.
>
> I would like the object model to look something like this:
>
> Product
> -(String) _description
> -(List<String>) _keywords
>
> Is it possible to map collections of simple objects and have them  
> persisted by Cayenne?  Seems like this would be a pretty common  
> request, but
> I am not seeing a way to do this in the modeler.
>
>
>
>