Rac*_*hel 41 java annotations hibernate
我有一个名为SynonymMapping的类,它有一组映射为CollectionOfElements的值
@Entity(name = "synonymmapping")
public class SynonymMapping {
@Id private String keyId;
//@CollectionOfElements(fetch = FetchType.EAGER)
@CollectionOfElements
@JoinTable(name="synonymmappingvalues", joinColumns={@JoinColumn(name="keyId")})
@Column(name="value", nullable=false)
@Sort(type=SortType.NATURAL)
private SortedSet<String> values;
public SynonymMapping() {
values = new TreeSet<String>();
}
public SynonymMapping(String key, SortedSet<String> values) {
this();
this.keyId = key;
this.values = values;
}
public String getKeyId() {
return keyId;
}
public Set<String> getValues() {
return values;
}
}
Run Code Online (Sandbox Code Playgroud)
我有一个测试,我将两个SynonymMapping对象存储到数据库,然后要求数据库返回所有保存的SynonymMapping对象,期望接收我存储的两个对象.
当我将值的映射更改为急切(如注释行中的代码所示)并再次运行测试时,我会收到四个匹配项.
我已经清除了运行之间的数据库,我可以复制这个问题在eager和lazy之间交换.
我认为它与hibernate在下面创建的连接有关但我无法在网上找到明确的答案.
任何人都可以告诉我为什么急切的提取是复制对象?
谢谢.
小智 69
我遇到了同样的问题 - 当你为@CollectionOfElements设置FetchType.EAGER时,Hibernate尝试一次性获取所有内容,即对链接到"master"对象的元素的每个条目使用一个单独的查询.如果将@Fetch(FetchMode.SELECT)注释添加到集合中,则可以以N + 1查询为代价成功解决此问题.在我的情况下,我希望有一个MediaObject实体,其中包含其元数据项(视频编解码器,音频编解码器,大小等)的集合.metadataItems集合的映射如下所示:
@CollectionOfElements (targetElement = String.class, fetch = FetchType.EAGER) @JoinTable(name = "mo_metadata_item", joinColumns = @JoinColumn(name = "media_object_id")) @MapKey(columns = @Column(name = "name")) @Column (name = "value") @Fetch (FetchMode.SELECT) private Map<String, String> metadataItems = new HashMap<String, String>();
Chs*_*y76 29
在映射中强制执行急切提取通常不是一个好主意 - 最好在适当的查询中指定热切联接(除非您100%确定在任何情况下,如果没有该集合,您的对象将无法理解/有效正在填充).
你得到重复的原因是因为Hibernate内部加入你的根和集合表.请注意,它们确实是重复的,例如,对于具有3个集合元素的2个SynonymMappings,每个将获得6个结果(2x3),每个SynonymMapping实体3个副本.因此,最简单的解决方法是将结果包装在Set中,从而确保它们是唯一的.
我遇到了这个问题,我用它来解决它
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
这样可以清除由子表连接引起的重复项.