I want to add custom behavior to single repository as described in 1.4.1 Adding behaviour to single repositories. In this custom behavior I want to use method already present in my base repository (like save() or findOne() method). Ho can I achieve this in Spring data?
I tried extending my UserRepositoryImpl with SimpleJpaRepository to have basic SimpleJpaRepository methods available. But this way I got instantiation problems.
Also using aproach described in 1.4.2 Adding custom behaviour to all repositories doesn't seem like good solution, because it's way too much code for adding one simple method. In this case Spring Data seems more like burden.
Or is it antipatern to add to my repository such simple method which depends on other methods from base repository? Should I rather move this method to service/business layer?
The same question came up a few days ago in this post. As I wrote there as well, I strongly believe this is an antipattern, so my answer to your last question would be a definite yes.
Related
I am contributing some framework and I am integrating it with Spring Boot. I want to create an annotation like #LocalPort that I made to use in testing. 😎
I found #LocalPort to be #Value in the end, but I don't think I can't use it because the annotation I'm making needs to be passed another value. In the end I think I should inherit ContextAnnotationAutowireCandidateResolver and either reimplement the getSuggestedValue(...) method or find another way. But I don't think this is the right way.
Is there another way to implement this? 🤔
For example,
#LocalSomePort(Protocol.HTTP) // Protocol.HTTPS
It was late, but I solved it by adding a custom BeanPostProcessor.
Modern Spring recommendations (Spring 4.x onwards) recommend not using field injection (with #Autowired or #Inject), and instead preferring constructor arguments. Several discussions about this here, here and the Spring Framework itself recommends constructor-based DI for mandatory dependencies.
In general I agree perfectly with the rationale, and in fact I haven't used any of the field injection mechanisms for years now.
What is bugging me however is the way we inject Spring Data Repositories. Of course these are mandatory dependencies, the service needs them to work. When one looks at the Spring Data documentation one finds that the reference documentation itself is using #Autowired field injection all over the place, precisely what was recommended as bad practice in the Spring Framework documentation itself.
Of course, it is no problem to have repositories use constructor injection. I have been using this for quite some time. However, sometimes components and services need quite a number of repositories. A service might be interacting with 7 or 8 database tables, and they would need to be in the same transaction.
How does one go about this to have neat code? Using constructor arguments is the safer approach, but leads you to have a huge number of constructor arguments. Setter injection does not seem to fit, these are not optional dependencies. Field injection is supposed to be plain wrong (even though the Spring Data doc uses it).
Is there any other approach one could use? I was tempted to aggregate related repositories in a separate #Component, at least the service constructor gets only one argument with this constructor. It does help a bit, but makes it even harder to interact with a new table (the new repository would need to be added to the aggregate, and the service would need to call the getter for it).
How is it supposed to be done neatly without violating any safety recommendations and adhering to coding standards (few constructor arguments etc.)?
I have been reading about Spring Boot custom repository. I have dozens of blogs explaining how to implement those but none of them explained scenario when we actually need it?
I mean one example where we cannot live without custom repo. I mean if there is case of complex query, we can anyhow achieve it using #Query.
Please explain.
Lets say I want strongly typed query instead of #Query. I would create a custom repo, autowire EntityManager and use QueryDSL with it so I can use strongly typed references.
You can use it to extend the repository with other libraries that aren't part of Spring.
I find them useful when working with a program generator like jHipster. They keep your code separate from the generated code.
The xxxRepositoryCustom.java xxxRepositoryImpl will not be overwritten when the entities are re-generated by a dumb programmer (me.) The queries themselves have some complex logic that can not be expressed in a simple #Query
For instance, if I open the Spring Framework Reference Documentation and open 5.9.2. #Autowired, I get this explanation: As expected, you can apply the #Autowired annotation to "traditional" setter methods:.
Not very informative. Actually, the explanation assumes prior knowledge given that I'm expected to have certain expectations.
So is there complete reference of annotations somewhere?
DZone had a refcard about Spring Annotations a good while back so its not the most up to date but this might still be useful to you - http://refcardz.dzone.com/refcardz/spring-annotations
You will need to quickly create an account if you dont have one (free by the way) but its worth it for all the other refcards anyway.
I think the official spring documentation is very good but ya you cant just jump into a section like 5.2.9 without prior knowledge of the how the dependency injection framework works etc.
And btw, the refcard was written by Craig Walls who is the author of the Spring in Action book series so you can be confident that the document is correct (albeit dated).
I am looking for an elegant solution to writing methods on DTO's
The problem arises from the fact that methods on a DTO can be used both on the client side and server side. Subsequently problems arise when you make use of any Client or server side specific methods. This generally results in an java.lang.NoClassDefFoundError exception.
The project that I am currently working on uses GWT and spring. I experienced this problem when trying to format an date on a DTO. The format method was throwing an java.lang.NoClassDefFoundError when GWT.create(GlobalConstants.class) was called. I am looking for an elegant way to differentiate if an method is being called from the server side or client side and adapt the implementation of the method accordingly.
First off, if you have such methods, then your object is not just a DTO (by definition, a DTO only has accessors and mutators).
That being said, there are several ways to solve your problem with your objects.
to solve the NoClassDefFoundError, use com.google.gwt.core.shared.GWT instead of
com.google.gwt.core.client.GWT. The shared class is present in both gwt-user.jar and gwt-servlet.jar.
You can use GWT.isClient() to tell whether you're on the client-side or server-side and branch to the appropriate code.
Starting with GWT 2.6, GWT.create() can be used outside of a GWT client-side context, so
you can make it work on the server-side (you have to provide your own ClassInstantiator to com.google.gwt.core.server.ServerGwtBridge.getInstance()#register())
If you have a server-side-specific method that wouldn't even transpile to JavaScript, starting with GWT 2.6, you can annotate it with #GwtIncompatible (any such annotation will work, the package doesn't matter, only the annotation name) and GWT will do as if it isn't there at all.
finally, when none of the above works, you can "fork" your code into a super-source, so as to provide distinct server-specific and client-specific implementations. See “Overriding one package implementation with another” in the GWT documentation.