I have a problem with inserting elements into an @ElementCollection
represented by a Map. When inserting elements with same values, they are not persisted.
Given following @Entity
and its @Embeddable
:
@Entity
@Table(name = "category", catalog = "my_db", schema = "")
public class Category implements Serializable {
@Id
@Column(name = "id")
private Integer id;
@ElementCollection(fetch = FetchType.LAZY, targetClass = CategoryLabels.class)
@CollectionTable(name = "category_labels", joinColumns =
@JoinColumn(name = "category_id"), catalog = "my_db")
@MapKeyColumn(name = "language_id")
private Map<Integer, CategoryLabels> labels = new HashMap<Integer, CategoryLabels>();
...
}
@Embeddable
public class CategoryLabels implements Serializable {
@Column(name = "label1")
private String label1;
@Column(name = "label2")
private String label2;
...
}
Database entries
+-------------+-------------+-----------+---------+
| category_id | language_id | label1 | label2 |
+-------------+-------------+-----------+---------+
| 183 | 1 | Capacity | Timings |
| 183 | 2 | | |
+-------------+-------------+-----------+---------+
Inserting works fine, if label1 and label2 differ for each map entry (as seen above).
But if I add one entry that has the same values for label1 and label2 as another entry, the second one is never persisted to the database. For example, if I add an entry to the Map with both labels empty (like the second entry in the example) but with language_id=3, this will never get persisted.
I am aware of this common problem: http://en.wikibooks.org/wiki/Java_Persistence/ElementCollection#Common_Problems and that embedded objects without ID are checked for their fields and foreign key @JoinColumns
as ID.
This does not seem to work in my case, the foreign key in the @JoinColumn
is completely ignored for the ID-check.
Is this a bug in Eclipselink or am I doing something wrong?
EDIT:
I've set -Declipselink.logging.level=FINEST
and this reveals that no SQLs are executed for the second and following entries with empty labels.
Additionally I've made a sample project with which you can reproduce the problem: http://bit.ly/1bR8ywO
Just tested again and I found out, that the problem is dedicated to the transaction management. I didn't want to use transactions at all so I annotated my SLSB with @TransactionManagement(TransactionManagementType.BEAN)
.
When I remove this, the transaction gets managed by the container and then the update works as expected.
Setting the transaction management to container managed is not the solution I hoped for but this works for now. Still I think this is a bug in eclipselink.