instanciating SolrCrudRepository programmatically, without Spring Boot magic - spring-boot

I have a Spring Boot 2.4 project that is using spring-boot-starter-data-solr. Unfortunately, spring-boot-starter-data-solr is not supported anymore (see https://spring.io/projects/spring-data-solr#overview) , so I can't easily upgrade Spring Boot as I usually do for other projects.
However, I thought I would still try to upgrade my project and keep using the latest spring-boot-starter-data-solr I could get : maybe it's not supported anymore, but I am not making an extensive use of it, so maybe I can take advantage of latest Spring Boot features for a some more time, before there's really a breaking change and I really can't use spring-boot-starter-data-solr
So, I upgraded my project to Spring Boot 2.6.4 letting Spring BOM pull all the latest versions of all dependencies managed. Of course, it failed on spring-boot-starter-data-solr, so I had to declare the version explicitly :
implementation 'org.springframework.boot:spring-boot-starter-data-solr:2.4.13'
I fixed few other things, and my project compiles. However, at startup (and in some integration tests), I have a problem :
#Configuration
public class PersistenceConfig {
#Bean
public TicketRepository ticketRepository(SolrTicketEntityRepository solrTicketEntityRepository) {
return new TicketRepositoryImpl(solrTicketEntityRepository);
}
... some other beans..
}
with SolrTicketEntityRepository defined like below :
public interface SolrTicketEntityRepository extends SolrCrudRepository<TicketEntity, String> {
#Query("?0")
Page<TicketEntity> search(String searchText, Pageable pageable);
With Spring Boot 2.6, the SolrTicketEntityRepository doesn't get instanciated anymore, so I have a missing bean at startup. I've tried adding the #EnableSolrRepositories on PersistenceConfig, but it doesn't do anything.
is there a way to mimic Spring Boot magic, and trigger programmatically SolrTicketEntityRepository / SolrCrudRepository instanciation, to be able to start my application ?
or is it way too complicated, and as recommended here , should I implement the stuff myself with the core Solr libraries without Spring Boot's help (which would be the objective at some point anyway) ?

Related

Upgrading from Java Config to Spring Boot

Upgrading an existing system to Spring Boot with Auto config. Currently the system is all Java config. I'm confused over whether to continue the use of #Profile. Is this annotation no longer needed? I searched extensively about upgrading and found only references to non-Spring Java migration and creating new projects.
Typical #Profile usage in our configuration classes looks something like:
#Bean
#Profile("is-standalone")
public Service unsecuredService(SomeApi someApi) {
return new ...
}
I inferred from the Spring Boot examples that using one of the #Conditional annotations is recommended like this:
#Bean
#ConditionalOnProperty("unsecured.enabled")
public Service unsecuredService(SomeApi someApi) {
return new ...
}
Then in a YAML file the is-standalone Profile enables or disables all the various properties for that Profile. Is this the proper way to upgrade? To repeat a question from above differently, can the #Profile usage be left as is? This is for a fairly large project, the upgrade is non-trivial, so I would like to do this only once!
Depends where your previous #Profile annotation is coming from. If you're using Spring's #Profile, the functionality is as follows:
Annotating a class with #Profile("dev") will load the class and register it in the Spring context only when the dev profile is active
Annotating a class with #Profile("!dev") will load the class and register it in the Spring context only when the dev profile is inactive
If this sounds like what you have already, no change is needed.

Using the Grails Cache Plugin on Normal Spring Service Bean

i have some standard Spring #Service classes in a separate jar lib that use the standard #Cacheable Spring annotation, in a Spring boot project i declare the dependency, configure a CacheManager and just works!
i try to do the same in a Grails 3.1 project but with no luck!
i discover that https://github.com/grails-plugins/grails-cache require to use its 'proprietary' #Cacheable annotation:
http://grails-plugins.github.io/grails-cache/3.0.x/api/grails/plugin/cache/Cacheable.html
As workaround i FORKED some Service just to use the Grails #Cacheable and it's working but i'd like to have a single #Service that works under grails or not!
I have misconfigured something, it doesn't behave the same way, but i can't figure out what is it!
i'd like to share this jar lib between spring only & grails projects, but so far i can't make caching work, unless i forked the service calsses under
grails-app/services directory & used 'proprietary' #Cacheable annotation;
i try to remove the plugin and configure the bean and the cache in:
/GPsGrails3/grails-app/init/gpsgrails3/Application.groovy
with the org.springframework.context.annotation.Bean annotation:
#Primary
#Bean
public ConcurrentMapCacheManager concurrentMapCacheManager() {
return new ConcurrentMapCacheManager();
}
#Bean
public SignatureService signatureService() {
SignatureService _signatureService = new SignatureService();
return _signatureService;
}
i put signatureService under grails-app/services directory:
/GPsGrails3/grails-app/services/it/finmatica/ifw/impl/SignatureService.groovy
Maybe i have to configure my beans in:
/GPsGrails3/grails-app/conf/spring/resources.groovy ?
i have to use the version 4 of the plugin?
compile "org.grails.plugins:cache:4.+"
I am not sure what the question is but you don't have to use the Grails #Cacheable annotation. If you want to use the Spring one in a Grails app, you can, and it will behave in the same way that it would if you weren't using Grails. You don't even need the plugin in order to do that.

Injecting spring beans into legacy web app POJOs [duplicate]

This question already has answers here:
Why is my Spring #Autowired field null?
(21 answers)
Closed 7 years ago.
In order to provide POJOs in my legacy web app (Tomcat 8.0.26) with the ability to send ActiveMQ messages I've taken the recommendation to introduce Camel (2.15.2) / Spring (4.2.1) into the app to purely for the purpose of managing pooled MQ connections. I'm hoping there isn't an easier way.
Doing things the Spring way I'm thinking everything would need to be based around an MVC architecture with HTTP servlet aware controllers having access to the servlet context and therefore the Spring context in order to inject beanFactory beans into classes annotated with #Controller and #Service (and in fact there must be a Spring #Controller class that enables Spring to inject the #Service class.
However, as I've stated this is legacy code that will not be using the spring web framework.
After much pain it seems that the only way I can get beanFactory beans injected into my POJOs is to go the AspectJ and Weaving route. Before I go down this road can someone tell me that this is currently the best approach (what I've read describing this solution is from 2011 Can't get Spring to inject my dependencies - Spring Newbie) ? Can you point me to documentation and a working example?
Many thanks.
1) aspectj with #Configurable
In your #Configuration annotated class/es
you can add some more annotations
#Configuration
#EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.ENABLED)
#EnableSpringConfigured
#EnableAspectJAutoProxy
to enable aspectj and the #Configurable annotation,
you need to import the aspectj lib to your project and add the spring tomcat instrumentable java agent in your tomcat lib folder (give a look here, it exaplains how to configure tomcat) http://docs.spring.io/spring-framework/docs/2.5.6/api/org/springframework/instrument/classloading/tomcat/TomcatInstrumentableClassLoader.html
this is not going to help you if you are going to create your pojos using "new"
MyPojo p = new MyPojo(); // no black magic for this, you will need to satisfies the dependencies yourself) but that would be helpful for example when you load some entities through a framework like hibernate and you want to inject something into them.. #Configurable it's an option that can be evaluated in those cases, for what you describe I would rather not use it.
2) You can have some static methods that uses some static set spring-beans and use them from your pojos, something like
class Util{
private static SprintBeanWithJmsSupport x;
public static setSpringBeanToHandleJmsMessages(SprintBeanWithJmsSupport x){
Util.x = x;
}
public static sendJmsMessage(JmsMessage m){
x.sendMessage(m)
}
}
and you can go with Util.sendJmsMessage(...)
this is a bit shitty but it does the work, I don't personally like this approach
3) set your spring beans in your pojo when they need to use them (maybe behind some nice interfaces that suit your domain)
if you go with spring mvc you will likely end up having some controllers that will use some services (generally they handle security / db access and are the entry point to start the "use cases"), as everything wthin these layers is handled by spring it will be very simple to pass the spring-bean to handle jms messaging to your pojos, this seems to me quite a nice way to handle the problem
I went mostly based on memory and something may not be completely accurate, plus my english is .. what it is, so hope this can be helpful anyway.

