JPA + Spring 4 + Hibernate 4:用户缺少权限或找不到对象:USER_GROUP

Posted

技术标签:

【中文标题】JPA + Spring 4 + Hibernate 4:用户缺少权限或找不到对象:USER_GROUP【英文标题】:JPA + Spring 4 + Hibernate 4 : user lacks privilege or object not found : USER_GROUP 【发布时间】:2014-04-30 06:27:48 【问题描述】:

我在 junit 下运行测试时遇到了一些麻烦。我收到此错误:

29/04/2014 22:39:43 INFO  Version - HHH000412: Hibernate Core 4.3.5.Final
...
29/04/2014 22:39:44 INFO  SchemaValidator - HHH000229: Running schema validator
29/04/2014 22:39:44 INFO  SchemaValidator - HHH000102: Fetching database metadata
29/04/2014 22:39:44 INFO  TableMetadata - HHH000261: Table found: PUBLIC.SECURITY.GROUP_USER
29/04/2014 22:39:44 INFO  TableMetadata - HHH000037: Columns: [usr_id, grp_id]
29/04/2014 22:39:44 INFO  TableMetadata - HHH000261: Table found: PUBLIC.SECURITY.GROUP
29/04/2014 22:39:44 INFO  TableMetadata - HHH000037: Columns: [grp_name, grp_id]
29/04/2014 22:39:44 INFO  TableMetadata - HHH000261: Table found: PUBLIC.SECURITY.USER
29/04/2014 22:39:44 INFO  TableMetadata - HHH000037: Columns: [usr_firstname, usr_id, usr_lastname, usr_expiration, usr_email, usr_modification, usr_login, usr_password, usr_creation, usr_enabled]
29/04/2014 22:39:45 INFO  ResourceDatabasePopulator - Executing SQL script from class path resource [database/populate-security-data.sql]
29/04/2014 22:39:45 INFO  ResourceDatabasePopulator - Done executing SQL script from class path resource [database/populate-security-data.sql] in 11 ms.
29/04/2014 22:39:45 INFO  TransactionalTestExecutionListener - Began transaction (1) for test context [DefaultTestContext@7c748639 testClass = SecurityTest, testInstance = SMP.pub.example.SecurityTest@46184804, testMethod = permissionTest@SecurityTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@6420228f testClass = SecurityTest, locations = 'classpath:spring/test-context.xml', classes = '', contextInitializerClasses = '[]', activeProfiles = '', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]; transaction manager [org.springframework.orm.jpa.JpaTransactionManager@79bd0da3]; rollback [true]
29/04/2014 22:39:45 DEBUG SqlStatementLogger - select SPuser0_.usr_id as usr_id1_7_0_, SPuser0_.usr_creation as usr_crea2_7_0_, SPuser0_.usr_email as usr_emai3_7_0_, SPuser0_.usr_enabled as usr_enab4_7_0_, SPuser0_.usr_expiration as usr_expi5_7_0_, SPuser0_.usr_firstname as usr_firs6_7_0_, SPuser0_.usr_lastname as usr_last7_7_0_, SPuser0_.usr_modification as usr_modi8_7_0_, SPuser0_.usr_password as usr_pass9_7_0_, SPuser0_.usr_login as usr_log10_7_0_ from security.user SPuser0_ where SPuser0_.usr_id=?
29/04/2014 22:39:45 TRACE BasicBinder - binding parameter [1] as [BIGINT] - [1]
29/04/2014 22:39:45 TRACE BasicExtractor - extracted value ([usr_crea2_7_0_] : [TIMESTAMP]) - [2014-04-29 22:39:45.323]
29/04/2014 22:39:45 TRACE BasicExtractor - extracted value ([usr_emai3_7_0_] : [VARCHAR]) - [commercial.63-1@sample.com]
29/04/2014 22:39:45 TRACE BasicExtractor - extracted value ([usr_enab4_7_0_] : [BOOLEAN]) - [true]
29/04/2014 22:39:45 TRACE BasicExtractor - extracted value ([usr_expi5_7_0_] : [TIMESTAMP]) - [2015-04-03 09:48:52.0]
29/04/2014 22:39:45 TRACE BasicExtractor - extracted value ([usr_firs6_7_0_] : [VARCHAR]) - [commercial]
29/04/2014 22:39:45 TRACE BasicExtractor - extracted value ([usr_last7_7_0_] : [VARCHAR]) - [63-1]
29/04/2014 22:39:45 TRACE BasicExtractor - extracted value ([usr_modi8_7_0_] : [TIMESTAMP]) - [2014-04-29 22:39:45.323]
29/04/2014 22:39:45 TRACE BasicExtractor - extracted value ([usr_pass9_7_0_] : [VARCHAR]) - []
29/04/2014 22:39:45 TRACE BasicExtractor - extracted value ([usr_log10_7_0_] : [VARCHAR]) - [commercial.63-1]
29/04/2014 22:39:45 TRACE CollectionType - Created collection wrapper: [com.sample.security.metier.impl.SPUser.groups#1]
...
29/04/2014 22:39:45 DEBUG SqlStatementLogger - select SPgroup0_.grp_id as grp_id1_2_0_, SPgroup0_.grp_name as grp_name2_2_0_ from security.group SPgroup0_ where SPgroup0_.grp_id=?
29/04/2014 22:39:45 TRACE BasicBinder - binding parameter [1] as [BIGINT] - [4]
29/04/2014 22:39:45 TRACE BasicExtractor - extracted value ([grp_name2_2_0_] : [VARCHAR]) - [Commercial 63]
29/04/2014 22:39:45 TRACE CollectionType - Created collection wrapper: [com.sample.security.metier.impl.SPGroup.childGroups#4]
29/04/2014 22:39:45 TRACE CollectionType - Created collection wrapper: [com.sample.security.metier.impl.SPGroup.parentGroups#4]
29/04/2014 22:39:45 TRACE CollectionType - Created collection wrapper: [com.sample.security.metier.impl.SPGroup.permissionTags#4]
29/04/2014 22:39:45 TRACE CollectionType - Created collection wrapper: [com.sample.security.metier.impl.SPGroup.roleTags#4]
29/04/2014 22:39:45 TRACE CollectionType - Created collection wrapper: [com.sample.security.metier.impl.SPGroup.users#4]
...
29/04/2014 07:46:50 DEBUG SqlStatementLogger - select groups0_.usr_id as usr_id2_7_0_, groups0_.grp_id as grp_id1_1_0_, SPgroup1_.grp_id as grp_id1_2_1_, SPgroup1_.grp_name as grp_name2_2_1_ from group_user groups0_ inner join security.group SPgroup1_ on groups0_.grp_id=SPgroup1_.grp_id where groups0_.usr_id=?
30/04/2014 07:46:50 WARN  SqlExceptionHelper - SQL Error: -5501, SQLState: 42501
** 30/04/2014 07:46:50 ERROR SqlExceptionHelper - user lacks privilege or object not found: GROUP_USER **

这是发生错误的代码部分:

public Set<Role> getRoles() 
    Set<Role> roles = new HashSet<Role>();
    List<SPGroup> localGroups = getGroups();
    if (localGroups != null) 
        ** for (SPGroup group : localGroups)  **
            roles.addAll(group.getRoles());
        
    
    return roles;

getGroups 函数运行良好,但在 localGroups 上的迭代会引发此错误。

这是我的代码和配置:

SPUser 实体

@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(name="user", schema="security")
public class SPUser implements User 

    private static final long serialVersionUID = 6335411953406117295L;

    @Id
    @GeneratedValue
    @Column(name = "usr_id", unique = true, nullable = false)
    private Long id;

    @Column(name = "usr_password", nullable = false, length=100)
    private String password;
    @Column(name = "usr_login", unique=true, nullable = false, length=128)
    private String username;
    @Column(name = "usr_enabled", nullable = false)
    private boolean enabled;
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "usr_expiration")
    private Date expirationDate;

    @Column(name = "usr_firstname", length=50)
    private String firstname;
    @Column(name = "usr_lastname", length=50)
    private String lastname;
    @Column(name = "usr_email", unique=true, length=128)
    private String email;

    @CreatedDate
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "usr_creation")
    private Date creationDate;

    @LastModifiedDate
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "usr_modification")
    private Date modificationDate;

    @ManyToMany(fetch = FetchType.LAZY, mappedBy = "users")
    private List<SPGroup> groups;

    ...

    public Long getId() 
        return id;
    

    public void setId(Long id) 
        this.id = id;
    

    @Override
    public String getPassword() 
        return this.password;
    

    public void setPassword(String password) 
        this.password = password;
    

    @Override
    public String getUsername() 
        return this.username;
    

    public void setUsername(String username) 
        this.username = username;
    

    @Override
    public boolean isEnabled() 
        return this.enabled;
    

    public void setEnabled(boolean enabled) 
        this.enabled = enabled;
    

    public Date getExpirationDate() 
        return expirationDate;
    

    public void setExpirationDate(Date expirationDate) 
        this.expirationDate = expirationDate;
    

    @Override
    public String getFirstname() 
        return firstname;
    

    public void setFirstname(String firstname) 
        this.firstname = firstname;
    

    @Override
    public String getLastname() 
        return lastname;
    

    public void setLastname(String lastname) 
        this.lastname = lastname;
    

    @Override
    public String getEmail() 
        return email;
    

    public void setEmail(String email) 
        this.email = email;
    

    public Date getCreationDate() 
        return creationDate;
    

    public void setCreationDate(Date creationDate) 
        this.creationDate = creationDate;
    

    public Date getModificationDate() 
        return modificationDate;
    

    public void setModificationDate(Date modificationDate) 
        this.modificationDate = modificationDate;
    

    @Override
    public List<SPGroup> getGroups() 
        return groups;
    

    public void setGroups(List<SPGroup> groups) 
        this.groups = groups;
    

    public Set<Role> getRoles() 
        Set<Role> roles = new HashSet<Role>();
        List<SPGroup> localGroups = getGroups();
        if (localGroups != null) 
            for (SPGroup group : localGroups) 
                roles.addAll(group.getRoles());
            
        
        return roles;
    

    @Override
    public Map<SPPermission, SPPerimeter> getPermissions() 
        return SPGroup.mergePermissionsFromGroups(getGroups());
    

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() 
        return getRoles();
    

    @Override
    public boolean isAccountNonExpired() 
        if (getExpirationDate() == null) 
            return true;
         else 
            return Calendar.getInstance().getTime().before(getExpirationDate());
        
    

    @Override
    public boolean isAccountNonLocked() 
        // TODO Auto-generated method stub
        return true;
    

    @Override
    public boolean isCredentialsNonExpired() 
        // TODO Auto-generated method stub
        return true;
    

    ...


SPGroup 实体

@Entity
@Table(name="group", schema="security")
public class SPGroup implements Group 

    @Id
    @GeneratedValue
    @Column(name = "grp_id", unique = true, nullable = false)
    private Long id;

    @Column(name = "grp_name", unique = true, nullable = false, length=150)
    private String name;

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable(name = "group_user", joinColumns =  
            @JoinColumn(name = "grp_id", nullable = false, updatable = false) , 
            inverseJoinColumns =  @JoinColumn(name = "usr_id", 
                    nullable = false, updatable = false) )
    private List<SPUser> users = new ArrayList<SPUser>();

    @ManyToMany(fetch = FetchType.LAZY, mappedBy = "childGroups")
    private List<SPGroup> parentGroups = new ArrayList<SPGroup>();
    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable(name = "group_group", joinColumns =  
            @JoinColumn(name = "parent_id", nullable = false, updatable = false, referencedColumnName="grp_id") , 
            inverseJoinColumns =  @JoinColumn(name = "child_id", 
                    nullable = false, updatable = false, referencedColumnName="grp_id") )
    private List<SPGroup> childGroups = new ArrayList<SPGroup>();

    @OneToMany(fetch = FetchType.LAZY, targetEntity=RoleTag.class ,mappedBy = "group", cascade=CascadeType.ALL)
    private List<RoleTag> roleTags = new ArrayList<RoleTag>();
    @OneToMany(fetch = FetchType.LAZY, targetEntity=PermissionTag.class, mappedBy = "group", cascade=CascadeType.ALL)
    private List<PermissionTag> permissionTags = new ArrayList<PermissionTag>();

    ...

    public Long getId() 
        return id;
    

    public void setId(Long id) 
        this.id = id;
    

    @Override
    public String getName() 
        return name;
    

    public void setName(String name) 
        this.name = name;
    

    public List<SPUser> getUsers() 
        return users;
    

    public void setUsers(List<SPUser> users) 
        this.users = users;
    

    public void addUser(SPUser user) 
        if (user.getGroups() == null) 
            user.setGroups(new ArrayList<SPGroup>());
        
        if (!user.getGroups().contains(this)) 
            user.getGroups().add(this);
        
        getUsers().add(user);
    

    public List<SPGroup> getParentGroups() 
        return parentGroups;
    

    public void setParentGroups(List<SPGroup> parentGroups) 
        this.parentGroups = parentGroups;
    

    public List<SPGroup> getChildGroups() 
        return childGroups;
    

    public void setChildGroups(List<SPGroup> childGroups) 
        this.childGroups = childGroups;
    

    public List<RoleTag> getRoleTags() 
        return roleTags;
    

    public void setRoleTags(List<RoleTag> roleTags) 
        this.roleTags = roleTags;
    

    public List<PermissionTag> getPermissionTags() 
        return permissionTags;
    

    public void setPermissionTags(List<PermissionTag> permissionTags) 
        this.permissionTags = permissionTags;
    

    public void addPermissionTag(PermissionTag permissionTag) 
        permissionTag.setGroup(this);
        getPermissionTags().add(permissionTag);
    

    @Override
    public List<SPUser> getAllUsers() 
        List<SPUser> allUsers = new ArrayList<SPUser>(getUsers());
        for (SPGroup childGroup : getAllChildGroups()) 
            for (SPUser user : childGroup.getUsers()) 
                if (!allUsers.contains(user)) 
                    allUsers.add(user);
                
            
        
        return allUsers;
    

    @Override
    public List<SPGroup> getAllParentGroups() 
        return getAllParentGroups(new HashSet<SPGroup>(Arrays.asList(this)));
    

    private List<SPGroup> getAllParentGroups(Set<SPGroup> ignoreSet) 
        List<SPGroup> allparentGroups = new ArrayList<SPGroup>();
        for (SPGroup parent : getParentGroups()) 
            if (!ignoreSet.contains(parent)) 
                ignoreSet.add(parent);
                allparentGroups.add(parent);
                allparentGroups.addAll(parent.getAllParentGroups(ignoreSet));
            
        
        return allparentGroups;
    

    @Override
    public List<SPGroup> getAllChildGroups() 
        return getAllChildGroups(new HashSet<SPGroup>(Arrays.asList(this)));
    

    private List<SPGroup> getAllChildGroups(Set<SPGroup> ignoreSet) 
        List<SPGroup> allChildrenGroups = new ArrayList<SPGroup>();
        for (SPGroup child : getChildGroups()) 
            if (!ignoreSet.contains(child)) 
                ignoreSet.add(child);
                allChildrenGroups.add(child);
                allChildrenGroups.addAll(child.getAllChildGroups(ignoreSet));
            
        
        return allChildrenGroups;
    

    @Override
    public Set<Role> getRoles() 
        return getRoles(true);
    

    private Set<Role> getRoles(boolean merged) 
        if (merged) 
            return getActiveRoles(getMergedRoleMap());
         else 
            return getActiveRoles(getRoleMap());

        
    

    private Map<Role, Boolean> getRoleMap() 
        Map<Role, Boolean> roleMap = new HashMap<Role, Boolean>();
        for (RoleTag roleTag : getRoleTags()) 
            roleMap.put(roleTag.getRole(), roleTag.isGranting());
        
        return roleMap;
    

    private Map<Role, Boolean> getParentsRoleMap() 
        return mergeRolesFromGroups(getParentGroups());
    

    private Map<Role, Boolean> getMergedRoleMap() 
        Map<Role, Boolean> roleMap = getRoleMap();
        for (Entry<Role, Boolean> mergedEntry : getParentsRoleMap().entrySet()) 
            // the roleMap override all the parents directives
            if (!roleMap.containsKey(mergedEntry.getKey())) 
                roleMap.put(mergedEntry.getKey(), mergedEntry.getValue());
            
        
        return roleMap;
    

    private static Map<Role, Boolean> mergeRolesFromGroups(List<SPGroup> groups) 
        Map<Role, Boolean> mergedRoleMap = new HashMap<Role, Boolean>();
        // merge of the parents' role
        for (SPGroup group : groups) 
            for (Entry<Role, Boolean> roleMapEntry : group.getMergedRoleMap().entrySet()) 
                if (mergedRoleMap.containsKey(roleMapEntry.getKey())) 
                    // We apply a OR operation between the parents' role
                    if (roleMapEntry.getValue() && !mergedRoleMap.get(roleMapEntry.getKey())) 
                        mergedRoleMap.put(roleMapEntry.getKey(), roleMapEntry.getValue());
                    
                 else 
                    mergedRoleMap.put(roleMapEntry.getKey(), roleMapEntry.getValue());
                
            
        
        return mergedRoleMap;
    

    private static Set<Role> getActiveRoles(Map<Role, Boolean> roleMap) 
        Set<Role> roles = new HashSet<Role>();
        for (Entry<Role, Boolean> mapEntry : roleMap.entrySet()) 
            if (mapEntry.getValue()) 
                roles.add(mapEntry.getKey());
            
        
        return roles;
    

    private Map<SPPermission, SPPerimeter> getPermissionMap() 
        Map<SPPermission, SPPerimeter> permissionMap = new HashMap<SPPermission, SPPerimeter>();
        for (PermissionTag permissionTag : getPermissionTags()) 
            if (!permissionMap.containsKey(permissionTag.getPermission())) 
                permissionMap.put(permissionTag.getPermission(), new SPPerimeter());
            
            permissionMap.get(permissionTag.getPermission()).add(permissionTag);
        
        return permissionMap;
    

    private Map<SPPermission, SPPerimeter> getParentsPermissionMap() 
        return mergePermissionsFromGroups(getParentGroups());
    

    public Map<SPPermission, SPPerimeter> getMergedPermissionMap() 
        Map<SPPermission, SPPerimeter> permissionMap = getPermissionMap();
        for (Entry<SPPermission, SPPerimeter> entry : getParentsPermissionMap().entrySet()) 
            if (permissionMap.containsKey(entry.getKey())) 
                permissionMap.get(entry.getKey()).merge(entry.getValue());
             else 
                permissionMap.put(entry.getKey(), entry.getValue());
            
        
        return permissionMap;
    

    public static Map<SPPermission, SPPerimeter> mergePermissionsFromGroups(List<SPGroup> groups) 
        Map<SPPermission, SPPerimeter> permissionMap = new HashMap<SPPermission, SPPerimeter>();
        for (SPGroup group : groups) 
            for (Entry<SPPermission, SPPerimeter> entry : group.getMergedPermissionMap().entrySet()) 
                if (permissionMap.containsKey(entry.getKey())) 
                    permissionMap.get(entry.getKey()).add(entry.getValue());
                 else 
                    permissionMap.put(entry.getKey(), entry.getValue());
                
            
        
        return permissionMap;
    

    @Override
    public Map<SPPermission, SPPerimeter> getPermissions() 
        return getMergedPermissionMap();
    

    @Override
    public String toString() 
        return getName() + "[" + getId() + "]";
    

    @Override
    public void setRole(GrantedAuthority role, boolean granting) 
        if (role instanceof Role) 
            setRole((Role) role, granting);
         else 
            setRole(new Role(role.getAuthority()), granting);
        

    

    @Override
    public void setPermission(Permission permission, Perimeter perimeter) 
        if (permission instanceof SPPermission) 
            setPermission((SPPermission) permission, perimeter);
         else 
            setPermission(new SPPermission(permission.getObjectType(), permission.getAction()), perimeter);
        
    

    private void setRole(Role role, boolean granting) 
        Map<Role, Boolean> roleMap = getMergedRoleMap();
        if (granting) 
            if (!roleMap.containsKey(role)) 
                // Role not defined
                getRoleTags().add(new RoleTag(role, true));
             else if (!roleMap.get(role)) 
                // Role explicitly forbidden
                Iterator<RoleTag> iterator = getRoleTags().iterator();
                while (iterator.hasNext()) 
                    RoleTag current = iterator.next();
                    if (current.getRole().equals(role)) 
                        iterator.remove();
                    
                
                getRoleTags().add(new RoleTag(role, true));
            
         else 
            if (roleMap.containsKey(role) && roleMap.get(role)) 
                // Role present
                Iterator<RoleTag> iterator = getRoleTags().iterator();
                boolean removed = false;
                while (iterator.hasNext()) 
                    RoleTag current = iterator.next();
                    if (current.getRole().equals(role)) 
                        iterator.remove();
                        removed = true;
                    
                
                if (removed) 
                    // Role was present locally, check inheritance again
                    roleMap = getMergedRoleMap();
                    if (roleMap.containsKey(role) && roleMap.get(role)) 
                        // Role still present, explicit remove
                        getRoleTags().add(new RoleTag(role, false));
                    
                 else 
                    // Role was not present locally, explicit remove
                    getRoleTags().add(new RoleTag(role, false));
                
            
        
    

    private boolean clearLocalPermission(SPPermission permission) 
        Iterator<PermissionTag> iterator = getPermissionTags().iterator();
        boolean modified = false;
        while (iterator.hasNext()) 
            PermissionTag permissionTag = iterator.next();
            if (permissionTag.getPermission().equals(permission)) 
                iterator.remove();
                modified = true;
            
        
        return modified;
    

    private void addLimitedPermisisonTags(SPPermission permission, Perimeter perimeter, Perimeter inheritedPerimeter) throws IllegalArgumentException 
        boolean isInherited = inheritedPerimeter != null;
        if (perimeter.isMyAllowed()) 
            if (!isInherited || !inheritedPerimeter.isMyAllowed()) 
                addPermissionTag(new PermissionTag(permission, Type.MY));
            
        
        for (Group group : perimeter.getAllowedGroups()) 
            if (group instanceof SPGroup) 
                if (!isInherited || !inheritedPerimeter.getAllowedGroups().contains(group)) 
                    addPermissionTag(new PermissionTag(permission, (SPGroup) group));
                
             else 
                throw new IllegalArgumentException("Groups in perimeter must be an instance of com.sample.security.metier.impl.SPGroup");
            
        
        for (User user : perimeter.getAllowedUsers()) 
            if (user instanceof SPUser) 
                if (!isInherited || !inheritedPerimeter.getAllowedUsers().contains(user)) 
                    addPermissionTag(new PermissionTag(permission, (SPUser) user));
                
             else 
                throw new IllegalArgumentException("Users in perimeter must be an instance of com.sample.security.metier.impl.SPUser");
            
        
    

    ...

我的 junit 的 Spring 上下文:test-context.xml

<beans ...>

    <util:properties id="properties">
        <prop key="SMPsecurity.dataSource">dataSource</prop>
        <prop key="SMPsecurity.hibernate.generateDdl">false</prop>
        <prop key="SMPsecurity.hibernate.target-database">HSQL</prop>
    </util:properties>

    <context:property-placeholder properties-ref="properties"/>

    <import resource="classpath*:spring/SMPsecurity-context.xml" />

    <jdbc:embedded-database id="dataSource" type="HSQL" >
        <jdbc:script location="classpath:database/create-schemas.sql"/>
    </jdbc:embedded-database>
    <jdbc:initialize-database data-source="dataSource"  >
        <jdbc:script location="classpath:database/populate-security-data.sql" />
    </jdbc:initialize-database>     
    ....
</beans>

上下文的附加文件:SMPsecurity-context.xml

<beans ...>

    <tx:annotation-driven transaction-manager="transactionManagerSMPSecurity" />

    <jpa:repositories base-package="com.sample.security.repositories" entity-manager-factory-ref="entityManagerFactorySMPSecurity" transaction-manager-ref="transactionManagerSMPSecurity"/>

    <util:map id="HibernateConfigurationSMPSecurity">
        <entry key="hibernate.generateDdl" value="$SMPsecurity.hibernate.ddl-generation:true" />
        <entry key="hibernate.databasePlatform" value="org.hibernate.dialect.$SMPsecurity.hibernate.target-database:HSQLDialect" />
        <entry key="hibernate.hbm2ddl.auto" value="$SMPsecurity.hibernate.hbm2ddl:validate"/>
    </util:map>

    <bean id="entityManagerFactorySMPSecurity" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="$SMPsecurity.dataSource:dataSourceSMPSecurity"/>
        <property name="packagesToScan" value="com.sample.security.metier.impl" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" >
                <property name="showSql" value="false"/>
            </bean>
        </property>
        <property name="persistenceXmlLocation" value="classpath:data/security/security-persistence.xml"/>
        <property name="jpaPropertyMap" ref="HibernateConfigurationSMPSecurity"/>
    </bean>

    <bean id="transactionManagerSMPSecurity" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactorySMPSecurity" />
    </bean>

</beans>

还有数据库的架构:

CREATE schema security AUTHORIZATION DBA;--déclaration du schema et des droits pour HSQL

CREATE TABLE security.group (grp_id BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1 INCREMENT BY 1) NOT NULL, grp_name VARCHAR(150) NOT NULL, PRIMARY KEY (grp_id));
REATE TABLE security.user (usr_id BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1 INCREMENT BY 1) NOT NULL, usr_creation TIMESTAMP, usr_email VARCHAR(128), usr_enabled BOOLEAN NOT NULL, usr_expiration TIMESTAMP, usr_firstname VARCHAR(50), usr_lastname VARCHAR(50), usr_modification TIMESTAMP, usr_password VARCHAR(100) NOT NULL, usr_login VARCHAR(128) NOT NULL, PRIMARY KEY (usr_id));
CREATE TABLE security.group_user (grp_id BIGINT NOT NULL, usr_id BIGINT NOT NULL, PRIMARY KEY (grp_id, usr_id));
ALTER TABLE security.group ADD CONSTRAINT UNQ_group_1 UNIQUE (grp_name);
ALTER TABLE security.user ADD CONSTRAINT UNQ_user_2 UNIQUE (usr_email);
ALTER TABLE security.user ADD CONSTRAINT UNQ_user_9 UNIQUE (usr_login);
ALTER TABLE security.group_user ADD CONSTRAINT FK_group_user_usr_id FOREIGN KEY (usr_id) REFERENCES security.user (usr_id);
ALTER TABLE security.group_user ADD CONSTRAINT FK_group_user_grp_id FOREIGN KEY (grp_id) REFERENCES security.group (grp_id);

这是单元测试

@ContextConfiguration(value = "classpath:spring/test-context.xml")
@Transactional
public class SecurityTest 

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private GroupRepository groupRepository;

    ...

    private void setCurrentUser(User user) 
        Authentication authentication = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authentication);
    

    @Test
    public void roleCommercialTest() 

        SPUser commercial_63_1 = userRepository.findOne(1L);
        setCurrentUser(commercial_63_1);

        Assert.assertTrue(SMPPubServiceOrController.testHasAction1());  
    
    ...

