title: JPA + Spring 4 + Hibernate 4 : user lacks privilege or object not found : USER_GROUP
body: <p>There are some trouble when i'm running my test under junit. I'm getting this error :</p>
  
  <pre><code>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 **
  </code></pre>
  
  <p>This is the part of code where the error occur :</p>
  
  <pre><code>public Set&lt;Role&gt; getRoles() {
      Set&lt;Role&gt; roles = new HashSet&lt;Role&gt;();
      List&lt;SPGroup&gt; localGroups = getGroups();
      if (localGroups != null) {
          ** for (SPGroup group : localGroups) { **
              roles.addAll(group.getRoles());
          }
      }
      return roles;
  }
  </code></pre>
  
  <p>getGroups function works well but the iteration on localGroups throws this error.</p>
  
  <p>Here are my code and config :</p>
  
  <p>SPUser entity</p>
  
  <pre><code>@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&lt;SPGroup&gt; 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&lt;SPGroup&gt; getGroups() {
          return groups;
      }
  
      public void setGroups(List&lt;SPGroup&gt; groups) {
          this.groups = groups;
      }
  
      public Set&lt;Role&gt; getRoles() {
          Set&lt;Role&gt; roles = new HashSet&lt;Role&gt;();
          List&lt;SPGroup&gt; localGroups = getGroups();
          if (localGroups != null) {
              for (SPGroup group : localGroups) {
                  roles.addAll(group.getRoles());
              }
          }
          return roles;
      }
  
      @Override
      public Map&lt;SPPermission, SPPerimeter&gt; getPermissions() {
          return SPGroup.mergePermissionsFromGroups(getGroups());
      }
  
      @Override
      public Collection&lt;? extends GrantedAuthority&gt; 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;
      }
  
      ...
  
  }
  </code></pre>
  
  <p>SPGroup Entity</p>
  
  <pre><code>@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&lt;SPUser&gt; users = new ArrayList&lt;SPUser&gt;();
  
      @ManyToMany(fetch = FetchType.LAZY, mappedBy = "childGroups")
      private List&lt;SPGroup&gt; parentGroups = new ArrayList&lt;SPGroup&gt;();
      @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&lt;SPGroup&gt; childGroups = new ArrayList&lt;SPGroup&gt;();
  
      @OneToMany(fetch = FetchType.LAZY, targetEntity=RoleTag.class ,mappedBy = "group", cascade={CascadeType.ALL})
      private List&lt;RoleTag&gt; roleTags = new ArrayList&lt;RoleTag&gt;();
      @OneToMany(fetch = FetchType.LAZY, targetEntity=PermissionTag.class, mappedBy = "group", cascade={CascadeType.ALL})
      private List&lt;PermissionTag&gt; permissionTags = new ArrayList&lt;PermissionTag&gt;();
  
      ...
  
      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&lt;SPUser&gt; getUsers() {
          return users;
      }
  
      public void setUsers(List&lt;SPUser&gt; users) {
          this.users = users;
      }
  
      public void addUser(SPUser user) {
          if (user.getGroups() == null) {
              user.setGroups(new ArrayList&lt;SPGroup&gt;());
          }
          if (!user.getGroups().contains(this)) {
              user.getGroups().add(this);
          }
          getUsers().add(user);
      }
  
      public List&lt;SPGroup&gt; getParentGroups() {
          return parentGroups;
      }
  
      public void setParentGroups(List&lt;SPGroup&gt; parentGroups) {
          this.parentGroups = parentGroups;
      }
  
      public List&lt;SPGroup&gt; getChildGroups() {
          return childGroups;
      }
  
      public void setChildGroups(List&lt;SPGroup&gt; childGroups) {
          this.childGroups = childGroups;
      }
  
      public List&lt;RoleTag&gt; getRoleTags() {
          return roleTags;
      }
  
      public void setRoleTags(List&lt;RoleTag&gt; roleTags) {
          this.roleTags = roleTags;
      }
  
      public List&lt;PermissionTag&gt; getPermissionTags() {
          return permissionTags;
      }
  
      public void setPermissionTags(List&lt;PermissionTag&gt; permissionTags) {
          this.permissionTags = permissionTags;
      }
  
      public void addPermissionTag(PermissionTag permissionTag) {
          permissionTag.setGroup(this);
          getPermissionTags().add(permissionTag);
      }
  
      @Override
      public List&lt;SPUser&gt; getAllUsers() {
          List&lt;SPUser&gt; allUsers = new ArrayList&lt;SPUser&gt;(getUsers());
          for (SPGroup childGroup : getAllChildGroups()) {
              for (SPUser user : childGroup.getUsers()) {
                  if (!allUsers.contains(user)) {
                      allUsers.add(user);
                  }
              }
          }
          return allUsers;
      }
  
      @Override
      public List&lt;SPGroup&gt; getAllParentGroups() {
          return getAllParentGroups(new HashSet&lt;SPGroup&gt;(Arrays.asList(this)));
      }
  
      private List&lt;SPGroup&gt; getAllParentGroups(Set&lt;SPGroup&gt; ignoreSet) {
          List&lt;SPGroup&gt; allparentGroups = new ArrayList&lt;SPGroup&gt;();
          for (SPGroup parent : getParentGroups()) {
              if (!ignoreSet.contains(parent)) {
                  ignoreSet.add(parent);
                  allparentGroups.add(parent);
                  allparentGroups.addAll(parent.getAllParentGroups(ignoreSet));
              }
          }
          return allparentGroups;
      }
  
      @Override
      public List&lt;SPGroup&gt; getAllChildGroups() {
          return getAllChildGroups(new HashSet&lt;SPGroup&gt;(Arrays.asList(this)));
      }
  
      private List&lt;SPGroup&gt; getAllChildGroups(Set&lt;SPGroup&gt; ignoreSet) {
          List&lt;SPGroup&gt; allChildrenGroups = new ArrayList&lt;SPGroup&gt;();
          for (SPGroup child : getChildGroups()) {
              if (!ignoreSet.contains(child)) {
                  ignoreSet.add(child);
                  allChildrenGroups.add(child);
                  allChildrenGroups.addAll(child.getAllChildGroups(ignoreSet));
              }
          }
          return allChildrenGroups;
      }
  
      @Override
      public Set&lt;Role&gt; getRoles() {
          return getRoles(true);
      }
  
      private Set&lt;Role&gt; getRoles(boolean merged) {
          if (merged) {
              return getActiveRoles(getMergedRoleMap());
          } else {
              return getActiveRoles(getRoleMap());
  
          }
      }
  
      private Map&lt;Role, Boolean&gt; getRoleMap() {
          Map&lt;Role, Boolean&gt; roleMap = new HashMap&lt;Role, Boolean&gt;();
          for (RoleTag roleTag : getRoleTags()) {
              roleMap.put(roleTag.getRole(), roleTag.isGranting());
          }
          return roleMap;
      }
  
      private Map&lt;Role, Boolean&gt; getParentsRoleMap() {
          return mergeRolesFromGroups(getParentGroups());
      }
  
      private Map&lt;Role, Boolean&gt; getMergedRoleMap() {
          Map&lt;Role, Boolean&gt; roleMap = getRoleMap();
          for (Entry&lt;Role, Boolean&gt; 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&lt;Role, Boolean&gt; mergeRolesFromGroups(List&lt;SPGroup&gt; groups) {
          Map&lt;Role, Boolean&gt; mergedRoleMap = new HashMap&lt;Role, Boolean&gt;();
          // merge of the parents' role
          for (SPGroup group : groups) {
              for (Entry&lt;Role, Boolean&gt; roleMapEntry : group.getMergedRoleMap().entrySet()) {
                  if (mergedRoleMap.containsKey(roleMapEntry.getKey())) {
                      // We apply a OR operation between the parents' role
                      if (roleMapEntry.getValue() &amp;&amp; !mergedRoleMap.get(roleMapEntry.getKey())) {
                          mergedRoleMap.put(roleMapEntry.getKey(), roleMapEntry.getValue());
                      }
                  } else {
                      mergedRoleMap.put(roleMapEntry.getKey(), roleMapEntry.getValue());
                  }
              }
          }
          return mergedRoleMap;
      }
  
      private static Set&lt;Role&gt; getActiveRoles(Map&lt;Role, Boolean&gt; roleMap) {
          Set&lt;Role&gt; roles = new HashSet&lt;Role&gt;();
          for (Entry&lt;Role, Boolean&gt; mapEntry : roleMap.entrySet()) {
              if (mapEntry.getValue()) {
                  roles.add(mapEntry.getKey());
              }
          }
          return roles;
      }
  
      private Map&lt;SPPermission, SPPerimeter&gt; getPermissionMap() {
          Map&lt;SPPermission, SPPerimeter&gt; permissionMap = new HashMap&lt;SPPermission, SPPerimeter&gt;();
          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&lt;SPPermission, SPPerimeter&gt; getParentsPermissionMap() {
          return mergePermissionsFromGroups(getParentGroups());
      }
  
      public Map&lt;SPPermission, SPPerimeter&gt; getMergedPermissionMap() {
          Map&lt;SPPermission, SPPerimeter&gt; permissionMap = getPermissionMap();
          for (Entry&lt;SPPermission, SPPerimeter&gt; 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&lt;SPPermission, SPPerimeter&gt; mergePermissionsFromGroups(List&lt;SPGroup&gt; groups) {
          Map&lt;SPPermission, SPPerimeter&gt; permissionMap = new HashMap&lt;SPPermission, SPPerimeter&gt;();
          for (SPGroup group : groups) {
              for (Entry&lt;SPPermission, SPPerimeter&gt; 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&lt;SPPermission, SPPerimeter&gt; 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&lt;Role, Boolean&gt; 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&lt;RoleTag&gt; 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) &amp;&amp; roleMap.get(role)) {
                  // Role present
                  Iterator&lt;RoleTag&gt; 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) &amp;&amp; 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&lt;PermissionTag&gt; 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");
              }
          }
      }
  
      ...
  }
  </code></pre>
  
  <p>My Spring context for junit : test-context.xml</p>
  
  <pre><code>&lt;beans ...&gt;
  
      &lt;util:properties id="properties"&gt;
          &lt;prop key="SMPsecurity.dataSource"&gt;dataSource&lt;/prop&gt;
          &lt;prop key="SMPsecurity.hibernate.generateDdl"&gt;false&lt;/prop&gt;
          &lt;prop key="SMPsecurity.hibernate.target-database"&gt;HSQL&lt;/prop&gt;
      &lt;/util:properties&gt;
  
      &lt;context:property-placeholder properties-ref="properties"/&gt;
  
      &lt;import resource="classpath*:spring/SMPsecurity-context.xml" /&gt;
  
      &lt;jdbc:embedded-database id="dataSource" type="HSQL" &gt;
          &lt;jdbc:script location="classpath:database/create-schemas.sql"/&gt;
      &lt;/jdbc:embedded-database&gt;
      &lt;jdbc:initialize-database data-source="dataSource"  &gt;
          &lt;jdbc:script location="classpath:database/populate-security-data.sql" /&gt;
      &lt;/jdbc:initialize-database&gt;     
      ....
  &lt;/beans&gt;
  </code></pre>
  
  <p>Additional file for context : SMPsecurity-context.xml</p>
  
  <pre><code>&lt;beans ...&gt;
  
      &lt;tx:annotation-driven transaction-manager="transactionManagerSMPSecurity" /&gt;
  
      &lt;jpa:repositories base-package="com.sample.security.repositories" entity-manager-factory-ref="entityManagerFactorySMPSecurity" transaction-manager-ref="transactionManagerSMPSecurity"/&gt;
  
      &lt;util:map id="HibernateConfigurationSMPSecurity"&gt;
          &lt;entry key="hibernate.generateDdl" value="${SMPsecurity.hibernate.ddl-generation:true}" /&gt;
          &lt;entry key="hibernate.databasePlatform" value="org.hibernate.dialect.${SMPsecurity.hibernate.target-database:HSQL}Dialect" /&gt;
          &lt;entry key="hibernate.hbm2ddl.auto" value="${SMPsecurity.hibernate.hbm2ddl:validate}"/&gt;
      &lt;/util:map&gt;
  
      &lt;bean id="entityManagerFactorySMPSecurity" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"&gt;
          &lt;property name="dataSource" ref="${SMPsecurity.dataSource:dataSourceSMPSecurity}"/&gt;
          &lt;property name="packagesToScan" value="com.sample.security.metier.impl" /&gt;
          &lt;property name="jpaVendorAdapter"&gt;
              &lt;bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" &gt;
                  &lt;property name="showSql" value="false"/&gt;
              &lt;/bean&gt;
          &lt;/property&gt;
          &lt;property name="persistenceXmlLocation" value="classpath:data/security/security-persistence.xml"/&gt;
          &lt;property name="jpaPropertyMap" ref="HibernateConfigurationSMPSecurity"/&gt;
      &lt;/bean&gt;
  
      &lt;bean id="transactionManagerSMPSecurity" class="org.springframework.orm.jpa.JpaTransactionManager"&gt;
          &lt;property name="entityManagerFactory" ref="entityManagerFactorySMPSecurity" /&gt;
      &lt;/bean&gt;
  
  &lt;/beans&gt;
  </code></pre>
  
  <p>And the schema of the database :</p>
  
  <pre><code>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);
  </code></pre>
  
  <p>Here is the unit test</p>
  
  <pre><code>@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());  
      }
      ...
  }
  </code></pre>