Hi all,
I have a problem when using @ElementCollection and @MapKeyColumn.
Problem occurs when no value is given (null) for a key.
(I'm using hibernate-core:3.5.6 and hibernate-annotations:3.5.6)
Here my example:
I have following two tables:
MYENTITY - this tables holds unlocalized attributes for my entity
Code:
pk | property1 | property2 ...
-----------------------------
1 | prop1 | prop2
MYENTITY_L10N - this table holds localized attributes for my entity
Code:
pk | langiso | name | pk_myentity
--------------------------------
1 | de | german | 1
2 | en | english | 1
3 | fr | (null) | 1
This is my entity class:
Code:
//no hibernate specific annotations used
import javax.persistence.*
@Entity(name = "MYENTITY")
@SecondaryTables(value = @SecondaryTable(name = "MYENTITY_L10N", pkJoinColumns = @PrimaryKeyJoinColumn(name = "PK_MYENTITY")))
public class MyEntity
{
@Id
@Column(name = "PK")
private int pk;
@ElementCollection(fetch = FetchType.EAGER)
@MapKeyColumn(name = "LANGISO", table = "MYENTITY_L10N")
@Column(name = "NAME", table = "MYENTITY_L10N")
@JoinTable(name = "MYENTITY_L10N", joinColumns = @JoinColumn(name = "PK_MYENTITY"))
private Map<String, String> allNames;
//...
public Map<String, String> getAllNames()
{
return allNames;
}
//...
}
I'm particularly interested in localized properties.
And here is my code:
Code:
public void test(Session session) {
MyEntity e = (MyEntity) session.load(MyEntity.class, Integer.valueOf(1));
Map m = e.getAllNames();
LOG.info(m.get("de")); //prints 'german'
LOG.info(m.get("en")); //prints 'english'
LOG.info(m.get("fr")); //prints nothing
//works
//Hibernate: update MYENTITY_L10N set NAME=? where PK_MYENTITY=? and LANGISO=?
m.put("de", "new value");
//works
//Hibernate: update MYENTITY_L10N set NAME=? where PK_MYENTITY=? and LANGISO=?
m.put("en", "new value");
//does not work
//Hibernate: insert into MYENTITY_L10N (PK_MYENTITY, LANGISO, NAME) values (?, ?, ?)
m.put("fr", "new value");
}
What i didn't expect is that hibernate fires an insert statement (which of course leads to a constraint violation)
when putting a value for 'fr'. Instead i need an update here like it was done for 'de' and 'en'
It seems that i never have a chance to update a value which initially is 'null'.
Another fact is that i can nullify an existing non-null value like that:
Code:
m.put("de", null); //Hibernate: update MYENTITY_L10N set NAME=? where PK_MYENTITY=? and LANGISO=?
and after commiting and trying to work with "de" again i have no chance.
Code:
m.put("de", "german"); //Hibernate: insert into MYENTITY_L10N (PK_MYENTITY, LANGISO, NAME) values (?, ?, ?)
Anybody have a clue?
Is there any chance with my mapping above to update a 'null' value?
Additional question:
When changing FetchType.EAGER to FetchType.LAZY i get this exception:
org.hibernate.HibernateException: More than one row with the given identifier was found: 1, for class: entity.MyEntityAnd i don't know why.
thx for help
Denny