2

There are some trouble when i'm running my test under junit. I'm getting this error :

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 **

This is the part of code where the error occur :

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 function works well but the iteration on localGroups throws this error.

Here are my code and config :

SPUser entity

@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

@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");
            }
        }
    }

    ...
}

My Spring context for junit : 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>

Additional file for context : 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:HSQL}Dialect" />
        <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>

And the schema of the database :

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);

Here is the unit test

@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());  
    }
    ...
}
FlyIn71
  • 31
  • 1
  • 6

2 Answers2

1

I found it. I have to add schema on ManyToMany annotation like this :

@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) })
FlyIn71
  • 31
  • 1
  • 6
0

Your error message is essentially saying that the table group_users doesn't actually exist. You need to work out where this table is being deleted.

Try changing your 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>

Totally remove your initialize-database tag. What happens?

JamesENL
  • 6,400
  • 6
  • 39
  • 64
  • Can you post the unit test code that is setting up your application context. there may be a misconfiguration in the way that you are setting up your unit tests – JamesENL May 01 '14 at 06:22
  • Yes, I added the ** to the end of the stacktrace. Before, the code above used eclipseLink as persistent data layer, I have to change it for hibernate. To test production mode, I choose to add an SQL script to generate schema and I configure hibernate to only validate schema in the spring context : hibernate.hbm2ddl.auto -> validate – FlyIn71 May 01 '14 at 06:22
  • And is your unit test wrapped in a transaction? Although if it wasn't I'd expect to see a `LazyCollectionInitilizationException` – JamesENL May 01 '14 at 06:25
  • Can you actually post the entire unit test? I want to see how you configured this test to run within the Spring Application context? – JamesENL May 01 '14 at 06:32
  • Have you got other unit tests running within the Spring Application context besides this one? – JamesENL May 01 '14 at 06:37
  • Yes and all use the same function getRoles. And they all fail on the same line because, all tests begin with setCurrentUser which is invoking getAuthorities function. In this one, there is a call to getRoles. – FlyIn71 May 01 '14 at 06:43
  • Are you using Spring Security's `UsernamePasswordAuthenticationToken` to secure access to your database? How? Usually the `UsernamePasswordAuthenticationToken` is only used to secure sessions or logins. – JamesENL May 01 '14 at 06:44
  • I'm not using spring security to control access to database. This project is a framework to deliver authorities to action, using spring security. That's why i'm using the authentication in junit test. – FlyIn71 May 01 '14 at 06:50
  • The first test which modify the database definition has the same result. For the second, I had to insert data to the database after hibernate creates schema otherwise, I cannot pass through getRoles function – FlyIn71 May 01 '14 at 07:29
  • Ok, if that's the case, then the table is either being deleted from the database or it is never being generated in the first place. Ensure that your session factory, and transaction manager are correctly configured. Have a look at how to run unit tests inside a transaction. My gut says its a problem with your application context not being preserved between tests. – JamesENL May 01 '14 at 07:35
  • When i'm using code to generate data test at the beggining of my test function, It works. I think there is not the same schema generated by hibernate than the other in sql script. Is there a way to compare it? That's the code I used to generate data : CFUser userToRegister = new CFUser("commercial.63-1","","commercial.63-1@sample.com",true); List listGroup = new ArrayList(); CFGroup groupToRegister = new CFGroup("Commercial 63"); listGroup.add(groupToRegister); userToRegister.setGroups(listGroup); userRepository.save(userToRegister); – FlyIn71 May 01 '14 at 07:47
  • Enable your hibernate logging to see the schema creation or validation step: http://stackoverflow.com/questions/8490617/enable-hibernate-logging – JamesENL May 01 '14 at 07:55
  • I could compare it. The only difference is : On the generated schema, there is no primary key to the group_user table. Is there a way to add it? – FlyIn71 May 01 '14 at 08:06
  • stop all schema generation, only run off your scripts. so change your SMPsecurity-context.xml `` . If you are generating your schema in SMPsecurity-context.xml then you will be overriding what you initially put there. What happened when you tried to run your unit tests – JamesENL May 01 '14 at 08:09
  • I used a bad parameter in test-context.xml : SMPsecurity.hibernate.generateDdl in replacement of SMPsecurity.hibernate.ddl-generation. But after change, there is no difference. In order to disable generation I use this parameters in SMPsecurity-context.xml : hibernate.generateDdl -> false hibernate.hbm2ddl.auto -> validate – FlyIn71 May 01 '14 at 08:31
  • Add `` into your test-context.xml. Are you actually using your bean to configure hibernate with? – JamesENL May 01 '14 at 08:32
  • I added SMPsecurity.hibernate.hbm2ddl to validate in test-context.xml but no change. In SMPsecurity-context.xml, i'm using an Map to configure jpa properties and this map is instanciated by an util:properties in test-context.xml – FlyIn71 May 01 '14 at 08:40