-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 
Author Message
 Post subject: How to persist Map<Integer, Entity> with Annotations?
PostPosted: Mon Jan 19, 2009 6:24 am 
Newbie

Joined: Mon Jan 19, 2009 6:11 am
Posts: 5
Hi,
i tried to persist a Map with something like this:

[code]
@CollectionOfElements(targetElement=Title.class)
@JoinTable(name = "titleList")
@org.hibernate.annotations.MapKeyManyToMany(targetEntity=Integer.class)
private Map<Integer, Title> titleList;
[/code]

Title is a simple Entity with only one string attribute (+PK) and the following error occurs:

org.hibernate.exception.SQLGrammarException: could not insert collection
Caused by: com.ibm.db2.jcc.c.SqlException: DB2 SQL error: SQLCODE: -204, SQLSTATE: 42704, SQLERRMC: DBPRAK06.TITLELIST
Exception in thread "main" org.hibernate.exception.ConstraintViolationException: could not insert collection
(some lines ommited)

cheers gerb

----

bleeding edge versions of hibernate and dependencies


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 19, 2009 7:46 am 
Beginner
Beginner

Joined: Wed Nov 19, 2008 8:25 am
Posts: 46
Location: Saint Petersburg, Russian Federation
You misuse @MapKeyManyToMany here. Ordinary map entity mapping assumes that the entity is a map entry's value (your situation). @MapKeyManyToMany is used when the entity is an entry's key.

So, the mapping looks like the following in your case:
Code:
@MapKey
    @ManyToMany
    @JoinTable(
        name = "titleList",
        joinColumns = @JoinColumn(name = "<current-entity-pk>"),
        inverseJoinColumns = @JoinColumn(name = "<title-pk>")
    )
    private Map<Integer, Title> titleList;


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 19, 2009 8:09 am 
Newbie

Joined: Mon Jan 19, 2009 6:11 am
Posts: 5
hi denis,
thank you for your help!

one more thing:

there is no such column as the key of the map!? where is it persisted? if I load the objects from the db, and do something like:

[code]
cd.printTitleList()
[/code]

the cd knows the track number of it's tracks!

thanks!!


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 19, 2009 8:40 am 
Beginner
Beginner

Joined: Wed Nov 19, 2008 8:25 am
Posts: 46
Location: Saint Petersburg, Russian Federation
gerb wrote:
hi denis,
thank you for your help!


welcome

gerb wrote:
hi denis,
one more thing:

there is no such column as the key of the map!? where is it persisted?


@MapKey allows to specify what property of the referenced entity should be used as a map key. Entity id is used by default (i.e. Title id in your case). You may specify any other property as well. The property is stored/loaded in accordance with the mapping settings defined at the referenced entity ('Title' in your case)

I.e. if you have 'Title.tracksNumber' property at the java level and want to define many-to-many mapping for Map<Integer/*tracks number*/, Title> with join table which columns are PKs of the 'Cd' and 'Title' entities, you can use the following mapping:

Code:
@MapKey(name = "tracksNumber")
@ManyToMany
@JoinTable(name = "titleList")
private Map<Integer, Title> titleList;


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 19, 2009 9:01 am 
Newbie

Joined: Mon Jan 19, 2009 6:11 am
Posts: 5
thanks again,

and if i don't want to save the trackNumber in Title?
What happens if i put the same title in two differnt cd's with different track numbers?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 19, 2009 9:25 am 
Beginner
Beginner

Joined: Wed Nov 19, 2008 8:25 am
Posts: 46
Location: Saint Petersburg, Russian Federation
gerb wrote:
thanks again,

and if i don't want to save the trackNumber in Title?
What happens if i put the same title in two differnt cd's with different track numbers?


Ok, I see your point. So, you're interested in track number only in context of particular album. You can use hibernate's @MapKey annotation then:

Code:
@ManyToMany
@JoinTable(name = "titleList")
@org.hibernate.annotations.MapKey(columns = @Column(name = "TRACK_NUMBER"))
private Map<Integer, Title> titleList;


Here your join table contains PKs of the Album and Title entities (composite TITLE_LIST PK) as well as a TRACK_NUMBER column that backs the key of the 'titleList' map.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 19, 2009 10:11 am 
Newbie

Joined: Mon Jan 19, 2009 6:11 am
Posts: 5
it's finally working! thanks for your patience...

some small additional info for db2:

you have to add "nullable=false":

@org.hibernate.annotations.MapKey(columns = { @Column(name = "trackNumber", nullable=false)} )

if it's not added, it is not possible to generate the table!

cheers gerb


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.