我正在尝试使用 @Loader 注释通过使用 hibernate 的查询来填充集合。
假设我有一个包含子菜单列表的 Menu 类。我希望使用@NamedNativeQuery 填充这些子菜单。
问题是当我将位置参数放在查询中时,我不知道如何在运行时设置它的值?
这是我的菜单类。当我获取菜单时,所有子菜单都为空。我应该在哪里设置位置参数值?你能帮忙吗?
这是我的 XML
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<sql-query name="getMenus">
<load-collection alias="menu" role="com.pmc.domain.Menu.submenus" />
select
{menu.*}
from
Menu menu
join menu_roles mr on (mr.menu_item_id=menu.menu_item_id)
join roles r on (r.user_role_id=mr.user_role_id)
join user_roles ur on (ur.user_role_id=r.user_role_id)
join users u on (u.username = ur.username)
where
menu.parent = ? and u.username=?
</sql-query>
</hibernate-mapping>
这是我的 POJO。
package com.pmc.domain;
import java.io.Serializable;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
import org.hibernate.annotations.Filter;
import org.hibernate.annotations.FilterDef;
import org.hibernate.annotations.Loader;
import org.hibernate.annotations.NamedNativeQuery;
import org.hibernate.annotations.ParamDef;
@Entity
@Table(name="menu", catalog="test")
public class Menu implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@Column(name = "menu_item_id")
private Integer menuId;
@ManyToMany(cascade={CascadeType.ALL})
@JoinTable(name="MENU_ROLES",
joinColumns={@JoinColumn(name="menu_item_id")},
inverseJoinColumns={@JoinColumn(name="user_role_id")})
private List<UserRole> userRoles;
@Column(name = "label", length = 100)
private String label;
@Column(name = "link", length = 100)
private String link;
@ManyToOne(cascade={CascadeType.ALL})
@JoinColumn(name = "parent")
private Menu parent;
@OneToMany(mappedBy="parent", fetch = FetchType.LAZY)
@Loader(namedQuery = "getMenus")
private List<Menu> submenus;
public Integer getMenuId() {
return menuId;
}
public void setMenuId(Integer menuId) {
this.menuId = menuId;
}
public List<UserRole> getUserRoles() {
return userRoles;
}
public void setUserRoles(List<UserRole> userRoles) {
this.userRoles = userRoles;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public Menu getParent() {
return parent;
}
public void setParent(Menu parent) {
this.parent = parent;
}
public List<Menu> getSubmenus() {
return submenus;
}
public void setSubmenus(List<Menu> submenus) {
this.submenus = submenus;
}
}
这是我的 DAO 方法
public List<Menu> getMenus() {
Session session = sessionFactory.openSession();
@SuppressWarnings("unchecked")
Query query = session.getNamedQuery("getMenus");
query=query.setParameter(0, 1);
query=query.setParameter(1, "jigar");
List<Menu> menuList = session.createQuery("select menu from User user, IN (user.userRole) roles, IN(roles.menus) menu where user.username = 'jigar' and menu.parent=0").list();
return menuList;
}
当我调用 getMenus 时,它返回菜单列表。但是当它们在jsp中访问时,子菜单查询会导致下面的异常
Expected positional parameter count: 2, actual parameters: [1] [select
{menu.*}
from
Menu menu
join menu_roles mr on (mr.menu_item_id=menu.menu_item_id)
join roles r on (r.user_role_id=mr.user_role_id)
join user_roles ur on (ur.user_role_id=r.user_role_id)
join users u on (u.username = ur.username)
where
menu.parent = ? and u.username=?]
at org.hibernate.internal.AbstractQueryImpl.verifyParameters(AbstractQueryImpl.java:429)
at org.hibernate.internal.SQLQueryImpl.verifyParameters(SQLQueryImpl.java:195)
at org.hibernate.internal.SQLQueryImpl.list(SQLQueryImpl.java:134)
at org.hibernate.persister.collection.NamedQueryCollectionInitializer.initialize(NamedQueryCollectionInitializer.java:73)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:693)
at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:92)
at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:1897)
at org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:558)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:260)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:554)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:142)
at org.hibernate.collection.internal.PersistentBag.iterator(PersistentBag.java:294)
at org.apache.taglibs.standard.tag.common.core.ForEachSupport.toForEachIterator(ForEachSupport.java:348)
at org.apache.taglibs.standard.tag.common.core.ForEachSupport.supportedTypeForEachIterator(ForEachSupport.java:224)
at org.apache.taglibs.standard.tag.common.core.ForEachSupport.prepare(ForEachSupport.java:155)
at javax.servlet.jsp.jstl.core.LoopTagSupport.doStartTag(LoopTagSupport.java:256)
at org.apache.jsp.WEB_002dINF.views.menu_jsp._jspx_meth_c_005fforEach_005f0(menu_jsp.java:108)
at org.apache.jsp.WEB_002dINF.views.menu_jsp._jspService(menu_jsp.java:77)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:748)
at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:604)
at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:543)
at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:954)
at org.apache.jsp.WEB_002dINF.views.menu_jsp._jspx_meth_c_005fif_005f0(menu_jsp.java:186)
at org.apache.jsp.WEB_002dINF.views.menu_jsp._jspx_meth_c_005fforEach_005f0(menu_jsp.java:122)
at org.apache.jsp.WEB_002dINF.views.menu_jsp._jspService(menu_jsp.java:77)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:748)
at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:604)
at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:543)
at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:954)
at org.apache.jsp.WEB_002dINF.views.addressList_jsp._jspService(addressList_jsp.java:137)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:748)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:486)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:411)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:338)
at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:172)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1228)
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1011)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:955)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:315)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Nov 17, 2014 10:25:39 AM org.apache.catalina.core.ApplicationDispatcher invoke
SEVERE: Servlet.service() for servlet jsp threw exception
如果我使用下面的代码
Query query = session.getNamedQuery("getMenus");
query=query.setParameter(0, 1);
query=query.setParameter(1, "jigar");
List<Menu> list = query.list();
它工作正常并返回正确的结果。
但是当我在@Loader 中传递它进行收集时,它找不到位置参数。但是,如果我使用单个位置参数,即?然后它也可以在那里工作,因为子菜单是由父级映射的,并且它将父级值作为位置参数。但对于进一步的位置参数,它不起作用。
最佳答案
从 更改您的代码
@Entity
@NamedNativeQuery(
name="submenus",
query="select * from menu where parent = ? ",
resultClass=Menu.class)
@Table(name="menu", catalog="test")
public class Menu implements Serializable{
到
@NamedNativeQueries({@NamedNativeQuery(
name="submenus",
query="select * from menu where parent = :parentName and menu_item_id = :menuItemId",
resultClass=Menu.class)
})
@Entity
@Table(name="menu", catalog="test")
public class Menu implements Serializable{
从 中删除 @Loader 注释
@OneToMany(mappedBy="parent",fetch = FetchType.LAZY)
@Loader(namedQuery = "submenus")
private List<Menu> submenus;
并将其作为 放在 Menu 类的顶部
@NamedNativeQueries({@NamedNativeQuery(
name="submenus",
query="select * from menu where parent = :parentName and menu_item_id = :menuItemId",
resultClass=Menu.class)
})
@Loader(namedQuery = "submenus")
@Entity
@Table(name="menu", catalog="test")
public class Menu implements Serializable{
Bcoz @Loader 注解仅适用于 Class & Collections,不适用于 @OneToMany 等关联。
将您命名的 native 查询称为
Query query = session.getNamedQuery("submenus");
query.setParameter("parentName", "Whatever u want");
query.setParameter("menuItemId", "Whatever u want");
//or
//if ur query is like this
//select * from menu where parent = ? and menu_item_id = ?
query.setParameter(1, "Whatever u want");
query.setParameter(2, "Whatever u want");
也看看
我希望它能帮助你。
关于java - 如何在 hibernate 中使用带有位置参数的@Loader?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26881128/