You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@rave.apache.org by "anne-helene.turpin@renater.fr" <an...@renater.fr> on 2012/05/31 12:41:26 UTC

Re: Extend Person model as Rave-Extension

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