I have this object:
#Service
public class myBr {
#PostFilter("filterObject.cellule.getId()==2")
public List<Bibliotheque> getB() {
return super.getAll();
}
public List<Bibliotheque> getA() {
return getB();
}
}
When I call from a test that does myBr.getB(), the #PostFilter is applied, but when I call myBr.getA(), the postfilter is not working.
Is there a way to handle this so that the filter is applied?
The issue is that the #PostFilter is applied through AOP techniques, yet you are calling the instance's implementation of getB() directly from getA(), and Spring AOP does not rewrite classes.
Here's what's going on:
+————————+ +——————————+
getA | pass | getA | |
—————>|·······>|—————>| |———+
| | | | |
| Bean | | Instance | | this.getB
| | | | |
getB | filter | getB | | |
—————>|·······>|—————>| |<——+
| | | |
+————————+ +——————————+
Spring AOP puts a proxy object as the actual bean that delegates to your bean, either by using a JDK proxy object (when you've got a suitable interface) or by using CGLIB to synthesize the object de novo. For getA it just passes straight through, and for getB it inserts the call into the post filtering code. That's great, but it does mean that when the instance — the object you've got as this inside the getA — is used to invoke getB directly, it skips the filter and jumps straight into the underlying code.
There are four possible fixes.
Use AspectJ to do the application of the AOP code, which does code rewriting (at a cost of a lot more complexity in deployment).
Give a handle to the bean to the instance (has to be done explicitly; you can't autowire it) and invoke getB through that.
Put getB in a different bean.
Put the filtering on both methods.
I've used option #2 myself (it was easier than the alternatives in my particular situation) and it works quite well, but the best option is almost certainly #3, so that you don't need to do self-calls to “interface” methods; that sort of thing is often indicative of incorrect partitioning of the application's functionality.
I assume that you have already solved your problem, but in case anyone is wondering about similar stuff with his bean calls (i had the same problem with EJBs):
Method annotations are read by the container/the application context or whatever it is that handles the injection. And when, like in this case, some kind of interceptor is needed to trigger the expected behaviour, it works only for calls from 'outside' of a bean, that is, the proxy object wrapped around your bean.
What getA() does in this case is a local call, so technically your thread jumps directly to method getB(), but it doesn't regard any annotations at all.
I think the only possible solution I can think of is to also add a #PostFilter annotation to the getA method.
This is because annotations works by creating a proxy object around the class instance there for adding and advice that handles the expressions (in this case after the method has been called) This is a aspect oriented trick but when you call a method from within the same instance the advice that was created is never called, that's why it doesn't work that way.
Related
In Spring DI, declaring an autowired field as Optional enables a client to not inject any value to it. Is this possible using Java EE's CDI? I tried Optional and it fails. I want to know if there is an equivalent mechanism I can use.
Here is what I tried:
public class OmeletteMaker implements EggMaker{
public static void main(String[] args){
WeldContainer container = new Weld().initialize();
OmeletteMaker omeletteMaker = container.instance().select(OmeletteMaker.class).get();
}
#Inject
Optional<Vegetable> vegetable;
}
I get an error message:
Exception in thread "main" org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [Optional] with qualifiers [#Default] at injection point [[BackedAnnotatedField] #Inject cafeteria.OmeletteMaker.vegetable]
There are many questions lurking in this seemingly simple question. I'll try to answer them bearing in mind the spirit of the question.
First, as a general rule, if you #Inject a Fred, that Fred cannot be null unless Fred is in #Dependent scope, and even then a producer method or custom bean will have to explicitly be written to return null. There are edge cases but in all modern CDI implementations this is a good rule of thumb to bear in mind.
Second, Optional isn't special. From the standpoint of CDI, an Optional is just another Java object, so see my first statement above. If you have something that produces an Optional (like a producer method) then it cannot make a null Optional (unless, again, the production is defined to be in the #Dependent scope—and if you were writing such a method to make Optional instances and returning null you are definitely going to confuse your users). If you are in control of producing Optional instances, then you can make them any way you like.
Third, in case you want to test to see if there is a managed bean or a producer of some kind for a Fred, you can, as one of the comments on your question indicates, inject a Provider<Fred> or an Instance<Fred>. These are "made" by the container automatically: you don't have to write anything special to produce them yourself. A Provider<Fred> is an accessor of Fred instances and does not attempt to acquire an instance until its get() method is called.
An Instance is a Provider and an Iterable of all known Freds and can additionally tell you whether (a) it is "unsatisfied"—there are no producers of Fred at all—and (b) it is "resolvable"—i.e. there is exactly one producer of Fred.
Fourth, the common idiom in cases where you want to see if something is there is to inject an Instance parameterized with the type you want, and then check its isResolvable() method. If that returns true, then you can call its get() method and trust that its return value will be non-null (assuming the thing it makes is not in #Dependent scope).
I hope this is helpful!
Let's admit I want to map an object A to an object B with Orika.
One field of the object B is constructed by a call to an external webservice with a parameter I have in object A.
Is it a good practice to create an Orika custom-mapper which uses a service that makes a call to an external service, or should I separate this behaviour in an external class ?
External service
^
|
[A]-----> Custom Mapper ------> [B]
Custom mappers in Orika can be regular Spring Beans there is already a lot of example on how to create Spring based Orika mapper
Take a look of this example:
https://github.com/dlizarra/orika-spring-integration
UPDATE
Yes absolutely.
In my data access layer I have a repository hierarchy that looks like this:
<TEntity>
IEntityRepository<---------+ICustomerRepository
^ ^
| |
| |
| |
+ |
<TEntity> +
EntityRepository<----------+CustomerRepository
The IEntityRepository<TEntity> interface defines basic CRUD operations that will be useful regardless of entity type. EntityRepository<TEntity> is a concrete implementation of these operations.
In addition, there are repository types for operations that are specific to a particular entity. In the example above, I have a Customer entity, and the ICustomerRepository interface defines operations such as GetByPhoneNumber. The ICustomerRepository also derives from IEntityRepository<Customer>, so that the common CRUD operations will also be available for an instance of ICustomerRepository. Finally, CustomerRepository is the concrete implementation for the ICustomerRepository operations, and it also inherits from EntityRepository<Customer> for the common operations implementation.
So, going over to my actual question: I use Simple Injector to inject instances into my application. I register each of the specialized repository types in my container: CustomerRepository as the implementation of ICustomerRepository and so on.
To ensure new entity types can be added to the system and used without needing to create a new, concrete repository implementation as well, I would like to be able to serve the base EntityRepository<> implementation when an IEntityRepository<> of the new entity is requested. I've understood I can use the RegisterOpenGeneric method for this.
What I can't figure out is, when a generic repository is requested, how can I serve the specialized repository for that type if it exists, and the generic repository only as a fallback?
For example, let's say I do this in my application:
container.Register<ICustomerRepository, CustomerRepository>();
container.RegisterOpenGeneric(typeof(IEntityRepository<>), typeof(EntityRepository<>));
Most of the classes relying on repositories would request the ICustomerRepositorydirectly. However, there could be a class in my application requesting the base interface, like this:
public ContractValidator(IEntityRepository<Customer> customerRepository,
IEntityRepository<Contract> contractRepository)
{
...
What happens in the example above is:
customerRepository gets an instance of EntityRepository<Customer>
contractRepository gets an instance of EntityRepository<Contract>
What I want to happen is:
customerRepository gets an instance of CustomerRepository
contractRepository gets an instance of EntityRepository<Contract>
Is there any way to inform Simple Injector's resolution that if a derivation of a particular interface exists, this should be served instead? So for IDerived : IBase, requests for IBase should return an implementation of IDerived if it exists. And I don't want this resolution across the board, just for these repositories. Can it be done in a reasonable way, or would I need to manually iterate through all the registrations in the RegisterOpenGeneric predicate and check manually?
Assuming your classes look like this
public class CustomerRepository :
ICustomerRepository,
IEntityRepository<Customer> { }
You can register all the generic implementations of IEntityRepository<> using RegisterManyForOpenGeneric and the fallback registration stays the same.
UPDATE: Updated with v3 syntax
// Simple Injector v3.x
container.Register<ICustomerRepository, CustomerRepository>();
container.Register(
typeof(IEntityRepository<>),
new[] { typeof(IEntityRepository<>).Assembly });
container.RegisterConditional(
typeof(IEntityRepository<>),
typeof(EntityRepository<>),
c => !c.Handled);
// Simple Injector v2.x
container.Register<ICustomerRepository, CustomerRepository>();
container.RegisterManyForOpenGeneric(
typeof(IEntityRepository<>),
new[] { typeof(IEntityRepository<>).Assembly });
container.RegisterOpenGeneric(
typeof(IEntityRepository<>),
typeof(EntityRepository<>));
But you should note that if you use any lifestyle then these separate registrations may not resolve as you would expect. This is known as a torn lifestyle.
You can't use RegisterOpenGeneric or RegisterManyForOpenGeneric for this. You will have to hand-write some code to reflect over the type system and find the implementations to register by their specific interface.
In my opinion however you should not have custom repository. These one-to-obe mappings are cause you these grief and besides, you are violating the SOLID principles by doing so. If you can, consider a design as described here.
I have a problem where isDirty isn't recognizing that an object has changed, even though I can see very clearly via a debugger that it has. I'd like to take a look at the source, but I can't seem to track the source down, and the debugger won't step into it (I assume because it's handled through some sort of AST magic).
I checked out git-core, but "find . -type f | xargs grep -il isDirty" yields no results.
Where can I track this code down?
The ASTs wire in the methods from GormInstanceApi (and GormStaticApi, GormValidationApi, etc.) and individual GORM implementations may subclass those (currently only the Hibernate implementations do).
For example, the Hibernate 3 implementation is here and the Hibernate 4 implementation is in class of the same name in the grails-datastore-gorm-hibernate4 project (most of the Hibernate code is in the grails-datastore-gorm-hibernate-core project, but due to changed interfaces some is in the two top-level projects).
I'm trying to create a generic function in grails that will allow me to specify a class and function name, and intercept any function calls based on that criteria:
getSomeClass().metaClass.invokeMethod = { String methodName, args ->
MetaMethod someAction = getSomeClass().metaClass.getMetaMethod(methodName, args)
def result = someAction.invoke(delegate, args)
if (methodName==getSomeMethodName())
intercept(args, result)
return result
}
This works for POGO, and domain classes, but does not seem to work for controller classes. While I'm fully aware there are Controller interceptors and filters available in Grails, these don't really centralise what I'm trying to achieve, and was trying to create a simple generic function for some centralised behaviour
Any guidance on why this doesn't work on Controllers would be appreciated, thanks
Your approach will work for method calls that are made through the Groovy metaclass mechanism, but in Grails 2 this doesn't apply to controller actions - they're called using normal Java reflection (java.lang.reflect.Method.invoke), and therefore your custom invokeMethod is bypassed.
If you want an AOP mechanism that'll work for calls from Java as well as from Groovy you'll probably have to use something like AspectJ load-time weaving. Spring's proxy-based AOP may work but the Grails 2 controller system relies on the action methods having a particular #Action annotation (which is added at compile time by an AST transformation) and I don't know whether Spring AOP proxies preserve method annotations from the target class on the generated proxy methods.
Could it be that MyController.metaClass.invokeMethod is overwritten by the grails framework after your definition?
Have you tried to check the content of MyController.metaClass.invokeMethod through reflection?