Does Intellij IDEA support #RooJpaRepository?

IntelliJ 12.1.6 Ultimate, with following plugins enabled :
AspectJ Support
AspectJ Weaver
Spring Support
Spring Data
Spring AOP and #AspectJ
I have a Spring Roo project, which use Spring Data repository API. Following are snippet codes :
Repository class
package my.package;
#RooJpaRepository(domainType = Thing.class)
public interface ThingRepository {
}
Roo generated aspect file
privileged aspect ThingRepository_Roo_Jpa_Repository {
declare parents: ThingRepository extends JpaRepository<Thing, Long>;
declare parents: ThingRepository extends JpaSpecificationExecutor<Thing>;
declare #type: ThingRepository: #Repository;
}
Spring JPA config
<repositories base-package="my.package" />
But in xml file, IntelliJ told me
So whenever I use method like find/save in IntelliJ, it will be marked as "Cannot resolve method"
However, both IntelliJ and Maven compiles without any problem, just the method not resolvable in editor. What could be the problem?
Bad news, I think you must wait for that functionality. See this:
http://youtrack.jetbrains.com/issue/IDEA-59138
In short: Nowadays Intellij doesn't support AspectJ declare parents nor declare precedence
Intellij developers have been playing around with this feature since Intellij 11 (See the comments about No technical block, just lack of resources)
The issue is marked to be resolved on Intellij 14. How long is that? See that Intellij 13.1 is planned to be released on Q2 of 2014, so it will take a while.