【问题讨论】:

【参考方案1】:

我找到了。我必须像这样在 ManyToMany 注释上添加模式:

@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "group_user", schema="security", joinColumns =  
@JoinColumn(name = "grp_id", nullable = false, updatable = false) , 
inverseJoinColumns =  @JoinColumn(name = "usr_id", 
nullable = false, updatable = false) )

【讨论】:

【参考方案2】:

您的错误消息本质上是说表group_users 实际上并不存在。您需要确定删除此表的位置。

尝试更改您的 test-context.xml:

<jdbc:embedded-database id="dataSource" type="HSQL" >
    <jdbc:script location="classpath:database/create-schemas.sql"/>
    <jdbc:script location="classpath:database/populate-security-data.sql" />
</jdbc:embedded-database>

完全删除您的初始化数据库标签。会发生什么?

【讨论】:

您能否发布设置应用程序上下文的单元测试代码。您设置单元测试的方式可能存在错误配置 是的,我在堆栈跟踪的末尾添加了 **。之前,上面的代码使用 eclipseLink 作为持久数据层,我必须将其更改为休眠。为了测试生产模式,我选择添加一个 SQL 脚本来生成模式,并将 hibernate 配置为仅在 spring 上下文中验证模式:hibernate.hbm2ddl.auto -> validate 您的单元测试是否包含在事务中?虽然如果不是我希望看到LazyCollectionInitilizationException 你真的可以发布整个单元测试吗?我想看看你是如何配置这个测试在 Spring Application 上下文中运行的? 除了这个之外,您是否在 Spring Application 上下文中运行了其他单元测试?

以上是关于JPA + Spring 4 + Hibernate 4:用户缺少权限或找不到对象:USER_GROUP的主要内容,如果未能解决你的问题,请参考以下文章

6.Spring+Struts+Hibernat注解方式整合

springboot 问题

grails 3(spring-boot) - 如何配置hibernate二级缓存

jpa_缓存

spring boot 1.5.4 集成spring-Data-JPA

Spring Data JPA系列4:Spring声明式事务处理与多数据源支持