Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF "Technology" (Ecore Tools, EMFatic, etc)  » EMaps and the missing @MapKey annotation
EMaps and the missing @MapKey annotation [message #74329] Thu, 08 March 2007 16:15 Go to next message
Jean-Denis Boudreault is currently offline Jean-Denis BoudreaultFriend
Messages: 55
Registered: July 2009
Member
Hello again,

im very active these days in Teneo evaluation ;)


I notice that the jpa annotation @MapKey is not currently supported by
Teneo. does that mean that we can not use EMap fields with Teneo? and if
we can, how can we set it up?

if we can't, will it be supported if we add the mapkey clause directly in
the xml.hbm file or will the Teneo runtime be incapable of handling EMaps?


thanks!
Re: EMaps and the missing @MapKey annotation [message #74367 is a reply to message #74329] Thu, 08 March 2007 16:23 Go to previous messageGo to next message
Martin Taal is currently offline Martin TaalFriend
Messages: 5468
Registered: July 2009
Senior Member
Hi Jean-Denis,
EMap is supported. EMap has a very specific implementation, it is nl. a list of map entries. The
entries are generated by emf as separate explicit java classes. In correspondence to the emf
approach the emap is mapped to the db as a list with a specific map entity.

gr. Martin

Jean-Denis Boudreault wrote:
> Hello again,
>
> im very active these days in Teneo evaluation ;)
>
>
> I notice that the jpa annotation @MapKey is not currently supported by
> Teneo. does that mean that we can not use EMap fields with Teneo? and
> if we can, how can we set it up?
>
> if we can't, will it be supported if we add the mapkey clause directly
> in the xml.hbm file or will the Teneo runtime be incapable of handling
> EMaps?
>
>
> thanks!
>


--

