我有3个表:1.moduls with atribue id,2.variant with attribute id and 3.moduls_variant with attributes moduls_id,variant_id。
我把这些表映射成两个类:
Moduls
@Entity
@Table (name = "moduls")
public class Moduls
{
@Id
@GeneratedValue (strategy = GenerationType.IDENTITY)
@Column (name = "id")...
}
变体
@Table(name = "variant")
@Entity
public class Variant{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column (name = "id", unique = true)
private Integer id;
@ManyToMany(fetch = FetchType.EAGER,cascade = CascadeType.ALL)
@JoinTable(name = "moduls_variant",
joinColumns = @JoinColumn(name = "variant_id") ,
inverseJoinColumns = @JoinColumn(name = "moduls_id") )
private Set<Moduls> modulsSet = new HashSet<Moduls>();...
}
我的问题就出现了。 让我们说我得到表模块项ID为1,2和3。 在表变体项中,标识为1。 最后在表moduls_variant 3行:
1 | 1
1 | 2
1 | 3
问题是,现在当我想通过使用以下方法从表变体中获取所有项目(我应该只获得1项)时
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Variant.class);
getHibernateTemplate().findByCriteria(detachedCriteria);
我从表变体中获得相同对象的三倍(具有相同的ID)
答案 0 :(得分:4)
这是因为您设置@ManyToMany
与FetchType.EAGER
的关联,后者返回笛卡尔结果。
您可以删除急切的提取以回退到默认的延迟初始化,也可以添加以下转换器:
detachedCriteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
答案 1 :(得分:3)
我知道这是一个旧帖子,但它出现在我的搜索中,所以这里是Julien接受的答案的替代解决方案。您可以保留EAGER fetch,只需添加此@Fetch(FetchMode.SUBSELECT)注释即可绕过笛卡尔结果。显然会有性能影响所以在你使用它时要小心。