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]