Hi Tony and all,

I've got some questions about your work on extending the User model for your internal implementation. I try to do the same for the Person model and the person service SPI.
Hi Raminder, we've been working on extending the User for our internal 
implementation.  It's still in the early stages but here is what I've done so 
far (all code is done in our overlay):

1) Create a Custom user:

package org.custom.portal.model;

@Entity
public class CustomUser extends org.apache.rave.model.User {
        @Transient
                 private String employeeNumber; 
        @Transient
        private String jobTitle;
        @Transient
        private String building;
        ...
                 // other custom user attributes
}

Our custom fields are marked Transient as they are populated from a read-only 
data source (LDAP) and we don't plan on allowing updates to them via Rave.

What are you declare in the persistence file ?
If I declare the CutomPerson as an Entity in the class but not in the persistence file, I can't call declared named queries on it. So I had to annotate the CustomPerson model class with @MappedSuperclass and I had to declare the CustomPerson in the persistence file in order to use it. It's work.

2) Create a new CustomUserRepository interface:

public interface CustomUserRepository {
         CustomUser getByEmployeeNumber(String employeeNumber);
         // ...  other custom function signatures
}

3) Create a new DefaultCustomUserRepository class with "userRepository" as the bean name 
that is marked as @Primary to override the default Rave userRepository implemenation 
(DefaultUserRepository).  This custom class will get injected into any Spring Bean that needs a 
"userRepository" like UserService.

@Repository(value="userRepository")
@Primary
@Transactional
public class DefaultCustomUserRepository extends JpaUserRepository implements 
CustomUserRepository {

        @Override
        public CustomUser getByEmployeeNumber(String employeeNumber) {
             ...
        }

        // custom code that fetches the new user data fields from our LDAP 
server
        private CustomUser getCustomUserFromLDAP(String employeeNumber) {
             ...
        }
}

4) Overlay core-applicationContext.xml with our version that includes component 
scans of our custom packages:
...
     <!-- component scan custom code -->
     <context:component-scan base-package="org.custom.portal.repository"/>
...

5) Overlay applicationContext.xml to reference our core-applicationContext.xml 
file:
...
     <import 
resource="classpath*:org/custom/portal/core-applicationContext.xml"/>
     <import resource="classpath*:org/apache/rave/web-applicationContext.xml"/>
     <import 
resource="classpath*:org/apache/rave/opensocial-provider-applicationContext.xml"/>
     <import 
resource="classpath*:org/apache/rave/w3c-provider-applicationContext.xml"/>
...

Again we are still in the early stages of this work so things may change over 
time but this should give you enough of a starting point.

Tony


I tried the same and it works for me if I'm declaring the PersonRepository in the service class but not with the CustomPersonRespository. But I can't call the custom method added in the CustomPersonRepository. If I declare a CustomPersonrepository in my CustomPersonService, I've got this deployment error :

   /org.springframework.beans.factory.UnsatisfiedDependencyException:
   Error creating bean with name 'customPersonService' defined in URL
   [jar:file:....CustomPersonServiceImpl.class]: Unsatisfied dependency
   expressed through constructor argument with index 1 of type
   [fr.renater.opensocial.repository.impl.CustomPersonRepositoryImpl]:
   : No matching bean of type
   [fr.renater.opensocial.repository.impl.CustomPersonRepositoryImpl]
   found for dependency: expected at least 1 bean which qualifies as
   autowire candidate for this dependency. Dependency annotations: {};
   nested exception is
   org.springframework.beans.factory.NoSuchBeanDefinitionException: No
   matching bean of type
   [fr.renater.opensocial.repository.impl.CustomPersonRepositoryImpl]
   found for dependency: expected at least 1 bean which qualifies as
   autowire candidate for this dependency. Dependency annotations: {}/
   /..../
   /Caused by:
   org.springframework.beans.factory.NoSuchBeanDefinitionException: No
   matching bean of type
   [fr.renater.opensocial.repository.impl.CustomPersonRepositoryImpl]
   found for dependency: expected at least 1 bean which qualifies as
   autowire candidate for this dependency. Dependency annotations: {}/


I don't understand. I create the custom repository class like this :

   /@Repository (value="personRepository")/
   /@Primary/
   /@Transactional/
   /public class CustomPersonRepositoryImpl extends JpaPersonRepository
   implements CustomPersonRepository{...}/

I include component scans of our custom package to the srping configuration file.

Which repository do you declare in your CustomUserService ? Can you share your experience ?

The original message was posted on the incubator developer mailing list. I'm sending a copy to the user mailing list, I think it could be interest some people.

Thanks
Anne-Hélène



--
Anne-Hélène TURPIN
Renater
Service Applicatif aux Utilisateurs
Tel : +33 2 23 23 71 42

Attachment: smime.p7s
Description: Signature cryptographique S/MIME

Reply via email to