我在将元素插入由映射表示的@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/

10-16 17:38