JBoss.orgCommunity Documentation

Chapter 8. Identity Management - Working with JPA

Table of Contents

8.1. JPAIdentityStoreConfiguration
8.1.1. Default Database Schema
8.1.2. Configuring an EntityManager
8.1.3. Mapping IdentityType Types
8.1.4. Mapping Partition Types
8.1.5. Mapping Relationship Types
8.1.6. Mapping Attributes for AttributedType Types
8.1.7. Mapping a CredentialStorage type
8.1.8. Configuring the Mapped Entities
8.1.9. Providing a EntityManager

The JPA identity store uses a relational database to store identity state. The configuration for this identity store provides control over which entity beans are used to store identity data, and how their fields should be used to store various identity-related state. The entity beans that store the identity data must be configured using the annotations found in the org.picketlink.jpa.annotations package. All identity configuration annotations listed in the tables below are from this package.

If you do not wish to provide your own JPA entities for storing IDM-related state, you may use the default schema provided by PicketLink in the picketlink-idm-simple-schema module. This module contains a collection of entity beans suitable for use with JPAIdentityStore. To use this module, add the following dependency to your Maven project's pom.xml file:


<dependency>
    <groupId>org.picketlink</groupId>
    <artifactId>picketlink-idm-simple-schema</artifactId>
    <version>${picketlink.version}</version>
</dependency>

In addition to including the above dependency, the default schema entity beans must be configured in your application's persistence.xml file. Add the following entries within the persistence-unit section:


<class>org.picketlink.idm.jpa.model.sample.simple.AttributedTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.AccountTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.RoleTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.GroupTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.IdentityTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.RelationshipTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.RelationshipIdentityTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.PartitionTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.PasswordCredentialTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.DigestCredentialTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.X509CredentialTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.OTPCredentialTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.AttributeTypeEntity</class>
yes

The following table summarizes all annotations that can be used to map entities to IdentityType types:


The following code shows an example of an entity class configured to store User types:


The following table summarizes all annotations that can be used to map entities to Relationship types:

Table 8.3. Relationship Annotations

AnnotationDescriptionProperty TypeRequired
@IdentityManaged This annotation is a type-level annotation and must be used to specify the Relationship types that should be mapped by the annotated entity. -True
@AttributeValue This annotation can be used to map a entity property to a Relationship property. The name property of this annotation can be used in case the property names are different. Any TypeFalse
@Identifier The unique identifier value for the relationship. StringTrue
@RelationshipClass The type for the relationship. When a Relationship is stored the FQN of its type is stored in a property annotated with this annotation. StringTrue
@RelationshipDescriptor This annotation must be used to indicate the field to store the name of the relationship role of a member. StringTrue
@RelationshipMember The reference to a IdentityType mapped entity. This annotation is used to identify the property that holds a reference to the identity type that belongs to this relationship with a specific descriptor. Usually this annotation is used in conjunction with a @ManyToOne property referencing the entity used to store identity types. The same type used to map a IdentityTypeTrue
@OwnerReference The reference to a Relationship mapped entity. This annotation is used to identify the property that holds a reference to the root entity for relationships, usually the entity annotated with the @RelationshipClass annotation. The same type used to map an entity with the @RelationshipClass annotation.True

The following code shows an example of an entity class configured to store Relationship types:


When mapping a relationship you also need to provide a specific entity to store its members:


The following table summarizes all annotations that can be used to map attributes to AttributedType types:


The following code shows an example of an entity class configured to store password-based credentials for IdentityType types:


Sometimes you may need to configure how the EntityManager is provided to the JPAIdentityStore, like when your application is using CDI and you must run the operations in the scope of the current transaction by using a injected EntityManager instance.

In cases like that, you need to initialize the IdentityContext by providing a ContextInitializer implementation, as discussed in Identity Context Configuration. You can always provide your own implementation for this interface to obtain the EntityManager from your application's environment.

IdentityConfigurationBuilder builder = new IdentityConfigurationBuilder();


builder
  .stores()
    .jpa()
      .addContextInitializer(new ContextInitializer() {
        @Override
        public void initContextForStore(IdentityContext context, IdentityStore<?> store) {
          if (store instanceof JPAIdentityStore) {
              EntityManager entityManager = // get the EntityManager
              context.setParameter(JPAIdentityStore.INVOCATION_CTX_ENTITY_MANAGER, entityManager);
          }
        }
      });

In most cases you don't need to provide your own ContextInitializer but use an implementation provided by PicketLink:

@Inject

private EEJPAContextInitializer contextInitializer;
public void observeIdentityConfigurationEvent(@Observes IdentityConfigurationEvent event) {
  IdentityConfigurationBuilder builder = event.getConfig();
  builder
    .stores()
      .jpa()
        // more JPA store config
        .addContextInitializer(this.contextInitializer);
}