
Originally Posted by
assaf
Given an ApplicationContext (which is what I have by implementing ApplicationContextAware in my new domain-object "factory" bean), where do you get an implementation of the AutowireCapableBeanFactory? Do you create a DefaultListableBeanFactory? Can you give the actual code?
Sure, this will do it:
Code:
public SomeClass implements BeanFactoryAware {
private AutowireCapableBeanFactory acbf;
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
if (!(beanFactory instanceof AutowireCapableBeanFactory)) {
throw new IllegalArgumentException("BeanFactory must be AutowireCapableBeanFactory");
}
this.acbf = (AutowireCapableBeanFactory) beanFactory;
}
}

Originally Posted by
assaf
I use AutowireCapableBeanFactory with DependencyInjectionInterceptorFactoryBean whenever I need a new object.
Related question: what do you mean when you say you use it "with" DependencyInjectionInterceptorFactoryBean? Do you use the latter somehow explicitly when creating new beans (as opposed to Hibernate-loaded beans)?
Sorry for being unclear here. When I have domain objects that I will be persisting via Hibernate, I use the DependencyInjectionInterceptorFactoryBean when retrieving those objects from Hibernate. I use the AutowireCapableBeanFactory.autowire methods when I am first creating those objects, before they are ever persisted. That's because my validation approach needs a Validator, and autowiring (via AutowireCapableBeanFactory for new instances, via DependencyInjectionInterceptorFactoryBean for existing instances) is an easy way to inject the Validator.

Originally Posted by
assaf
I see in your interface that you insist validate does not change the state of the object, but only reports errors.
Would you place all of the above into bindSupport?
Yes, the bindSupport method is allowed to change the object as it wishes. Validate is not supposed to change the object, given it theoretically should be dealing with a fully valid object by the time is is called.

Originally Posted by
assaf
I'm probably missing something here, but let's say in your MVC controller, you first bind the domain object (calling bindSupport), and then automatically call the Validator, and then, in onSubmit, you actually persist the changes through a service layer call.
However, when you persist the object, the DAO layer "update" gets called, which in turn calls bindAndValidate()... So that both bind and validate get called twice. Is this what happens?
Yes, it gets called twice. It needs to happen this way in case your services layer modifies the object in some way, making it invalid. This is why the interceptor sits on the DAO methods, because it's the last chance before it is actually saved. We could have taken that a step further and used a Hibernate Interceptor, but then bindSupport() could never modify the object. It's also non-portable to other persistence frameworks if you did that.

Originally Posted by
assaf
If so, assuming (as in the above case), the bindSupport method makes other changes to the child object hierarchy (and possibly creates other objects for persistence), I would need some kind of boolean safeguard to make sure it only gets called once. All of which seems a bit messy!
If you're simply modifying properties in the child object hierarchy, what's the problem? It isn't too much of a performance problem to do that. Now if you are creating additional child objects, isn't there some sort of logic you could embed in your domain object to determine whether or not all the necessary child objects have been created? Working around the "only gets called once" won't work, because bindAndValidate() is designed to also be called by any business method that requires a guaranteed valid object state. So you could have a third, forth and fifth call as well in a given use case. As such I'd either leave creating the child objects to some other class (most likely the services layer method that implements the given use case) or embed necessary logic into the domain object to control whether or not it needs an additional child.
Hope this helps.