java - Map<String, Entity> with composite key in Entity -
i've got following 2 tables:
table a: int id varchar x primary key (id) table b: int a_id varchar locale varchar z primary key (a_id, locale)
it's simple onetomany relation. table b
contains the id (a_id
) of referenced row in table a
plus locale
. means: every entry in a
can have 0..*
entries in table b
, each 1 distinct locale
value.
i have following 2 classes, should represent tables:
@entity @table(name="a") class { @id @column(name="id") int id; @column(name="x") string x; @onetomany(mappedby="a") // ??? @mapkey... // ??? map<string, b> bmap; } @entity @table(name="b") class b { @manytoone @joincolumn(name="a_id") a; @column(name="locale") string locale; @column(name="z") string z; }
now 2 things missing:
the annotations
map<string, b> bmap
. don't know if should use@mapkey
or@mapkeycolumn
, how map composite key. , if should/have use@onetomany
?the
b
class of course needs composite key. should use@embeddedid
or@idclass
?
could provide example code scenario?
thank you!
working solution @ bottom
i think, i've managed put things together. @ least generated sql tables right, though still have figure out how cascaded saving done...
@entity @table(name="a") public class { @id @generatedvalue(strategy=generationtype.auto) long id; @column(name="x") string x; @onetomany(mappedby="id.a", cascade=cascadetype.all, orphanremoval=true) @mapkey(name="id.locale") map<string, b> bmap = new hashmap<string, b>(); } @entity @table(name="b") public class b { @embeddedid bpk id; @column(name="z") string z; } @embeddable public class bpk implements serializable { @manytoone @joincolumn(name="a_id") a; @column(name="locale") string locale; // equals + hashcode }
when calling arepository.findbyid(...)
hibernates gives:
hibernate: select * a a.id=?
which correct.
but if call aentity.getbmap()
fetches whole map, if want use aentity.getbmap().put("en", somebobject)
, don't want read data it. that's okay now.
now i've figure out how cascaded saving work. when doing aentity.getbmap().put("en", somebobject); arepository.save(eentity);
get
org.hibernate.id.identifiergenerationexception: null id generated for:class b
i think i'm missing setters @embeddedid
or it's fields.
finally solved:
cascaded saving somehow didn't work @embeddedid
composite key. thought , figured out, instead use @elementcollection
! :)
.
so here's did:
@entity @table(name="a") public class { @id @generatedvalue(strategy=generationtype.auto) long id; @column(name="x") string x; @elementcollection @collectiontable(name="b", joincolumns=@joincolumn(name="a_id")) @mapkeycolumn(name="locale") map<string, b> bmap = new hashmap<string, b>(); } @embeddable public class b { @column(name="z") string z; }
hibernate outputs:
a = arepository.findbyid(...)
- hibernate: select * id=?
a.getbmap().put("en", somebobject)
- hibernate: select * b a_id=?
arepository.save(a)
- hibernate: insert b (a_id, locale, z) values (?, ?, ?)
Comments
Post a Comment