我正在使用wicket和hibernate。我有两个对象category
和group
。 group
可以包含多个categorys
,而category
可以包含多个groups
。
我的问题(我很难用英语解释它): 似乎在我的列表中,我从数据库获得的是与我存储到组中的类别的大小相等的对象(而在数据库中只有一组)。
示例:
的categorys 1,2,3,4
群组测试
测试得到了类别1和2.所以在我的面板中,组测试显示两次。如果我要添加类别3,则组测试将显示三次。
这是我获取数据库数据的方式:
public List<T> getAll( Class theClass) {
List<T> entity = null;
Transaction trns = null;
Session session = sessionFactory.openSession();
try {
trns = session.beginTransaction();
entity = session.createCriteria(theClass).list();
session.getTransaction().commit();
} catch (RuntimeException e) {
e.printStackTrace();
}finally {
session.flush();
session.close();
}
return entity;
}
在我的面板中,我得到了一个像我这样的小组列表:
List<Group> groupList = new ArrayList<Group>();
groupList = groupDao.getAll(Group.class);
如果我通过我的面板调试并在groupList
中的此页面上保持,则SAME对象等于存储到该组的类别的大小。数据库内部仍然只有一行。
集团实体:
@Entity
@Table(name = "GROUP_USER")
public class Group implements Serializable{
@Id
@GeneratedValue
@Column(name = "GROUP_ID")
private int groupID;
@ManyToMany(cascade = {CascadeType.MERGE}, fetch = FetchType.EAGER)
@JoinTable(name="GROUP_TO_CATEGORY",
joinColumns={@JoinColumn(name="GROUP_ID")},
inverseJoinColumns={@JoinColumn(name="CATEGORY_ID")})
private Set<Category> categorys = new HashSet<Category>();
//constructor.. getter and setter..
}
类别实体:
@Entity
@Table(name = "CATEGORY")
public class Category implements Serializable{
@Id
@GeneratedValue
@Column(name = "CATEGORY_ID")
private int categoryId;
@ManyToMany(mappedBy="categorys", fetch = FetchType.EAGER)
private Set<Group> groups = new HashSet<Group>();
//constructor.. getter and setter..
}
答案 0 :(得分:2)
这是因为你使用了渴望的提取,无论如何这通常是一个坏主意。
如果可能的话,您应该尝试更改映射以执行延迟提取集合。这将解决这个问题,它引入的任何新问题都可以通过其他方式更好地处理,例如“在视图中打开会话”。您可以在this question中看到对此的一些讨论。
但是,如果您必须急切地进行抓取,则可以使用合并重复项的ResultTransformer更正此问题,如下所示:
public List<T> getAll( Class theClass) {
List<T> entity = null;
Transaction trns = null;
Session session = sessionFactory.openSession();
try {
trns = session.beginTransaction();
Criteria criteria = session.createCriteria(theClass);
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
entity = criteria.list();
session.getTransaction().commit();
} catch (RuntimeException e) {
e.printStackTrace();
}finally {
session.flush();
session.close();
}
return entity;
}