Thank you very much.  That makes sense and seems like a good solution.  
Apologies to all for my being dense.

----- Original Message ----
From: Imants Firsts <[EMAIL PROTECTED]>
To: Tapestry users <users@tapestry.apache.org>
Sent: Wednesday, January 23, 2008 4:36:00 AM
Subject: Re: T5: Inject services into domain objects?


For the domain objects that need access to tapestry
service I define a constructor which takes as a
parameter the needed service. In my case I only have
one such service (not separate DAOs for all domain
objects) - HibernateService.

Then I contribute the following interceptor to
Hibernate, which makes Hibernate to instantiate domain
objects with my constructor instead of the default one.

It is also easy to test such domain objects, because
you simply call the needed constructor to create them.

public class ServiceInjectionInterceptor<T extends
HibernateService> extends EmptyInterceptor {
    private static final long serialVersionUID =
-441261606300488418L;

    private T service = null;

    public ServiceInjectionInterceptor(T service) {
        this.service = service;
    }
    
    @Override
    public Object instantiate(String entityName,
EntityMode entityMode, Serializable id) throws
CallbackException {
        if (service == null) {
            throw new IllegalStateException("Service is null,
but we are already creating objects!");
        }

        Class<?> clazz;
        try {
            clazz = ReflectHelper.classForName(entityName);
        } catch (ClassNotFoundException e) {
            throw new CallbackException(e);
        }
        // Only inject in classes which have an appropriate
constructor
        Constructor<?> constructor;
        try {
            constructor =
ClassUtils.findConstructorWhichAcceptsType(clazz,
service.getClass());
        } catch (NoSuchMethodException e) {
            return null;
        }
        
        Object object;
        try {
            object = constructor.newInstance(service);
        } catch (InstantiationException e) {
            throw new CallbackException(e);
        } catch (IllegalAccessException e) {
            throw new CallbackException(e);
        } catch (InvocationTargetException e) {
            throw new CallbackException(e);
        }
        service.getClassMetadata(clazz).setIdentifier(object,
id, entityMode);
        return object;
    }
}


Quoting Franz Amador <[EMAIL PROTECTED]>:
> I'm afraid I don't see a connection between Hibernate
interceptors and my
> use case.  I'm wondering if it's because I didn't
explain myself well
> enough.  In my use case, a domain object is executing
some business
> logic.  It needs to gather some other domain objects
to do something with
> them, and for some reason it doesn't make sense to
treat them as a
> collection mapped by Hibernate (query too complex,
collection too
> temporary, something like that).
> 
> The object that knows how to execute such queries is
a DAO (data-access
> object, a common pattern for encapsulating access to
the database), which
> is a singleton service that was injected with access
to Hibernate.  In
> fact, there are two implementations of this DAO: the
"production" one
> that uses Hibernate, and a "test" one that keeps
objects in memory and
> runs really fast for unit tests of the domain
objects.  So, my domain
> object asks the DAO for the other domain objects and
goes about its merry
> way.
> 
> The question is, how does my domain object get hold
of the DAO?  The
> domain object is highly temporary, and was probably
created by Hibernate
> (though in a unit test it's probably created just
using "new").  The
> obvious, old-school way is for the domain object to
use a static method
> that gets the DAO instance from a static variable. 
That'll still work,
> and it isn't *too* horrible, given that the DAO is
still being
> constructed via IOC, with its dependencies being
injected.  Still, it's
> unsavory, and it'd be much nicer to be able to inject
the DAO into the
> domain object.
> 
> ----- Original Message ----
> From: Davor Hrg <[EMAIL PROTECTED]>
> To: Tapestry users <users@tapestry.apache.org>
> Sent: Monday, January 21, 2008 12:56:49 PM
> Subject: Re: T5: Inject services into domain objects?
> 
> 
> have you tried using a hibernate interceptor ?
> 
> On Jan 21, 2008 8:26 PM, Franz Amador
<[EMAIL PROTECTED]> wrote:
> > Are there any plans for a way to inject services
into domain objects,
>  i.e. entities created by Hibernate?  For example, my
domain objects
>  have some fairly complex business logic that must
occasionally execute
> a
>  query.  For that, they use a DAO, which is a
service, but it's not
>  clear the best way for them to get access to the
DAOs.  In the absence
> of
>  something better, I tend to keep a static reference
to the instance of
>  each DAO, but that's poor form.
> >
> > Spring has a way of doing this using aspects, and I
know it's
>  controversial.  I've seen heated debates between
those who believe
> entities
>  should be simple data carriers that have no reason
to access services
> and
>  those who prefer a more classic OO style in which
the entities are
>  full domain objects that carry out the primary
behavior of the app.
>   Obviously I fall into the latter camp, and I
believe there are enough
> of us
>  to form a sizable constituency for such a feature.
> >
> >
> >
> 
>
---------------------------------------------------------------------
> To unsubscribe, e-mail:
[EMAIL PROTECTED]
> For additional commands, e-mail:
[EMAIL PROTECTED]


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]




Reply via email to