我使用Spring Security和Hibernate实现了基本的用户管理。
以下是包含关系的实体(UserEntity
,RoleEntity
,PermissionEntity
,UserRoleEntity
和UserPermissionEntity
):
UserEntity:
@Entity
@Table(name = "tb_user")
@NamedQuery(name = "User.findById", query = "SELECT u FROM UserEntity u WHERE u.idUser = :userId")
@NamedEntityGraph(
name = "graph.userRoles.role",
attributeNodes = {
@NamedAttributeNode(value = "userRoles", subgraph = "userRolesGraph"),
@NamedAttributeNode(value = "userPermissions", subgraph = "userPermissionsGraph")
},
subgraphs = {
@NamedSubgraph(name = "userRolesGraph", attributeNodes = @NamedAttributeNode("role")),
@NamedSubgraph(name = "userPermissionsGraph", attributeNodes = @NamedAttributeNode("permission"))
}
)
public class UserEntity implements Serializable
{
[...]
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
private Set<UserRoleEntity> userRoles;
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
private Set<UserPermissionEntity> userPermissions;
[...]
}
UserRoleEntity:
@Entity
public class UserRoleEntity implements Serializable
{
[...]
@JoinColumn(name = "id_role", referencedColumnName = "id_role")
@ManyToOne(fetch = FetchType.LAZY)
private RoleEntity role;
@JoinColumn(name = "id_user", referencedColumnName = "id_user")
@ManyToOne(fetch = FetchType.LAZY)
private UserEntity user;
[...]
}
UserPermissionEntity:
@Entity
public class UserPermissionEntity implements Serializable
{
[...]
@JoinColumn(name = "id_user", referencedColumnName = "id_user")
@ManyToOne(fetch = FetchType.LAZY)
private UserEntity user;
@JoinColumn(name = "id_permission", referencedColumnName = "id_permission")
@ManyToOne(fetch = FetchType.LAZY)
private PermissionEntity permission;
[...]
}
我只想获得一个特定的UserEntity及其ID和fetch:
这是Dao方法:
@Override
@Transactional(readOnly = true)
public UserEntity getUserByIdGraph(Integer userId)
{
TypedQuery<UserEntity> query = this.entityManager.createNamedQuery("User.findById", UserEntity.class);
query.setParameter("userId", userId);
query.setHint("javax.persistence.fetchgraph",
this.entityManager.getEntityGraph("graph.userRoles.role"));
UserEntity userEntity = query.getSingleResult(); //Fails here
return (userEntity);
}
问题是我有以下错误:
Etat HTTP 500 - Request processing failed; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'left outer join tb_permission_user userpermis3_ on userentity0_.id_user=userperm' at line 1
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
java.lang.reflect.Constructor.newInstance(Constructor.java:408)
com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
com.mysql.jdbc.Util.getInstance(Util.java:381)
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1030)
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3491)
com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3423)
com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1936)
com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2060)
com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2542)
com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1734)
com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1885)
org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:80)
org.hibernate.loader.Loader.getResultSet(Loader.java:2065)
org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1862)
org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1838)
org.hibernate.loader.Loader.doQuery(Loader.java:909)
org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:354)
org.hibernate.loader.Loader.doList(Loader.java:2553)
org.hibernate.loader.Loader.doList(Loader.java:2539)
org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2369)
org.hibernate.loader.Loader.list(Loader.java:2364)
org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:496)
org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:387)
org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:231)
org.hibernate.internal.SessionImpl.list(SessionImpl.java:1264)
org.hibernate.internal.QueryImpl.list(QueryImpl.java:103)
org.hibernate.jpa.internal.QueryImpl.list(QueryImpl.java:573)
org.hibernate.jpa.internal.QueryImpl.getSingleResult(QueryImpl.java:495)
org.hibernate.jpa.criteria.compile.CriteriaQueryTypeQueryAdapter.getSingleResult(CriteriaQueryTypeQueryAdapter.java:71)
com.az.metal.dao.impl.UserDaoImpl.getUserByIdGraph(UserDaoImpl.java:110)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:483)
org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
com.sun.proxy.$Proxy576.getUserByIdGraph(Unknown Source)
com.az.metal.service.impl.UserServiceImpl.getUserByIdGraph(UserServiceImpl.java:212)
com.az.metal.controller.UserController.view(UserController.java:77)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:483)
org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:111)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:806)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:729)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.sitemesh.webapp.contentfilter.ContentBufferingFilter.bufferAndPostProcess(ContentBufferingFilter.java:169)
org.sitemesh.webapp.contentfilter.ContentBufferingFilter.doFilter(ContentBufferingFilter.java:126)
org.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:120)
org.sitemesh.config.ConfigurableSiteMeshFilter.doFilter(ConfigurableSiteMeshFilter.java:163)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
我不明白发生了什么,因为如果我分别只提取userRoles.role
或userPermissions.permission
,那就有效了。但是这两个子图一起失败(使用javax.persistence.loadgraph
时也是如此)!
我真的迷路了。
PS:我尝试使用注释@EntityGraph使用attributePaths
,但NetBeans无法识别它!你知道正确的Maven包使用@EntityGraph注释吗?
非常感谢你的帮助!
答案 0 :(得分:0)
我知道这不会直接解决您的问题,但我觉得我应该将其作为应用程序设计说明。您似乎使用实体来描述用户&lt; - &gt;角色(UserRoleEntity)和用户&lt; - &gt;权限(UserPermissionEntity)之间的实体关系。您是否考虑过使用@JoinTables来简化这些映射?
示例:
@Entity
public class UserEntity implements Serializable {
@OneToMany
@JoinTable(name="USER_ROLE",
joinColumns= @JoinColumn(name="USER_ID"),
inverseJoinColumns= @JoinColumn(name="ROLE_ID"))
private Set<RoleEntity> userRoles;
@OneToMany
@JoinTable(name="USER_PERM",
joinColumns= @JoinColumn(name="USER_ID"),
inverseJoinColumns= @JoinColumn(name="PERM_ID"))
private Set<PermissionEntity> userPermissions;
}
@Entity
public class RoleEntity {
@ManyToOne
@JoinTable(name = "USER_ROLE",
joinColumns = @JoinColumn(name = "ROLE_ID"),
inverseJoinColumns = @JoinColumn(name = "USER_ID"))
private UserEntity user;
}
@Entity
public class PermissionEntity {
@ManyToOne
@JoinTable(name = "USER_PERM",
joinColumns = @JoinColumn(name = "PERM_ID"),
inverseJoinColumns = @JoinColumn(name = "USER_ID"))
private UserEntity user;
}