You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@wicket.apache.org by Shu <we...@yahoo.com> on 2012/07/16 05:10:18 UTC

Retaining non-injected properties of a SpringBean

In the Spring-enabled example below, the DAODataProvider object has an entityClass property. When the user navigates to the DemoPage via the Back button, the dataProvider and dataProvider.dao properties are available, but dataProvider.entityClass is null. This is because dataProvider is a proxy which doesn't serialize its own non-injected state fields.




public class DemoPage extends WebPage { 
    @Inject @SpringBean DAODataProvider dataProvider; 

    public DemoPage(final PageParameters parameters) throws ClassNotFoundException, IntrospectionException { 
        super(parameters); 
        dataProvider.setEntityClass(UserAccount.class); 
        add(new CRUDPanel("panel", UserAccount.class, dataProvider)); 
    } 
} 

@Component 
@Scope("request") 
public class DAODataProvider extends SortableDataProvider { 
    @Inject protected GeneralDAO dao; 
    private Class<?> entityClass; 

    public DAODataProvider() { 
        super(); 
    } 
} 


The solution for retaining the state of a non-Wicket component seems to be to either do this (Option 1):

(Option 1)
public class DemoPage extends WebPage { 
    @Inject @SpringBean DAODataProvider dataProvider; 

    public DemoPage(final PageParameters parameters) throws ClassNotFoundException, IntrospectionException { 
        super(parameters); 
        dataProvider.setEntityClass(UserAccount.class); 
        add(new CRUDPanel("panel", UserAccount.class, dataProvider)); 
    } 

    @Override 
    protected void onBeforeRender() 
    { 
        dataProvider.setEntityClass(UserAccount.class); 
        super.onBeforeRender(); 
    } 
} 


or use Injector (Option 2):

(Option 2)

public class DemoPage extends WebPage { 
    DAODataProvider dataProvider; 

    public DemoPage(final PageParameters parameters) throws ClassNotFoundException, IntrospectionException { 
        super(parameters); 
        dataProvider = new DAODataProvider();
        dataProvider.setEntityClass(UserAccount.class); 
        add(new CRUDPanel("panel", UserAccount.class, dataProvider)); 
    } 
} 

@Component 
@Scope("request") 
public class DAODataProvider extends SortableDataProvider { 
    @Inject protected GeneralDAO dao; 
    private Class<?> entityClass; 

    public DAODataProvider() { 
        super(); 
        Injector.get().inject(this);
    } 
} 


or use Session scope (Option 3):


@Component 
@Scope("session") 
public class DAODataProvider extends SortableDataProvider { 
    @Inject protected GeneralDAO dao; 
    private Class<?> entityClass; 

    public DAODataProvider() { 
        super(); 
    } 
} 


The first 2 options create a tighter dependency between my code and Spring, which I would like to avoid. With the 3rd option it is difficult to have many instances of DAODataProvider within the same user session.

Is there a better way to indicate that a SpringBean-injected object should have its non-injected properties serialized? Or is there some sort of Page scope where dependencies are bound to a page and deserialized appropriately?


Thanks,
Shu          

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Retaining non-injected properties of a SpringBean

Posted by Dan Retzlaff <dr...@gmail.com>.
Hi Shu,

We essentially use option 2. Since we use Guice, @Component and @Scope are
unfamiliar to me. (DAODataProvider isn't created/managed by Spring, so why
specify a scope like that?) Aside from those, I don't see any undue
coupling... just an @Inject.

Our general rule is that @Inject'd dependencies should never have mutable
state. Your options 1 and 3 are tricky workarounds necessary only because
you violated this simple rule. Once you introduce things like data filters
and variable sorting into your data provider, you'll find these approaches
even more problematic.

Hope that helps,
Dan

On Sun, Jul 15, 2012 at 8:10 PM, Shu <we...@yahoo.com> wrote:

> In the Spring-enabled example below, the DAODataProvider object has an
> entityClass property. When the user navigates to the DemoPage via the Back
> button, the dataProvider and dataProvider.dao properties are available, but
> dataProvider.entityClass is null. This is because dataProvider is a proxy
> which doesn't serialize its own non-injected state fields.
>
>
>
>
> public class DemoPage extends WebPage {
>     @Inject @SpringBean DAODataProvider dataProvider;
>
>     public DemoPage(final PageParameters parameters) throws
> ClassNotFoundException, IntrospectionException {
>         super(parameters);
>         dataProvider.setEntityClass(UserAccount.class);
>         add(new CRUDPanel("panel", UserAccount.class, dataProvider));
>     }
> }
>
> @Component
> @Scope("request")
> public class DAODataProvider extends SortableDataProvider {
>     @Inject protected GeneralDAO dao;
>     private Class<?> entityClass;
>
>     public DAODataProvider() {
>         super();
>     }
> }
>
>
> The solution for retaining the state of a non-Wicket component seems to be
> to either do this (Option 1):
>
> (Option 1)
> public class DemoPage extends WebPage {
>     @Inject @SpringBean DAODataProvider dataProvider;
>
>     public DemoPage(final PageParameters parameters) throws
> ClassNotFoundException, IntrospectionException {
>         super(parameters);
>         dataProvider.setEntityClass(UserAccount.class);
>         add(new CRUDPanel("panel", UserAccount.class, dataProvider));
>     }
>
>     @Override
>     protected void onBeforeRender()
>     {
>         dataProvider.setEntityClass(UserAccount.class);
>         super.onBeforeRender();
>     }
> }
>
>
> or use Injector (Option 2):
>
> (Option 2)
>
> public class DemoPage extends WebPage {
>     DAODataProvider dataProvider;
>
>     public DemoPage(final PageParameters parameters) throws
> ClassNotFoundException, IntrospectionException {
>         super(parameters);
>         dataProvider = new DAODataProvider();
>         dataProvider.setEntityClass(UserAccount.class);
>         add(new CRUDPanel("panel", UserAccount.class, dataProvider));
>     }
> }
>
> @Component
> @Scope("request")
> public class DAODataProvider extends SortableDataProvider {
>     @Inject protected GeneralDAO dao;
>     private Class<?> entityClass;
>
>     public DAODataProvider() {
>         super();
>         Injector.get().inject(this);
>     }
> }
>
>
> or use Session scope (Option 3):
>
>
> @Component
> @Scope("session")
> public class DAODataProvider extends SortableDataProvider {
>     @Inject protected GeneralDAO dao;
>     private Class<?> entityClass;
>
>     public DAODataProvider() {
>         super();
>     }
> }
>
>
> The first 2 options create a tighter dependency between my code and
> Spring, which I would like to avoid. With the 3rd option it is difficult to
> have many instances of DAODataProvider within the same user session.
>
> Is there a better way to indicate that a SpringBean-injected object should
> have its non-injected properties serialized? Or is there some sort of Page
> scope where dependencies are bound to a page and deserialized appropriately?
>
>
> Thanks,
> Shu
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>