我正在分析我的应用程序的性能,我注意到以下内容。我有这个查询:
public List<Rol> findAll() {
return mySessionFactory.getCurrentSession().createQuery("from Rol").list();
}
这将返回此查询:
SELECT rol0_._id as column1_2_, rol0_.description as descripc2_2_, rol0_.name as nombre6_2_, rol0_.status as status7_2_ FROM rol rol0_
这很好,但在我的jsp中我有以下内容:
<form:select multiple="true" path="roles" required="true">
<form:options items="${roles}" itemValue="id" itemLabel="nombre" />
</form:select>
这会为每个角色创建一个新查询:
DEBUG: org.hibernate.SQL - select rol0_._id as column1_2_0_, rol0_.description as descripc2_2_0_, rol0_.name as name6_2_0_, rol0_.status as status7_2_0_ from rol rol0_ where rol0_._id=?
TRACE: org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [1] as [VARCHAR] - 1
DEBUG: org.hibernate.SQL - select rol0_._id as column1_2_0_, rol0_.description as descripc2_2_0_, rol0_.name as name6_2_0_, rol0_.status as status7_2_0_ from rol rol0_ where rol0_._id=?
TRACE: org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [1] as [VARCHAR] - 2
DEBUG: org.hibernate.SQL - select rol0_._id as column1_2_0_, rol0_.description as descripc2_2_0_, rol0_.name as name_2_0_, rol0_.status as status7_2_0_ from rol rol0_ where rol0_._id=?
TRACE: org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [1] as [VARCHAR] - 20130915150706256
DEBUG: org.hibernate.SQL - select rol0_._id as column1_2_0_, rol0_.description as descripc2_2_0_, rol0_.name as name6_2_0_, rol0_.status as status7_2_0_ from rol rol0_ where rol0_._id=?
TRACE: org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [1] as [VARCHAR] - 3
在我的控制器中,我有:
List<Rol> roles = rolDao.findAll();
ModelAndView mav = new ModelAndView("usuarioNew");
mav.getModelMap().put("roles", roles);
有什么办法可以避免这种情况吗?第一个查询包含我需要的所有信息,我不想要额外的查询。
编辑:
@Entity
@Table(name = "rol", uniqueConstraints = { @UniqueConstraint(columnNames = "name") })
public class Rol implements Serializable{
@Id
@Column(name = "_id")
private String id;
@Column(name = "name")
@NotEmpty
private String name;
@Column(name = "description")
private String description;
@Column(name = "status")
private String status;
@NotEmpty
@Fetch(FetchMode.JOIN)
@OneToMany(mappedBy = "rolPermission_pk.rol", orphanRemoval = true, cascade=CascadeType.ALL)
private Set<Rol_Permission> permissions = new HashSet<Rol_Permission>(0);
....//getters, setters
}
编辑2:
public class UserRolCollectionEditor extends CustomCollectionEditor {
private final RolDAO rolDao;
public UserRolCollectionEditor (Class<?> collectionType, RolDAO rolDao) {
super(collectionType);
this.rolDao = rolDao;
}
@Override
protected Object convertElement(Object element) {
String rolId = (String) element;
Rol rol = rolDao.findById(rolId);
User_Rol usuRol = new User_Rol();
User user = new User();
usuRol.setUser(user);
usuRol.setRol(rol);
usuRol.setStatus("active");
return usuRol;
}
}
编辑3:
我做了一些测试,问题出在 UserRolCollectionEditor 和 @Fetch(FetchMode.JOIN) 上。如果我从代码中删除 UserRolCollectionEditor 和 @Fetch(FetchMode.JOIN),我会得到一个查询。如果只删除 @Fetch(FetchMode.JOIN) 我会得到额外的查询。如果仅删除 UserRolCollectionEditor 我会收到额外的查询..我不知道该怎么做..