我在将元素插入由映射表示的@ElementCollection
时遇到问题。当插入具有相同值的元素时,它们不会被持久化。
给出如下@Entity
及其@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;
...
}
数据库条目
+-------------+-------------+-----------+---------+
| category_id | language_id | label1 | label2 |
+-------------+-------------+-----------+---------+
| 183 | 1 | Capacity | Timings |
| 183 | 2 | | |
+-------------+-------------+-----------+---------+
如果每个地图条目的label1和label2不同(如上所示),则插入工作正常。
但是,如果我添加一个label1和label2的值与另一个条目的值相同的条目,那么第二个条目将永远不会持久化到数据库中。
例如,如果我在映射中添加了一个两个标签都为空的条目(如示例中的第二个条目),但语言为3,则这将永远不会持久化。
我知道这个常见的问题:http://en.wikibooks.org/wiki/Java_Persistence/ElementCollection#Common_Problems并且没有ID的嵌入对象会检查其字段和外键
@JoinColumns
作为ID。这在我的情况下似乎不起作用,
@JoinColumn
中的外键对于ID检查完全被忽略。这是日食线上的虫子还是我做错了什么?
编辑:
我已经设置了
-Declipselink.logging.level=FINEST
,这表明对于第二个和后面带有空标签的条目,不会执行任何sql。此外,我还制作了一个示例项目,您可以用它重现问题:
http://bit.ly/1bR8ywO
最佳答案
刚刚又测试了一下,我发现,问题出在事务管理上。我根本不想使用事务,所以我用@TransactionManagement(TransactionManagementType.BEAN)
注释了SLSB。
当我删除它时,事务由容器管理,然后更新按预期工作。
将事务管理设置为container managed并不是我希望的解决方案,但目前这是可行的。不过我还是觉得这是日食线上的一个虫子。
关于java - 当字段值相等时,@ Embeddable的@ElementCollection映射不会保留,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20990889/