With Regards, Martin Taal

Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
Re: EMaps and the missing @MapKey annotation [message #74439 is a reply to message #74367] Thu, 08 March 2007 19:00 Go to previous messageGo to next message
Jean-Denis Boudreault is currently offline Jean-Denis BoudreaultFriend
Messages: 55
Registered: July 2009
Member
thanks for your answer.

im not sure if it get it all, perhaps i dont understand very well how
teneo maps from the hibernate engine to the EMF datatypes.

But if i get it right, Teneo creates a oneToMany/ManyToOne relationship to
the owner object,is that it? then, how dies it define the key? is it
possible to perform this kind of mapping in teneo and define the column
used for the key? (or perhaps the key column is defined automatically?)

<scenario>
TableA

[ID: 1, Name: "entry1"]


TableB (joins table A on ID:ParentID)

[ID: 1, ParentID: 1, name="entry1"]
[ID: 2, ParentID: 1, name="entry2"]
[ID: 3 ParentID: 1, name="entry3"]


then, in code:

class TableAEntity
{
public Map<Integer, TableBEntity> childs;
}
</scenario>

where the key of the map is mapped to the ID column of TableB and the
value of the map is the TableB entity for this ID.

thanks for your time!
Re: EMaps and the missing @MapKey annotation [message #74475 is a reply to message #74439] Thu, 08 March 2007 20:45 Go to previous messageGo to next message
Martin Taal is currently offline Martin TaalFriend
Messages: 5468
Registered: July 2009
Senior Member
Hi JD,
Teneo maps from emf to hibernate (so the other way around). This means that it maps the emap to
hibernate in correspondence to the emf approach. For an emap entry emf (so not teneo but emf itself)
will generate a separate class (for example stringtostringemapentry or something). The emf emap is
not a real map but a list of these map entries (so not a hashmap with map entries). Because it is a
list it can not be mapped easily to a real map-like model in the db.
Teneo takes the separately generated map entry class and creates a mapping for that class as if it
is in the list of the owner. The entry class is modeled as a separate entity with its own primary
key (for example a generated id). This key has nothing to do with the map key (it does not really
need it).
Teneo just follows the emf approach here.

gr. Martin

JD wrote:
> thanks for your answer.
>
> im not sure if it get it all, perhaps i dont understand very well how
> teneo maps from the hibernate engine to the EMF datatypes.
>
> But if i get it right, Teneo creates a oneToMany/ManyToOne relationship
> to the owner object,is that it? then, how dies it define the key? is it
> possible to perform this kind of mapping in teneo and define the column
> used for the key? (or perhaps the key column is defined automatically?)
>
> <scenario>
> TableA
>
> [ID: 1, Name: "entry1"]
>
>
> TableB (joins table A on ID:ParentID)
>
> [ID: 1, ParentID: 1, name="entry1"]
> [ID: 2, ParentID: 1, name="entry2"]
> [ID: 3 ParentID: 1, name="entry3"]
>
>
> then, in code:
>
> class TableAEntity
> {
> public Map<Integer, TableBEntity> childs;
> }
> </scenario>
>
> where the key of the map is mapped to the ID column of TableB and the
> value of the map is the TableB entity for this ID.
>
> thanks for your time!
>


--

With Regards, Martin Taal

Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
Re: EMaps and the missing @MapKey annotation [message #74510 is a reply to message #74475] Thu, 08 March 2007 23:10 Go to previous messageGo to next message
Jean-Denis Boudreault is currently offline Jean-Denis BoudreaultFriend
Messages: 55
Registered: July 2009
Member
Hi Martin, thanks for your very detailed answers!

I guess where i am confused is how a list can behaves like a map, since how
does it provide the key/value functionality. i explain:

I just found on the EMF FAQ
( http://wiki.eclipse.org/index.php/EMF-FAQ#How_do_i_create_a_ Map_in_EMF.3F)
where they explain about EMaps. it surely concurs with your sayings. I have
two questions from there (i hope these questions dont annoy you, but if i
better understand, perhaps i can help too :))

1. In my ecore diagram, i create an EAttribute of EType EMap <K, V>
[java.util.Map]. When i generate the code, i get a good old java.util.Map. I
guess this is where i get confused. with a java.util.Map, can't we get
hibernate to function like it always did? and from there, wouldn't it be a
good idea to implement the @MapKey annotation?

2. Im pretty sure im not understanding well and you will explain to my why
the java.util.Map thing is wrong. then, if the EMap is a list of custom
mapEntries class, what happens behind the scenes when i do: myMap.ge(2)
specifying a key value? is there a hidden foreach in the implementation
that iterates the list of entries and returns the found result? and if so,
what prevents us from mapping a column in a oneToMany relationship as the
key to the mapEntries? there, the @MapKey annotation would be useful, to
define which column in the entity is to be used for key, instead of forcing
the ID column. am i being clear?

basically, if i get this right, we define a EClass for the EMap entries,
right? so, suppose we take my database example from before:

<scenario>
TableA

[ID: 1, Name: "entry1"]


TableB (joins table A on ID:ParentID)

[ID: 1, ParentID: 1, name="entry1", someUniqueField=233]
[ID: 2, ParentID: 1, name="entry2", someUniqueField=34456]
[ID: 3 ParentID: 1, name="entry3", someUniqueField=2342]

</scenario>

Then, if we want a map of type tableB with the key being someUniqueField
column, we could have:

SomeUniqueFieldToTableBEntry<Integer, TableBClass>

with this, it would make sense to have @MapKey defined to select the column
to be used to set the key.

am i making any sense?

anyways, i hope im getting this right, since perhaps i really dont know what
goes under the hood.

thanks for your help, this is much appreciated! :)

"Martin Taal" <mtaal@elver.org> wrote in message
news:espslr$uoj$1@utils.eclipse.org...
> Hi JD,
> Teneo maps from emf to hibernate (so the other way around). This means
> that it maps the emap to hibernate in correspondence to the emf approach.
> For an emap entry emf (so not teneo but emf itself) will generate a
> separate class (for example stringtostringemapentry or something). The emf
> emap is not a real map but a list of these map entries (so not a hashmap
> with map entries). Because it is a list it can not be mapped easily to a
> real map-like model in the db.
> Teneo takes the separately generated map entry class and creates a mapping
> for that class as if it is in the list of the owner. The entry class is
> modeled as a separate entity with its own primary key (for example a
> generated id). This key has nothing to do with the map key (it does not
> really need it).
> Teneo just follows the emf approach here.
>
> gr. Martin
>
> JD wrote:
>> thanks for your answer.
>>
>> im not sure if it get it all, perhaps i dont understand very well how
>> teneo maps from the hibernate engine to the EMF datatypes.
>>
>> But if i get it right, Teneo creates a oneToMany/ManyToOne relationship
>> to the owner object,is that it? then, how dies it define the key? is it
>> possible to perform this kind of mapping in teneo and define the column
>> used for the key? (or perhaps the key column is defined automatically?)
>>
>> <scenario>
>> TableA
>>
>> [ID: 1, Name: "entry1"]
>>
>>
>> TableB (joins table A on ID:ParentID)
>>
>> [ID: 1, ParentID: 1, name="entry1"]
>> [ID: 2, ParentID: 1, name="entry2"]
>> [ID: 3 ParentID: 1, name="entry3"]
>>
>>
>> then, in code:
>>
>> class TableAEntity
>> {
>> public Map<Integer, TableBEntity> childs;
>> }
>> </scenario>
>>
>> where the key of the map is mapped to the ID column of TableB and the
>> value of the map is the TableB entity for this ID.
>>
>> thanks for your time!
>>
>
>
> --
>
> With Regards, Martin Taal
>
> Springsite/Elver.org
> Office: Hardwareweg 4, 3821 BV Amersfoort
> Postal: Nassaulaan 7, 3941 EC Doorn
> The Netherlands
> Tel: +31 (0)84 420 2397
> Fax: +31 (0)84 225 9307
> Mail: mtaal@springsite.com - mtaal@elver.org
> Web: www.springsite.com - www.elver.org
Re: EMaps and the missing @MapKey annotation [message #74528 is a reply to message #74510] Thu, 08 March 2007 23:26 Go to previous messageGo to next message
Jean-Denis Boudreault is currently offline Jean-Denis BoudreaultFriend
Messages: 55
Registered: July 2009
Member
Hi,

i was just thinking about this and i think i get your point.

so basically if i get what your saying, the mapentry class is defined in a
table of its own (entity), and the key is probably the unique ID of this
class, is that it? the value itself is either a column type or a onetoone
reference to another entity table.

so, following this logic, there would be no way to make direct relationships
to other entity table, without going through this 'intermediary' entity
being the mapentry.

If this is so, could it be possible to eliminate the need to explicitely
define a mapEntry entity and let teneo generate one in the background? foe
example:


KeyToValueEntry<K, V>.

then, there would be no need to have an intermediary table, and we could
directly specify the key column and the entity type. so we could create:

<pseudocode>
ClassA
{
public EMap<Integer, ClassB> field;
}
</pseudocode>

and with anotations define the column of the entity that is used as the Key
with @MapKey. in the background, teneo could generate this
KeyToValueEntry<K, V> list and dynamically rebuild an EMap. In the xml.hbm
file, there would be not intermediary entity, just a map from EnityA to
EntityB with a key column defined.

how does that sound? (i could be right off, sorry if i am, jsut trying to
help)

"Jean-Denis Boudreault" <jdboudreault@gmail.com> wrote in message
news:esq552$ekj$1@utils.eclipse.org...
> Hi Martin, thanks for your very detailed answers!
>
> I guess where i am confused is how a list can behaves like a map, since
> how does it provide the key/value functionality. i explain:
>
> I just found on the EMF FAQ
> ( http://wiki.eclipse.org/index.php/EMF-FAQ#How_do_i_create_a_ Map_in_EMF.3F)
> where they explain about EMaps. it surely concurs with your sayings. I
> have two questions from there (i hope these questions dont annoy you, but
> if i better understand, perhaps i can help too :))
>
> 1. In my ecore diagram, i create an EAttribute of EType EMap <K, V>
> [java.util.Map]. When i generate the code, i get a good old java.util.Map.
> I guess this is where i get confused. with a java.util.Map, can't we get
> hibernate to function like it always did? and from there, wouldn't it be
> a good idea to implement the @MapKey annotation?
>
> 2. Im pretty sure im not understanding well and you will explain to my why
> the java.util.Map thing is wrong. then, if the EMap is a list of custom
> mapEntries class, what happens behind the scenes when i do: myMap.ge(2)
> specifying a key value? is there a hidden foreach in the implementation
> that iterates the list of entries and returns the found result? and if
> so, what prevents us from mapping a column in a oneToMany relationship as
> the key to the mapEntries? there, the @MapKey annotation would be useful,
> to define which column in the entity is to be used for key, instead of
> forcing the ID column. am i being clear?
>
> basically, if i get this right, we define a EClass for the EMap entries,
> right? so, suppose we take my database example from before:
>
> <scenario>
> TableA
>
> [ID: 1, Name: "entry1"]
>
>
> TableB (joins table A on ID:ParentID)
>
> [ID: 1, ParentID: 1, name="entry1", someUniqueField=233]
> [ID: 2, ParentID: 1, name="entry2", someUniqueField=34456]
> [ID: 3 ParentID: 1, name="entry3", someUniqueField=2342]
>
> </scenario>
>
> Then, if we want a map of type tableB with the key being someUniqueField
> column, we could have:
>
> SomeUniqueFieldToTableBEntry<Integer, TableBClass>
>
> with this, it would make sense to have @MapKey defined to select the
> column to be used to set the key.
>
> am i making any sense?
>
> anyways, i hope im getting this right, since perhaps i really dont know
> what goes under the hood.
>
> thanks for your help, this is much appreciated! :)
>
> "Martin Taal" <mtaal@elver.org> wrote in message
> news:espslr$uoj$1@utils.eclipse.org...
>> Hi JD,
>> Teneo maps from emf to hibernate (so the other way around). This means
>> that it maps the emap to hibernate in correspondence to the emf approach.
>> For an emap entry emf (so not teneo but emf itself) will generate a
>> separate class (for example stringtostringemapentry or something). The
>> emf emap is not a real map but a list of these map entries (so not a
>> hashmap with map entries). Because it is a list it can not be mapped
>> easily to a real map-like model in the db.
>> Teneo takes the separately generated map entry class and creates a
>> mapping for that class as if it is in the list of the owner. The entry
>> class is modeled as a separate entity with its own primary key (for
>> example a generated id). This key has nothing to do with the map key (it
>> does not really need it).
>> Teneo just follows the emf approach here.
>>
>> gr. Martin
>>
>> JD wrote:
>>> thanks for your answer.
>>>
>>> im not sure if it get it all, perhaps i dont understand very well how
>>> teneo maps from the hibernate engine to the EMF datatypes.
>>>
>>> But if i get it right, Teneo creates a oneToMany/ManyToOne relationship
>>> to the owner object,is that it? then, how dies it define the key? is it
>>> possible to perform this kind of mapping in teneo and define the column
>>> used for the key? (or perhaps the key column is defined automatically?)
>>>
>>> <scenario>
>>> TableA
>>>
>>> [ID: 1, Name: "entry1"]
>>>
>>>
>>> TableB (joins table A on ID:ParentID)
>>>
>>> [ID: 1, ParentID: 1, name="entry1"]
>>> [ID: 2, ParentID: 1, name="entry2"]
>>> [ID: 3 ParentID: 1, name="entry3"]
>>>
>>>
>>> then, in code:
>>>
>>> class TableAEntity
>>> {
>>> public Map<Integer, TableBEntity> childs;
>>> }
>>> </scenario>
>>>
>>> where the key of the map is mapped to the ID column of TableB and the
>>> value of the map is the TableB entity for this ID.
>>>
>>> thanks for your time!
>>>
>>
>>
>> --
>>
>> With Regards, Martin Taal
>>
>> Springsite/Elver.org
>> Office: Hardwareweg 4, 3821 BV Amersfoort
>> Postal: Nassaulaan 7, 3941 EC Doorn
>> The Netherlands
>> Tel: +31 (0)84 420 2397
>> Fax: +31 (0)84 225 9307
>> Mail: mtaal@springsite.com - mtaal@elver.org
>> Web: www.springsite.com - www.elver.org
>
>
Re: EMaps and the missing @MapKey annotation [message #74582 is a reply to message #74528] Fri, 09 March 2007 11:18 Go to previous messageGo to next message
Jean-Denis Boudreault is currently offline Jean-Denis BoudreaultFriend
Messages: 55
Registered: July 2009
Member
Hello again,


i deeply apologize for the verbose, but i think this can actually be very
useful. This post may be long and detailed, but i want to make sure it is
clear.


So, i went a head and took a look at the BasicEList and BasicEMap
implementation files of EMF 2.3. So, now i understand what you were saying
about EMaps. it is in reality just a list, of the type map.entry. Where we
get an object by key in the EMap, it basically loops the list until it
finds the entry for that key. (I guess we should create an EMF feature
request for a EHashmap then since this is not very efficient for large
lists).


but, back to teneo. lets take this POJO scenario:

<code>
public class parent
{
int ID;

// the key is the GUID
public EMap<String, child>
}

public class child
{
int ID;
string GUID;
String name;
}
</code>

basically, a parent class holds a collection of child class, and to
accelerate lookup, keeps a map where the key is the unique string GUID of
the parent class. the datbase tables might look like this:

<dbschema>
--------------------
| PARENT |
--------------------
| Int | ID |
--------------------



--------------------
| CHILD |
--------------------
| Int | ID |
| Int |parentID|
| varchar | GUID |
| varchar | name |
--------------------

where there is a join in ID/ParentID

</dbschema>

Now, if we created a EList collection instead of a EMap, it would be a
simple thing, we would simply add a manyToOne/OneToMany hibernate
relationship on the collection to get it going.

but with emaps, its slightly different. to go with EMF, what teneo
currently does (if i correctly understand Martin's explanation) is to add
a third table, which is a 'middleman' joining table that represents the
map.Entry. this table has a field for the key and the value. this im not
sure, but i assume the value could also be a oneToOne join to the child
table. For this reason, the @MapKey is not supported, since there is no
other field to select the key from; just the defined field 'KEY' in that
table.

here is my suggestion: (i hope it makes sense).

when we think of it, a map really is just a list, with a key that
simplifies each entries lookup (hence the EMap design decision). for this
reason, pure hibernate allows for parent/*childs collections to be mapped
either as lists, or as maps where we can define which column can be used
as the key (hence @MapKey).

i belive it could be possible to allow teneo to function the same way, by
eliminating the burden on the developper of maintaining manually the
map.Entry 'KeyToValueEntry' class. Teneo could consider the EMap mapping
to be a EList, with a key column. The table mapping could remain the same
as EList. when rebuilding the list at load time, Teneo could dynamically
create a map.Entry<K,V> for each list entry, and then use the key column
defined to set the key value. this is basically what hibernate does too.

so, we could have in the database:

[parent table]
ID: 1

[child table]
ID: 1; ParentID: 1l GUID: 'whatever', name: 'name1'
ID: 2; ParentID: 1l GUID: 'whatever2', name: 'name2'
ID: 3; ParentID: 1l GUID: 'whatever3', name: 'name3'

then, the runtime loaded class could have a list of childs, and the key
set at the GUID (defiend by @MapKey annotation).

we could then search by key (here GUID) like this:
child chld = parent.childs.Get("whatever2"); // returns the child with ID=2


so, basically, my suggestion is to keep closer to the hibernate
methodology and map it to EMF, rather than map EMF to hibernate. This way
is just as valid, but removes the need to manually create / handle the
keyToValueEntry classes as well as map them to the table schema,
complicating map like options such as defining the key.


so, what do you think?


thanks and i hope this helps
Re: EMaps and the missing @MapKey annotation [message #74618 is a reply to message #74582] Fri, 09 March 2007 16:18 Go to previous messageGo to next message
Martin Taal is currently offline Martin TaalFriend
Messages: 5468
Registered: July 2009
Senior Member
Hi Jean-Denis,
No problem of being verbose :-).
Just to react on point in your description: you say that the developer manually has to create/handle
the keyToValueEntry class. However these entry classes are also generated by emf. The entry classes
are hidden for the developer using the emf objects. So the developer does not need create/handle
these classes manually. Or am I maybe missing your point here?

For me the real issue is in the current database mapping. From a relational-mapping perspective the
issue with the current approach is that the resulting database model has redundant information: the
key is repeated in a separate field while it can be present in the value-entity. Also the current
approach will always create a join table while this is not always required. In addition the entry
class will always get a synthetic id and version which does not work in case of client-server scenarios.

Your proposal is interesting and certainly something to try out. I can also look again at mapping an
emap as a real map.
Can you enter a separate bugzilla for this (change relational mapping of emap) and copy the contents
of these posting into it? Then I can take it from there. This is some work so it will probably take
some time (number of weeks) before I can spend time on it.

gr. Martin

Jean-Denis Boudreault wrote:
> Hello again,
>
>
> i deeply apologize for the verbose, but i think this can actually be
> very useful. This post may be long and detailed, but i want to make sure
> it is clear.
>
>
> So, i went a head and took a look at the BasicEList and BasicEMap
> implementation files of EMF 2.3. So, now i understand what you were
> saying about EMaps. it is in reality just a list, of the type map.entry.
> Where we get an object by key in the EMap, it basically loops the list
> until it finds the entry for that key. (I guess we should create an EMF
> feature request for a EHashmap then since this is not very efficient for
> large lists).
>
>
> but, back to teneo. lets take this POJO scenario:
>
> <code>
> public class parent
> {
> int ID;
>
> // the key is the GUID
> public EMap<String, child>
> }
>
> public class child
> {
> int ID;
> string GUID;
> String name;
> }
> </code>
>
> basically, a parent class holds a collection of child class, and to
> accelerate lookup, keeps a map where the key is the unique string GUID
> of the parent class. the datbase tables might look like this:
>
> <dbschema>
> --------------------
> | PARENT |
> --------------------
> | Int | ID |
> --------------------
>
>
>
> --------------------
> | CHILD |
> --------------------
> | Int | ID |
> | Int |parentID|
> | varchar | GUID |
> | varchar | name |
> --------------------
>
> where there is a join in ID/ParentID
>
> </dbschema>
>
> Now, if we created a EList collection instead of a EMap, it would be a
> simple thing, we would simply add a manyToOne/OneToMany hibernate
> relationship on the collection to get it going.
>
> but with emaps, its slightly different. to go with EMF, what teneo
> currently does (if i correctly understand Martin's explanation) is to
> add a third table, which is a 'middleman' joining table that represents
> the map.Entry. this table has a field for the key and the value. this im
> not sure, but i assume the value could also be a oneToOne join to the
> child table. For this reason, the @MapKey is not supported, since there
> is no other field to select the key from; just the defined field 'KEY'
> in that table.
>
> here is my suggestion: (i hope it makes sense).
>
> when we think of it, a map really is just a list, with a key that
> simplifies each entries lookup (hence the EMap design decision). for
> this reason, pure hibernate allows for parent/*childs collections to be
> mapped either as lists, or as maps where we can define which column can
> be used as the key (hence @MapKey).
>
> i belive it could be possible to allow teneo to function the same way,
> by eliminating the burden on the developper of maintaining manually the
> map.Entry 'KeyToValueEntry' class. Teneo could consider the EMap mapping
> to be a EList, with a key column. The table mapping could remain the
> same as EList. when rebuilding the list at load time, Teneo could
> dynamically create a map.Entry<K,V> for each list entry, and then use
> the key column defined to set the key value. this is basically what
> hibernate does too.
>
> so, we could have in the database:
>
> [parent table]
> ID: 1
>
> [child table]
> ID: 1; ParentID: 1l GUID: 'whatever', name: 'name1'
> ID: 2; ParentID: 1l GUID: 'whatever2', name: 'name2'
> ID: 3; ParentID: 1l GUID: 'whatever3', name: 'name3'
>
> then, the runtime loaded class could have a list of childs, and the key
> set at the GUID (defiend by @MapKey annotation).
>
> we could then search by key (here GUID) like this:
> child chld = parent.childs.Get("whatever2"); // returns the child with ID=2
>
>
> so, basically, my suggestion is to keep closer to the hibernate
> methodology and map it to EMF, rather than map EMF to hibernate. This
> way is just as valid, but removes the need to manually create / handle
> the keyToValueEntry classes as well as map them to the table schema,
> complicating map like options such as defining the key.
>
>
> so, what do you think?
>
>
> thanks and i hope this helps
>
>


--

With Regards, Martin Taal

Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
Re: EMaps and the missing @MapKey annotation [message #74636 is a reply to message #74618] Fri, 09 March 2007 16:29 Go to previous messageGo to next message
Jean-Denis Boudreault is currently offline Jean-Denis BoudreaultFriend
Messages: 55
Registered: July 2009
Member
Thanks Martin,

it will be a pleasure to log a feature request. BTW, should you deem it
useful, i am ready to help on this topic as it would be most useful for my
own projects which i am migrating to Teneo.

in any case, thanks for listening and being open to suggestions :)
Re: EMaps and the missing @MapKey annotation [message #74654 is a reply to message #74636] Fri, 09 March 2007 16:38 Go to previous messageGo to next message
Jean-Denis Boudreault is currently offline Jean-Denis BoudreaultFriend
Messages: 55
Registered: July 2009
Member
Feature request created with ID: 176833

(got a little formatting problem in the description, I hope this is not
important.)
Re: EMaps and the missing @MapKey annotation [message #74671 is a reply to message #74636] Fri, 09 March 2007 17:03 Go to previous messageGo to next message
Martin Taal is currently offline Martin TaalFriend
Messages: 5468
Registered: July 2009
Senior Member
Hi Jean-Denis,
Contributions are always wellcomed ofcourse!

If you are interested to try this out, the main changes (afaics) are:
- In the defaultannotator class there is a method processOneToManyReference. In this method the
target entity name has to be set to the eclass name of the value eclass (not the entry eclass).
- The HibernatePersistableEList is the list handler for hibernate. It extends PersistableElist which
extends DelegatingEcoreEList. The delegate list in these classes is the hibernate list (which
connects to the actual db). A possible solution approach is in the constructor of the
PersistableEList to wrap the hibernate list again in a new EMapEntryConvertingList (or another nice
name) which takes case of converting all calls from and to the hibernate list from/to the correct
map entry class.

At first I would not try to think about to handle the mapkey mapping but just get it working with a
hard coded key.

And ofcourse a test case proving that it all works is a prerequisite...

gr. Martin

Jean-Denis Boudreault wrote:
> Thanks Martin,
>
> it will be a pleasure to log a feature request. BTW, should you deem it
> useful, i am ready to help on this topic as it would be most useful for
> my own projects which i am migrating to Teneo.
>
> in any case, thanks for listening and being open to suggestions :)
>


--

With Regards, Martin Taal

Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
Re: EMaps and the missing @MapKey annotation [message #74689 is a reply to message #74671] Fri, 09 March 2007 17:12 Go to previous messageGo to next message
Jean-Denis Boudreault is currently offline Jean-Denis BoudreaultFriend
Messages: 55
Registered: July 2009
Member
Right-on,


i will get at it ASAP and post a patch on the bug report when im done.

thanks Martin :)
Re: EMaps and the missing @MapKey annotation [message #74811 is a reply to message #74689] Sat, 10 March 2007 17:27 Go to previous messageGo to next message
Jean-Denis Boudreault is currently offline Jean-Denis BoudreaultFriend
Messages: 55
Registered: July 2009
Member
Hi Martin, hope you dont mind if i ask a few questions as i
investigate the code. I will try to keep it to a minimum.


so, i got latest sources of teneo, emf and hibernate. i begun
investigating runtime behavior of EMaps and here is where i am at for
the moment:

i found that an EMap type is mapped by teneo as a list in the .hbm.xml.
example mapping:



<class entity-name="someclass" abstract="false" lazy="false"
discriminator-value="someclass" table="`someclass`">
<meta attribute="eclassName">someclass</meta>
<meta attribute="epackage">http://someclass</meta>
<id type="long" name="e_id" column="e_id"
access=" org.eclipse.emf.teneo.hibernate.mapping.identifier.Identifie rPropertyHandler ">
<meta attribute="syntheticId">true</meta>
<generator class="native"/>
</id>
<discriminator column="`dtype`" type="string"/>
<property name="name" lazy="false" insert="true" update="true"
not-null="false" unique="false" type="java.lang.String">
<column not-null="false" unique="false" name="`name`"/>
</property>
/* <list name="somemap" lazy="true"
cascade="merge,persist,save-update,lock,refresh">
<key update="true">
<column name="`*//*somechild_somemap*//*_e_id`"
not-null="false" unique="false"/>
</key>
<list-index column="`somechild_somemap_idx`"/>
<one-to-many entity-name="somekeyToValueEntry"/>
</list>*/
</class>
[/*.hbm.xml]

In the code, the hibernate property is defined as a listType, but
obviously, a map is not a list (at least, a java.util.map is not a
java.util.list). The class PersistableEMap returns a
PersistableDelegatingMap in 'public Map<K, V> map()' for the type, which
does not implement java.util.List. When hibernate tries to persist it
all, it attempts a cast to List on a PersistableDelegatingMap instance,
which fails with exception:

Exception in thread "Thread-1" java.lang.ClassCastException:
org.eclipse.emf.teneo.mapping.elist.PersistableEMap$Persista bleDelegatingMap
at org.hibernate.type.ListType.wrap(ListType.java:40)
[...]

Is this normal? (i guess not), but i mean, am i missing something in my
setup or is this a new bug?

besides from that, i was supprised to see how EMF hardcodes the
mechanism to define a map to a class with "key" and "value" (took me a
while to figure it out, didnt expect it to be so 'hardcoded'). Its a
surprising design decision indeed. i will see how we can approach the
problem for the EMap mapping to a <map [...]> hibernate clause.

thanks

Jean-Denis Boudreault wrote:
> Right-on,
>
> i will get at it ASAP and post a patch on the bug report when im done.
>
> thanks Martin :)
>
Re: EMaps and the missing @MapKey annotation [message #74943 is a reply to message #74811] Sun, 11 March 2007 17:08 Go to previous message
Jean-Denis Boudreault is currently offline Jean-Denis BoudreaultFriend
Messages: 55
Registered: July 2009
Member
Hi!

ok, im done with the fix. i attached the patch in bug 176833. this
would enable @MapKey as well as @Where annotations.

see bug report for more details.

regards,

Jean-Denis Boudreault wrote:
> Hi Martin, hope you dont mind if i ask a few questions as i
> investigate the code. I will try to keep it to a minimum.
>
>
> so, i got latest sources of teneo, emf and hibernate. i begun
> investigating runtime behavior of EMaps and here is where i am at for
> the moment:
>
> i found that an EMap type is mapped by teneo as a list in the
> .hbm.xml. example mapping:
>
>
>
> <class entity-name="someclass" abstract="false" lazy="false"
> discriminator-value="someclass" table="`someclass`">
> <meta attribute="eclassName">someclass</meta>
> <meta attribute="epackage">http://someclass</meta>
> <id type="long" name="e_id" column="e_id"
> access=" org.eclipse.emf.teneo.hibernate.mapping.identifier.Identifie rPropertyHandler ">
>
> <meta attribute="syntheticId">true</meta>
> <generator class="native"/>
> </id>
> <discriminator column="`dtype`" type="string"/>
> <property name="name" lazy="false" insert="true" update="true"
> not-null="false" unique="false" type="java.lang.String">
> <column not-null="false" unique="false" name="`name`"/>
> </property>
> /* <list name="somemap" lazy="true"
> cascade="merge,persist,save-update,lock,refresh">
> <key update="true">
> <column name="`*//*somechild_somemap*//*_e_id`"
> not-null="false" unique="false"/>
> </key>
> <list-index column="`somechild_somemap_idx`"/>
> <one-to-many entity-name="somekeyToValueEntry"/>
> </list>*/
> </class>
> [/*.hbm.xml]
>
> In the code, the hibernate property is defined as a listType, but
> obviously, a map is not a list (at least, a java.util.map is not a
> java.util.list). The class PersistableEMap returns a
> PersistableDelegatingMap in 'public Map<K, V> map()' for the type,
> which does not implement java.util.List. When hibernate tries to
> persist it all, it attempts a cast to List on a
> PersistableDelegatingMap instance, which fails with exception:
>
> Exception in thread "Thread-1" java.lang.ClassCastException:
> org.eclipse.emf.teneo.mapping.elist.PersistableEMap$Persista bleDelegatingMap
>
> at org.hibernate.type.ListType.wrap(ListType.java:40)
> [...]
>
> Is this normal? (i guess not), but i mean, am i missing something in
> my setup or is this a new bug?
>
> besides from that, i was supprised to see how EMF hardcodes the
> mechanism to define a map to a class with "key" and "value" (took me a
> while to figure it out, didnt expect it to be so 'hardcoded'). Its a
> surprising design decision indeed. i will see how we can approach the
> problem for the EMap mapping to a <map [...]> hibernate clause.
>
> thanks
>
> Jean-Denis Boudreault wrote:
>> Right-on,
>>
>> i will get at it ASAP and post a patch on the bug report when im done.
>>
>> thanks Martin :)
>>
Re: EMaps and the missing @MapKey annotation [message #603305 is a reply to message #74329] Thu, 08 March 2007 16:23 Go to previous message
Martin Taal is currently offline Martin TaalFriend
Messages: 5468
Registered: July 2009
Senior Member
Hi Jean-Denis,
EMap is supported. EMap has a very specific implementation, it is nl. a list of map entries. The
entries are generated by emf as separate explicit java classes. In correspondence to the emf
approach the emap is mapped to the db as a list with a specific map entity.

gr. Martin

Jean-Denis Boudreault wrote:
> Hello again,
>
> im very active these days in Teneo evaluation ;)
>
>
> I notice that the jpa annotation @MapKey is not currently supported by
> Teneo. does that mean that we can not use EMap fields with Teneo? and
> if we can, how can we set it up?
>
> if we can't, will it be supported if we add the mapkey clause directly
> in the xml.hbm file or will the Teneo runtime be incapable of handling
> EMaps?
>
>
> thanks!
>


--

With Regards, Martin Taal

Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
Re: EMaps and the missing @MapKey annotation [message #603321 is a reply to message #74367] Thu, 08 March 2007 19:00 Go to previous message
Jean-Denis Boudreault is currently offline Jean-Denis BoudreaultFriend
Messages: 55
Registered: July 2009
Member
thanks for your answer.

im not sure if it get it all, perhaps i dont understand very well how
teneo maps from the hibernate engine to the EMF datatypes.

But if i get it right, Teneo creates a oneToMany/ManyToOne relationship to
the owner object,is that it? then, how dies it define the key? is it
possible to perform this kind of mapping in teneo and define the column
used for the key? (or perhaps the key column is defined automatically?)

<scenario>
TableA

[ID: 1, Name: "entry1"]


TableB (joins table A on ID:ParentID)

[ID: 1, ParentID: 1, name="entry1"]
[ID: 2, ParentID: 1, name="entry2"]
[ID: 3 ParentID: 1, name="entry3"]


then, in code:

class TableAEntity
{
public Map<Integer, TableBEntity> childs;
}
</scenario>

where the key of the map is mapped to the ID column of TableB and the
value of the map is the TableB entity for this ID.

thanks for your time!
Re: EMaps and the missing @MapKey annotation [message #603327 is a reply to message #74439] Thu, 08 March 2007 20:45 Go to previous message
Martin Taal is currently offline Martin TaalFriend
Messages: 5468
Registered: July 2009
Senior Member
Hi JD,
Teneo maps from emf to hibernate (so the other way around). This means that it maps the emap to
hibernate in correspondence to the emf approach. For an emap entry emf (so not teneo but emf itself)
will generate a separate class (for example stringtostringemapentry or something). The emf emap is
not a real map but a list of these map entries (so not a hashmap with map entries). Because it is a
list it can not be mapped easily to a real map-like model in the db.
Teneo takes the separately generated map entry class and creates a mapping for that class as if it
is in the list of the owner. The entry class is modeled as a separate entity with its own primary
key (for example a generated id). This key has nothing to do with the map key (it does not really
need it).
Teneo just follows the emf approach here.

gr. Martin

JD wrote:
> thanks for your answer.
>
> im not sure if it get it all, perhaps i dont understand very well how
> teneo maps from the hibernate engine to the EMF datatypes.
>
> But if i get it right, Teneo creates a oneToMany/ManyToOne relationship
> to the owner object,is that it? then, how dies it define the key? is it
> possible to perform this kind of mapping in teneo and define the column
> used for the key? (or perhaps the key column is defined automatically?)
>
> <scenario>
> TableA
>
> [ID: 1, Name: "entry1"]
>
>
> TableB (joins table A on ID:ParentID)
>
> [ID: 1, ParentID: 1, name="entry1"]
> [ID: 2, ParentID: 1, name="entry2"]
> [ID: 3 ParentID: 1, name="entry3"]
>
>
> then, in code:
>
> class TableAEntity
> {
> public Map<Integer, TableBEntity> childs;
> }
> </scenario>
>
> where the key of the map is mapped to the ID column of TableB and the
> value of the map is the TableB entity for this ID.
>
> thanks for your time!
>


--

With Regards, Martin Taal

Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
Re: EMaps and the missing @MapKey annotation [message #603332 is a reply to message #74475] Thu, 08 March 2007 23:10 Go to previous message
Jean-Denis Boudreault is currently offline Jean-Denis BoudreaultFriend
Messages: 55
Registered: July 2009
Member
Hi Martin, thanks for your very detailed answers!

I guess where i am confused is how a list can behaves like a map, since how
does it provide the key/value functionality. i explain:

I just found on the EMF FAQ
( http://wiki.eclipse.org/index.php/EMF-FAQ#How_do_i_create_a_ Map_in_EMF.3F)
where they explain about EMaps. it surely concurs with your sayings. I have
two questions from there (i hope these questions dont annoy you, but if i
better understand, perhaps i can help too :))

1. In my ecore diagram, i create an EAttribute of EType EMap <K, V>
[java.util.Map]. When i generate the code, i get a good old java.util.Map. I
guess this is where i get confused. with a java.util.Map, can't we get
hibernate to function like it always did? and from there, wouldn't it be a
good idea to implement the @MapKey annotation?

2. Im pretty sure im not understanding well and you will explain to my why
the java.util.Map thing is wrong. then, if the EMap is a list of custom
mapEntries class, what happens behind the scenes when i do: myMap.ge(2)
specifying a key value? is there a hidden foreach in the implementation
that iterates the list of entries and returns the found result? and if so,
what prevents us from mapping a column in a oneToMany relationship as the
key to the mapEntries? there, the @MapKey annotation would be useful, to
define which column in the entity is to be used for key, instead of forcing
the ID column. am i being clear?

basically, if i get this right, we define a EClass for the EMap entries,
right? so, suppose we take my database example from before:

<scenario>
TableA

[ID: 1, Name: "entry1"]


TableB (joins table A on ID:ParentID)

[ID: 1, ParentID: 1, name="entry1", someUniqueField=233]
[ID: 2, ParentID: 1, name="entry2", someUniqueField=34456]
[ID: 3 ParentID: 1, name="entry3", someUniqueField=2342]

</scenario>

Then, if we want a map of type tableB with the key being someUniqueField
column, we could have:

SomeUniqueFieldToTableBEntry<Integer, TableBClass>

with this, it would make sense to have @MapKey defined to select the column
to be used to set the key.

am i making any sense?

anyways, i hope im getting this right, since perhaps i really dont know what
goes under the hood.

thanks for your help, this is much appreciated! :)

"Martin Taal" <mtaal@elver.org> wrote in message
news:espslr$uoj$1@utils.eclipse.org...
> Hi JD,
> Teneo maps from emf to hibernate (so the other way around). This means
> that it maps the emap to hibernate in correspondence to the emf approach.
> For an emap entry emf (so not teneo but emf itself) will generate a
> separate class (for example stringtostringemapentry or something). The emf
> emap is not a real map but a list of these map entries (so not a hashmap
> with map entries). Because it is a list it can not be mapped easily to a
> real map-like model in the db.
> Teneo takes the separately generated map entry class and creates a mapping
> for that class as if it is in the list of the owner. The entry class is
> modeled as a separate entity with its own primary key (for example a
> generated id). This key has nothing to do with the map key (it does not
> really need it).
> Teneo just follows the emf approach here.
>
> gr. Martin
>
> JD wrote:
>> thanks for your answer.
>>
>> im not sure if it get it all, perhaps i dont understand very well how
>> teneo maps from the hibernate engine to the EMF datatypes.
>>
>> But if i get it right, Teneo creates a oneToMany/ManyToOne relationship
>> to the owner object,is that it? then, how dies it define the key? is it
>> possible to perform this kind of mapping in teneo and define the column
>> used for the key? (or perhaps the key column is defined automatically?)
>>
>> <scenario>
>> TableA
>>
>> [ID: 1, Name: "entry1"]
>>
>>
>> TableB (joins table A on ID:ParentID)
>>
>> [ID: 1, ParentID: 1, name="entry1"]
>> [ID: 2, ParentID: 1, name="entry2"]
>> [ID: 3 ParentID: 1, name="entry3"]
>>
>>
>> then, in code:
>>
>> class TableAEntity
>> {
>> public Map<Integer, TableBEntity> childs;
>> }
>> </scenario>
>>
>> where the key of the map is mapped to the ID column of TableB and the
>> value of the map is the TableB entity for this ID.
>>
>> thanks for your time!
>>
>
>
> --
>
> With Regards, Martin Taal
>
> Springsite/Elver.org
> Office: Hardwareweg 4, 3821 BV Amersfoort
> Postal: Nassaulaan 7, 3941 EC Doorn
> The Netherlands
> Tel: +31 (0)84 420 2397
> Fax: +31 (0)84 225 9307
> Mail: mtaal@springsite.com - mtaal@elver.org
> Web: www.springsite.com - www.elver.org
Re: EMaps and the missing @MapKey annotation [message #603336 is a reply to message #74510] Thu, 08 March 2007 23:26 Go to previous message
Jean-Denis Boudreault is currently offline Jean-Denis BoudreaultFriend
Messages: 55
Registered: July 2009
Member
Hi,

i was just thinking about this and i think i get your point.

so basically if i get what your saying, the mapentry class is defined in a
table of its own (entity), and the key is probably the unique ID of this
class, is that it? the value itself is either a column type or a onetoone
reference to another entity table.

so, following this logic, there would be no way to make direct relationships
to other entity table, without going through this 'intermediary' entity
being the mapentry.

If this is so, could it be possible to eliminate the need to explicitely
define a mapEntry entity and let teneo generate one in the background? foe
example:


KeyToValueEntry<K, V>.

then, there would be no need to have an intermediary table, and we could
directly specify the key column and the entity type. so we could create:

<pseudocode>
ClassA
{
public EMap<Integer, ClassB> field;
}
</pseudocode>

and with anotations define the column of the entity that is used as the Key
with @MapKey. in the background, teneo could generate this
KeyToValueEntry<K, V> list and dynamically rebuild an EMap. In the xml.hbm
file, there would be not intermediary entity, just a map from EnityA to
EntityB with a key column defined.

how does that sound? (i could be right off, sorry if i am, jsut trying to
help)

"Jean-Denis Boudreault" <jdboudreault@gmail.com> wrote in message
news:esq552$ekj$1@utils.eclipse.org...
> Hi Martin, thanks for your very detailed answers!
>
> I guess where i am confused is how a list can behaves like a map, since
> how does it provide the key/value functionality. i explain:
>
> I just found on the EMF FAQ
> ( http://wiki.eclipse.org/index.php/EMF-FAQ#How_do_i_create_a_ Map_in_EMF.3F)
> where they explain about EMaps. it surely concurs with your sayings. I
> have two questions from there (i hope these questions dont annoy you, but
> if i better understand, perhaps i can help too :))
>
> 1. In my ecore diagram, i create an EAttribute of EType EMap <K, V>
> [java.util.Map]. When i generate the code, i get a good old java.util.Map.
> I guess this is where i get confused. with a java.util.Map, can't we get
> hibernate to function like it always did? and from there, wouldn't it be
> a good idea to implement the @MapKey annotation?
>
> 2. Im pretty sure im not understanding well and you will explain to my why
> the java.util.Map thing is wrong. then, if the EMap is a list of custom
> mapEntries class, what happens behind the scenes when i do: myMap.ge(2)
> specifying a key value? is there a hidden foreach in the implementation
> that iterates the list of entries and returns the found result? and if
> so, what prevents us from mapping a column in a oneToMany relationship as
> the key to the mapEntries? there, the @MapKey annotation would be useful,
> to define which column in the entity is to be used for key, instead of
> forcing the ID column. am i being clear?
>
> basically, if i get this right, we define a EClass for the EMap entries,
> right? so, suppose we take my database example from before:
>
> <scenario>
> TableA
>
> [ID: 1, Name: "entry1"]
>
>
> TableB (joins table A on ID:ParentID)
>
> [ID: 1, ParentID: 1, name="entry1", someUniqueField=233]
> [ID: 2, ParentID: 1, name="entry2", someUniqueField=34456]
> [ID: 3 ParentID: 1, name="entry3", someUniqueField=2342]
>
> </scenario>
>
> Then, if we want a map of type tableB with the key being someUniqueField
> column, we could have:
>
> SomeUniqueFieldToTableBEntry<Integer, TableBClass>
>
> with this, it would make sense to have @MapKey defined to select the
> column to be used to set the key.
>
> am i making any sense?
>
> anyways, i hope im getting this right, since perhaps i really dont know
> what goes under the hood.
>
> thanks for your help, this is much appreciated! :)
>
> "Martin Taal" <mtaal@elver.org> wrote in message
> news:espslr$uoj$1@utils.eclipse.org...
>> Hi JD,
>> Teneo maps from emf to hibernate (so the other way around). This means
>> that it maps the emap to hibernate in correspondence to the emf approach.
>> For an emap entry emf (so not teneo but emf itself) will generate a
>> separate class (for example stringtostringemapentry or something). The
>> emf emap is not a real map but a list of these map entries (so not a
>> hashmap with map entries). Because it is a list it can not be mapped
>> easily to a real map-like model in the db.
>> Teneo takes the separately generated map entry class and creates a
>> mapping for that class as if it is in the list of the owner. The entry
>> class is modeled as a separate entity with its own primary key (for
>> example a generated id). This key has nothing to do with the map key (it
>> does not really need it).
>> Teneo just follows the emf approach here.
>>
>> gr. Martin
>>
>> JD wrote:
>>> thanks for your answer.
>>>
>>> im not sure if it get it all, perhaps i dont understand very well how
>>> teneo maps from the hibernate engine to the EMF datatypes.
>>>
>>> But if i get it right, Teneo creates a oneToMany/ManyToOne relationship
>>> to the owner object,is that it? then, how dies it define the key? is it
>>> possible to perform this kind of mapping in teneo and define the column
>>> used for the key? (or perhaps the key column is defined automatically?)
>>>
>>> <scenario>
>>> TableA
>>>
>>> [ID: 1, Name: "entry1"]
>>>
>>>
>>> TableB (joins table A on ID:ParentID)
>>>
>>> [ID: 1, ParentID: 1, name="entry1"]
>>> [ID: 2, ParentID: 1, name="entry2"]
>>> [ID: 3 ParentID: 1, name="entry3"]
>>>
>>>
>>> then, in code:
>>>
>>> class TableAEntity
>>> {
>>> public Map<Integer, TableBEntity> childs;
>>> }
>>> </scenario>
>>>
>>> where the key of the map is mapped to the ID column of TableB and the
>>> value of the map is the TableB entity for this ID.
>>>
>>> thanks for your time!
>>>
>>
>>
>> --
>>
>> With Regards, Martin Taal
>>
>> Springsite/Elver.org
>> Office: Hardwareweg 4, 3821 BV Amersfoort
>> Postal: Nassaulaan 7, 3941 EC Doorn
>> The Netherlands
>> Tel: +31 (0)84 420 2397
>> Fax: +31 (0)84 225 9307
>> Mail: mtaal@springsite.com - mtaal@elver.org
>> Web: www.springsite.com - www.elver.org
>
>
Re: EMaps and the missing @MapKey annotation [message #603349 is a reply to message #74528] Fri, 09 March 2007 11:18 Go to previous message
Jean-Denis Boudreault is currently offline Jean-Denis BoudreaultFriend
Messages: 55
Registered: July 2009
Member
Hello again,


i deeply apologize for the verbose, but i think this can actually be very
useful. This post may be long and detailed, but i want to make sure it is
clear.


So, i went a head and took a look at the BasicEList and BasicEMap
implementation files of EMF 2.3. So, now i understand what you were saying
about EMaps. it is in reality just a list, of the type map.entry. Where we
get an object by key in the EMap, it basically loops the list until it
finds the entry for that key. (I guess we should create an EMF feature
request for a EHashmap then since this is not very efficient for large
lists).


but, back to teneo. lets take this POJO scenario:

<code>
public class parent
{
int ID;

// the key is the GUID
public EMap<String, child>
}

public class child
{
int ID;
string GUID;
String name;
}
</code>

basically, a parent class holds a collection of child class, and to
accelerate lookup, keeps a map where the key is the unique string GUID of
the parent class. the datbase tables might look like this:

<dbschema>
--------------------
| PARENT |
--------------------
| Int | ID |
--------------------



--------------------
| CHILD |
--------------------
| Int | ID |
| Int |parentID|
| varchar | GUID |
| varchar | name |
--------------------

where there is a join in ID/ParentID

</dbschema>

Now, if we created a EList collection instead of a EMap, it would be a
simple thing, we would simply add a manyToOne/OneToMany hibernate
relationship on the collection to get it going.

but with emaps, its slightly different. to go with EMF, what teneo
currently does (if i correctly understand Martin's explanation) is to add
a third table, which is a 'middleman' joining table that represents the
map.Entry. this table has a field for the key and the value. this im not
sure, but i assume the value could also be a oneToOne join to the child
table. For this reason, the @MapKey is not supported, since there is no
other field to select the key from; just the defined field 'KEY' in that
table.

here is my suggestion: (i hope it makes sense).

when we think of it, a map really is just a list, with a key that
simplifies each entries lookup (hence the EMap design decision). for this
reason, pure hibernate allows for parent/*childs collections to be mapped
either as lists, or as maps where we can define which column can be used
as the key (hence @MapKey).

i belive it could be possible to allow teneo to function the same way, by
eliminating the burden on the developper of maintaining manually the
map.Entry 'KeyToValueEntry' class. Teneo could consider the EMap mapping
to be a EList, with a key column. The table mapping could remain the same
as EList. when rebuilding the list at load time, Teneo could dynamically
create a map.Entry<K,V> for each list entry, and then use the key column
defined to set the key value. this is basically what hibernate does too.

so, we could have in the database:

[parent table]
ID: 1

[child table]
ID: 1; ParentID: 1l GUID: 'whatever', name: 'name1'
ID: 2; ParentID: 1l GUID: 'whatever2', name: 'name2'
ID: 3; ParentID: 1l GUID: 'whatever3', name: 'name3'

then, the runtime loaded class could have a list of childs, and the key
set at the GUID (defiend by @MapKey annotation).

we could then search by key (here GUID) like this:
child chld = parent.childs.Get("whatever2"); // returns the child with ID=2


so, basically, my suggestion is to keep closer to the hibernate
methodology and map it to EMF, rather than map EMF to hibernate. This way
is just as valid, but removes the need to manually create / handle the
keyToValueEntry classes as well as map them to the table schema,
complicating map like options such as defining the key.


so, what do you think?


thanks and i hope this helps
Re: EMaps and the missing @MapKey annotation [message #603357 is a reply to message #74582] Fri, 09 March 2007 16:18 Go to previous message
Martin Taal is currently offline Martin TaalFriend
Messages: 5468
Registered: July 2009
Senior Member
Hi Jean-Denis,
No problem of being verbose :-).
Just to react on point in your description: you say that the developer manually has to create/handle
the keyToValueEntry class. However these entry classes are also generated by emf. The entry classes
are hidden for the developer using the emf objects. So the developer does not need create/handle
these classes manually. Or am I maybe missing your point here?

For me the real issue is in the current database mapping. From a relational-mapping perspective the
issue with the current approach is that the resulting database model has redundant information: the
key is repeated in a separate field while it can be present in the value-entity. Also the current
approach will always create a join table while this is not always required. In addition the entry
class will always get a synthetic id and version which does not work in case of client-server scenarios.

Your proposal is interesting and certainly something to try out. I can also look again at mapping an
emap as a real map.
Can you enter a separate bugzilla for this (change relational mapping of emap) and copy the contents
of these posting into it? Then I can take it from there. This is some work so it will probably take
some time (number of weeks) before I can spend time on it.

gr. Martin

Jean-Denis Boudreault wrote:
> Hello again,
>
>
> i deeply apologize for the verbose, but i think this can actually be
> very useful. This post may be long and detailed, but i want to make sure
> it is clear.
>
>
> So, i went a head and took a look at the BasicEList and BasicEMap
> implementation files of EMF 2.3. So, now i understand what you were
> saying about EMaps. it is in reality just a list, of the type map.entry.
> Where we get an object by key in the EMap, it basically loops the list
> until it finds the entry for that key. (I guess we should create an EMF
> feature request for a EHashmap then since this is not very efficient for
> large lists).
>
>
> but, back to teneo. lets take this POJO scenario:
>
> <code>
> public class parent
> {
> int ID;
>
> // the key is the GUID
> public EMap<String, child>
> }
>
> public class child
> {
> int ID;
> string GUID;
> String name;
> }
> </code>
>
> basically, a parent class holds a collection of child class, and to
> accelerate lookup, keeps a map where the key is the unique string GUID
> of the parent class. the datbase tables might look like this:
>
> <dbschema>
> --------------------
> | PARENT |
> --------------------
> | Int | ID |
> --------------------
>
>
>
> --------------------
> | CHILD |
> --------------------
> | Int | ID |
> | Int |parentID|
> | varchar | GUID |
> | varchar | name |
> --------------------
>
> where there is a join in ID/ParentID
>
> </dbschema>
>
> Now, if we created a EList collection instead of a EMap, it would be a
> simple thing, we would simply add a manyToOne/OneToMany hibernate
> relationship on the collection to get it going.
>
> but with emaps, its slightly different. to go with EMF, what teneo
> currently does (if i correctly understand Martin's explanation) is to
> add a third table, which is a 'middleman' joining table that represents
> the map.Entry. this table has a field for the key and the value. this im
> not sure, but i assume the value could also be a oneToOne join to the
> child table. For this reason, the @MapKey is not supported, since there
> is no other field to select the key from; just the defined field 'KEY'
> in that table.
>
> here is my suggestion: (i hope it makes sense).
>
> when we think of it, a map really is just a list, with a key that
> simplifies each entries lookup (hence the EMap design decision). for
> this reason, pure hibernate allows for parent/*childs collections to be
> mapped either as lists, or as maps where we can define which column can
> be used as the key (hence @MapKey).
>
> i belive it could be possible to allow teneo to function the same way,
> by eliminating the burden on the developper of maintaining manually the
> map.Entry 'KeyToValueEntry' class. Teneo could consider the EMap mapping
> to be a EList, with a key column. The table mapping could remain the
> same as EList. when rebuilding the list at load time, Teneo could
> dynamically create a map.Entry<K,V> for each list entry, and then use
> the key column defined to set the key value. this is basically what
> hibernate does too.
>
> so, we could have in the database:
>
> [parent table]
> ID: 1
>
> [child table]
> ID: 1; ParentID: 1l GUID: 'whatever', name: 'name1'
> ID: 2; ParentID: 1l GUID: 'whatever2', name: 'name2'
> ID: 3; ParentID: 1l GUID: 'whatever3', name: 'name3'
>
> then, the runtime loaded class could have a list of childs, and the key
> set at the GUID (defiend by @MapKey annotation).
>
> we could then search by key (here GUID) like this:
> child chld = parent.childs.Get("whatever2"); // returns the child with ID=2
>
>
> so, basically, my suggestion is to keep closer to the hibernate
> methodology and map it to EMF, rather than map EMF to hibernate. This
> way is just as valid, but removes the need to manually create / handle
> the keyToValueEntry classes as well as map them to the table schema,
> complicating map like options such as defining the key.
>
>
> so, what do you think?
>
>
> thanks and i hope this helps
>
>


--

With Regards, Martin Taal

Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
Re: EMaps and the missing @MapKey annotation [message #603360 is a reply to message #74618] Fri, 09 March 2007 16:29 Go to previous message
Jean-Denis Boudreault is currently offline Jean-Denis BoudreaultFriend
Messages: 55
Registered: July 2009
Member
Thanks Martin,

it will be a pleasure to log a feature request. BTW, should you deem it
useful, i am ready to help on this topic as it would be most useful for my
own projects which i am migrating to Teneo.

in any case, thanks for listening and being open to suggestions :)
Re: EMaps and the missing @MapKey annotation [message #603363 is a reply to message #74636] Fri, 09 March 2007 16:38 Go to previous message
Jean-Denis Boudreault is currently offline Jean-Denis BoudreaultFriend
Messages: 55
Registered: July 2009
Member
Feature request created with ID: 176833

(got a little formatting problem in the description, I hope this is not
important.)
Re: EMaps and the missing @MapKey annotation [message #603366 is a reply to message #74636] Fri, 09 March 2007 17:03 Go to previous message
Martin Taal is currently offline Martin TaalFriend
Messages: 5468
Registered: July 2009
Senior Member
Hi Jean-Denis,
Contributions are always wellcomed ofcourse!

If you are interested to try this out, the main changes (afaics) are:
- In the defaultannotator class there is a method processOneToManyReference. In this method the
target entity name has to be set to the eclass name of the value eclass (not the entry eclass).
- The HibernatePersistableEList is the list handler for hibernate. It extends PersistableElist which
extends DelegatingEcoreEList. The delegate list in these classes is the hibernate list (which
connects to the actual db). A possible solution approach is in the constructor of the
PersistableEList to wrap the hibernate list again in a new EMapEntryConvertingList (or another nice
name) which takes case of converting all calls from and to the hibernate list from/to the correct
map entry class.

At first I would not try to think about to handle the mapkey mapping but just get it working with a
hard coded key.

And ofcourse a test case proving that it all works is a prerequisite...

gr. Martin

Jean-Denis Boudreault wrote:
> Thanks Martin,
>
> it will be a pleasure to log a feature request. BTW, should you deem it
> useful, i am ready to help on this topic as it would be most useful for
> my own projects which i am migrating to Teneo.
>
> in any case, thanks for listening and being open to suggestions :)
>


--

With Regards, Martin Taal

Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
Re: EMaps and the missing @MapKey annotation [message #603369 is a reply to message #74671] Fri, 09 March 2007 17:12 Go to previous message
Jean-Denis Boudreault is currently offline Jean-Denis BoudreaultFriend
Messages: 55
Registered: July 2009
Member
Right-on,


i will get at it ASAP and post a patch on the bug report when im done.

thanks Martin :)
Re: EMaps and the missing @MapKey annotation [message #603406 is a reply to message #74689] Sat, 10 March 2007 17:27 Go to previous message
Jean-Denis Boudreault is currently offline Jean-Denis BoudreaultFriend
Messages: 55
Registered: July 2009
Member
Hi Martin, hope you dont mind if i ask a few questions as i
investigate the code. I will try to keep it to a minimum.


so, i got latest sources of teneo, emf and hibernate. i begun
investigating runtime behavior of EMaps and here is where i am at for
the moment:

i found that an EMap type is mapped by teneo as a list in the .hbm.xml.
example mapping:



<class entity-name="someclass" abstract="false" lazy="false"
discriminator-value="someclass" table="`someclass`">
<meta attribute="eclassName">someclass</meta>
<meta attribute="epackage">http://someclass</meta>
<id type="long" name="e_id" column="e_id"
access=" org.eclipse.emf.teneo.hibernate.mapping.identifier.Identifie rPropertyHandler ">
<meta attribute="syntheticId">true</meta>
<generator class="native"/>
</id>
<discriminator column="`dtype`" type="string"/>
<property name="name" lazy="false" insert="true" update="true"
not-null="false" unique="false" type="java.lang.String">
<column not-null="false" unique="false" name="`name`"/>
</property>
/* <list name="somemap" lazy="true"
cascade="merge,persist,save-update,lock,refresh">
<key update="true">
<column name="`*//*somechild_somemap*//*_e_id`"
not-null="false" unique="false"/>
</key>
<list-index column="`somechild_somemap_idx`"/>
<one-to-many entity-name="somekeyToValueEntry"/>
</list>*/
</class>
[/*.hbm.xml]

In the code, the hibernate property is defined as a listType, but
obviously, a map is not a list (at least, a java.util.map is not a
java.util.list). The class PersistableEMap returns a
PersistableDelegatingMap in 'public Map<K, V> map()' for the type, which
does not implement java.util.List. When hibernate tries to persist it
all, it attempts a cast to List on a PersistableDelegatingMap instance,
which fails with exception:

Exception in thread "Thread-1" java.lang.ClassCastException:
org.eclipse.emf.teneo.mapping.elist.PersistableEMap$Persista bleDelegatingMap
at org.hibernate.type.ListType.wrap(ListType.java:40)
[...]

Is this normal? (i guess not), but i mean, am i missing something in my
setup or is this a new bug?

besides from that, i was supprised to see how EMF hardcodes the
mechanism to define a map to a class with "key" and "value" (took me a
while to figure it out, didnt expect it to be so 'hardcoded'). Its a
surprising design decision indeed. i will see how we can approach the
problem for the EMap mapping to a <map [...]> hibernate clause.

thanks

Jean-Denis Boudreault wrote:
> Right-on,
>
> i will get at it ASAP and post a patch on the bug report when im done.
>
> thanks Martin :)
>
Re: EMaps and the missing @MapKey annotation [message #603455 is a reply to message #74811] Sun, 11 March 2007 17:08 Go to previous message
Jean-Denis Boudreault is currently offline Jean-Denis BoudreaultFriend
Messages: 55
Registered: July 2009
Member
Hi!

ok, im done with the fix. i attached the patch in bug 176833. this
would enable @MapKey as well as @Where annotations.

see bug report for more details.

regards,

Jean-Denis Boudreault wrote:
> Hi Martin, hope you dont mind if i ask a few questions as i
> investigate the code. I will try to keep it to a minimum.
>
>
> so, i got latest sources of teneo, emf and hibernate. i begun
> investigating runtime behavior of EMaps and here is where i am at for
> the moment:
>
> i found that an EMap type is mapped by teneo as a list in the
> .hbm.xml. example mapping:
>
>
>
> <class entity-name="someclass" abstract="false" lazy="false"
> discriminator-value="someclass" table="`someclass`">
> <meta attribute="eclassName">someclass</meta>
> <meta attribute="epackage">http://someclass</meta>
> <id type="long" name="e_id" column="e_id"
> access=" org.eclipse.emf.teneo.hibernate.mapping.identifier.Identifie rPropertyHandler ">
>
> <meta attribute="syntheticId">true</meta>
> <generator class="native"/>
> </id>
> <discriminator column="`dtype`" type="string"/>
> <property name="name" lazy="false" insert="true" update="true"
> not-null="false" unique="false" type="java.lang.String">
> <column not-null="false" unique="false" name="`name`"/>
> </property>
> /* <list name="somemap" lazy="true"
> cascade="merge,persist,save-update,lock,refresh">
> <key update="true">
> <column name="`*//*somechild_somemap*//*_e_id`"
> not-null="false" unique="false"/>
> </key>
> <list-index column="`somechild_somemap_idx`"/>
> <one-to-many entity-name="somekeyToValueEntry"/>
> </list>*/
> </class>
> [/*.hbm.xml]
>
> In the code, the hibernate property is defined as a listType, but
> obviously, a map is not a list (at least, a java.util.map is not a
> java.util.list). The class PersistableEMap returns a
> PersistableDelegatingMap in 'public Map<K, V> map()' for the type,
> which does not implement java.util.List. When hibernate tries to
> persist it all, it attempts a cast to List on a
> PersistableDelegatingMap instance, which fails with exception:
>
> Exception in thread "Thread-1" java.lang.ClassCastException:
> org.eclipse.emf.teneo.mapping.elist.PersistableEMap$Persista bleDelegatingMap
>
> at org.hibernate.type.ListType.wrap(ListType.java:40)
> [...]
>
> Is this normal? (i guess not), but i mean, am i missing something in
> my setup or is this a new bug?
>
> besides from that, i was supprised to see how EMF hardcodes the
> mechanism to define a map to a class with "key" and "value" (took me a
> while to figure it out, didnt expect it to be so 'hardcoded'). Its a
> surprising design decision indeed. i will see how we can approach the
> problem for the EMap mapping to a <map [...]> hibernate clause.
>
> thanks
>
> Jean-Denis Boudreault wrote:
>> Right-on,
>>
>> i will get at it ASAP and post a patch on the bug report when im done.
>>
>> thanks Martin :)
>>
Previous Topic:Name mapping
Next Topic:[Teneo] Invalid subclass tag in hibernate mapping file .
Goto Forum:
  


Current Time: Thu Mar 28 22:55:23 GMT 2024

Powered by FUDForum. Page generated in 0.03915 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top