Should I use Spring or Guice for a Tomcat/Wicket/Hibernate project?

I'm building a new web application that uses Linux, Apache, Tomcat, Wicket, JPA/Hibernate, and MySQL. My primary need is Dependency Injection, which both Spring and Guice can do well. I think I need transaction support that would come with Spring and JTA but I'm not sure.
The site will probably have about 20 pages and I'm not expect huge traffic.
Should I use Spring or Guice?
Feel free to ask and followup questions and I'll do my best to update this.
If you like the "do-it-all-in-Java" philosophy that Wicket follows, then you might prefer Guice over Spring. There is no XML configuration in Guice - it is all done using the Guice Module class.
For example, your Wicket WebApplication class might look something like this:
public class SampleApplication extends WebApplication
{
#Override
protected void init()
{
addComponentInstantiationListener(
new GuiceComponentInjector(this, new GuiceModule()));
}
}
The GuiceComponentInjector comes from the wicket-guice extension. Here's the Module:
public class GuiceModule extends AbstractModule
{
#Override
protected void configure()
{
// Business object bindings go here.
bind(Greetings.class).to(GreetingRepository.class);
}
}
In this example, Greetings is an interface implemented by a concrete GreetingRepository class. When Guice needs to inject a Greetings object, it will satisfy the dependency with a GreetingRepository.
I have put together a sample project that demonstrates how to build a Wicket/Guice application for Google App Engine. You can safely ignore the App Engine specifics and focus on how the Wicket-Guice integration works.
If you do end up going with Guice, definitely check out Warp Persist for Hibernate, Guice Servlet for Tomcat, and wicket-guice for Wicket.
Spring would probably give you more flexibility, but if you just need DI then Guice may be a better choice.
It is difficult to answer as Spring has so many features that would make the DAO more flexible, and works well with Hibernate. It would help if you had more requirements for what you are looking for.
Here are a couple of comparisons between Spring and Guice and Spring, Guice and Picocontainer.
http://code.google.com/p/google-guice/wiki/SpringComparison
http://www.christianschenk.org/blog/comparison-between-guice-picocontainer-and-spring/
Don't forget CDI/JSR-299, part of Java EE 6. You can use weld-wicket to integrate wicket with CDI.
(as long as you're using the weld implementation (as GlassFish v3 and JBoss 6 do), but the weld-wicket is rather small so you could probably adapt it if needed).
I managed to get Wicket 1.4 + weld-wicket + wicket-contrib-javaee + EJB 3.1 + JPA 2.0 + wicket-security (SWARM) + Spring Security 3 + Spring 3 running together in a small proof of concept application. That's a bit too many frameworks though, will probably drop spring-security & spring as they appear redundant.

Resources