Disable transaction manager in Spring Boot application - java

How to disable transaction manager in Spring Boot application?
I have this exception :
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.transaction.PlatformTransactionManager] is defined
Because of #Transactional annotations (I use these annotations in an other app, so I can't remove, but there is a way to ignore it? By disable transaction manager?).

I guess you have three choices:
remove the annotation
supply a transaction manager
exclude the configuration class that adds #EnableTransactionManagement
In a Spring Boot app you only get #EnableTransactionManagement if you are using JDBC or JPA, so really there should be a transaction manager already. The only reason I can see for one not being there is you have spring-jdbc on the classpath but no database. If you have spring-tx and spring-jdbc on your classpath already (which seems to be the case) you can just add an in-memory database (e.g. h2) to get a transaction manager. That seems like the best solution to me. But you could also exclude DataSourceTransactionManagerAutoConfiguration in your #EnableAutoConfiguration.

Related

How to disable DataSourceHealthIndicator bean in Spring Boot?

I have application with spring-boot-starter-actuator dependency. When I add my error handling library as dependency, application fails to start with the following message
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
After a bit research, I found out the error handling library introduces transitive dependency of spring-boot-starter-data-jpa which in turn causes actuator autoconfiguration to automatically introduce DataSourceHealthIndicator bean. This bean fails on missing database connection, but the application actually doesn't use database at all. However, the logging library requires the JPA dependency at runtime, so I can't exclude it.
I tried to set the following application property: management.health.db.enabled=false, but I still get the same error on startup. I can't find any documentation how to disable DataSourceHealthIndicator bean and leaving other autoconfiguration intact.

Lazy load #EnableCaching class in spring

I want my spring boot server to be up even if my redis cache isnt up.
I am using #EnableCachingannotation , but my server startup fails if redis is down giving me BeanCreationException. Because BeanCreationException cannot be handled , the only option I have is to lazy load my #EnableCaching class.
I tried annotating that class as under:
#Configuration
#EnableCaching
#Lazy
#Profile("dev")
public class RedisCache extends CachingConfigurerSupport {}
But still this bean is getting loaded at server startup and startup therefore fails.
How do I lazy load the above mentioned class
As far as I know Spring configuration is alwasy loaded on application startup, because that is when the ApplicationContext is created.
In order to do what you want you'd either have to create some sort of custom implementation of ApplicationContext (although I honestly cannot think of how it should work regarding the dependency resolution for dependency injection) or create custom wrapper for caching which would not try to establish connection to Redis until the cache is used.
It may also be possible to configure Spring Boot to skip this particular #Configuration class (Using Boot configuration classes) and then to manually create AnnotationConfigApplicationContext and then retrieve Redis connection Beans from this context manually rather than autowiring them.

CGLIB errors converting a weblogic spring web app to springboot app

I am attempting to convert an existing spring weblogic application to a spring boot embedded tomcat application.
There are lots of moving parts so it's hard to show any code, I'm hoping there is some general answer that might clue me in to the issue.
Under weblogic, using the spring-framework 4.3.6.RELEASE libraries, the application deploys fine. It has no problems creating the different service, repository and component beans.
However, when I migrate it to Spring Boot 1.5.1.RELEASE, I get the following error:
2017-06-21 17:08:16,402 [ERROR] SpringApplication reportFailure (815) - Application startup failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'alertEventServiceImpl': Unsatisfied dependency expressed through field 'alertEventDao'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'alertEventDaoImpl' defined in URL [jar:file:/Users/username/Development/source/carma-war/target/carma-war-2.0.0-SNAPSHOT.war!/WEB-INF/lib/protocol-manager-1.8.0-SNAPSHOT.jar!/org/ihc/hwcir/protocol/dao/AlertEventDaoImpl.class]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class org.ihc.hwcir.protocol.dao.AlertEventDaoImpl]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class org.ihc.hwcir.protocol.dao.AlertEventDaoImpl
Many of our service classes are final as they shouldn't be extended. Since there are so many that are final, I wanted to minimize the amount of code in our different libraries that we modify to make this work.
I thought because the bean creation process works under weblogic, it should work under spring boot.
Things I have tried to force not using the cglib proxies:
All implementations implement interfaces already
In beans created via xml, added <aop:scoped-proxy proxy-target-class="false"/>
In beans created through annotations, added (example for service bean)
#Service
#Scope(proxyMode = ScopedProxyMode.INTERFACE)
However, in the end, I'm perplexed as to why spring can create beans (the classes marked as final) under the weblogic container but unable to do so under the embedded tomcat spring-boot container.
Spring Boot by default uses class based proxies, which will not work with final classes/methods.
To disable this add spring.aop.proxy-target-class=false to the application.properties to enable JDK Dynamic Proxies instead of class based proxies. (And revert your modifications).
NOTE: To have everything take into account the spring.aop.proxy-target-class you might need to upgrade to Spring Boot 1.5.3 as some final patches where made to include this property in parts that were missed in previous versions.
See the following issues for more information 8434, 8869 and 8887.
I was unable to make this work using M. Deinums' answer using spring.aop.proxy-target-class=false.
What worked for me was to add in the application.properties file
spring.dao.exceptiontranslation.enabled=false
Please note that this option disables proxy creation for repositories.
And in my spring boot application configurer the annotation to handle transactions without using a proxy class.
#EnableTransactionManagement(proxyTargetClass = false)
This is using Spring Boot version 1.5.1.RELEASE.

jpa:repositories / #EnableJpaRepositories vs #Repository - spring

Does using the #EnableJpaRepositories or jpa:repositories (on the xml) gives the developer not to use #Repository tag of Spring? As I look on the example guidelines of Spring most of their examples is that they do not use the #Repository tag anymore on their interfaces that extends JpaRepository or CrudRepository interface of Spring Data.
I tried to use them together but Intellij warns me that it can not autowired my repository because there is more than one bean. I tried to remove the jpa:repositories on my xml file but the an error appeared that the application can not create a bean for my entity manager.
These are two different things. #Repository annotation is much older than Spring Data and is used to tell Spring to translate all exceptions thrown by #Repository annotated components to DataAccessException (more to read here: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/stereotype/Repository.html)
In SpringData you have #EnableJpaRepositories + entire underlying scanning and repository bean generation mechanism and there is no need to mark your repository interfaces (or custom classes) with #Repository.
The Spring Data Documentation is IMHO not entirely clear about this.
In chapter 3.1.1 it says:
Using the repositories element looks up Spring Data repositories as described in “Creating Repository Instances”. Beyond that, it activates persistence exception translation for all beans annotated with #Repository, to let exceptions being thrown by the JPA persistence providers be converted into Spring’s DataAccessException hierarchy.
To me this sounds like you would still need to add #Repository explicitly in order to activate persistance exception translation.

Autowired Dependency Injection with Spring Security

I have a spring webapp with annotation driven configuration.
All Controllers, Repositories are autowired.
When integrating Spring Security I defined a separate security-app.xml. I created a Service called LoginUserService which implements UserDetailsService. Now the method loadUserByUsername() method of this class gets invoked for authentication.
This class has an autowired dependency for UserRepository. Now this autowired dependency turns out to be null. To fix this I enable annotation driven configuration and add the package name for the repository class in component scan configuration.
This solution is also discussed here
spring security with custom user details
But now the problem is that the UserRepository has an EntityManager field with #PersistenceContext annotation. For the spring security configuration it is able to locate the UserRepository but not able to locate the entity manager. Should I create a new EntityManagerFactory here? I guess that will create two persistence units in my application?
How can I inject an autowired dependency to UserRepository created with the original servlet xml?
Update
This is briefly discussed here:
https://stackoverflow.com/a/7078395/161628
But I guess a canonical detailed answer will be more useful to me.
Update
How about using ApplicationContext to get the UserRepository at runtime?
if (userRepository == null) {
userRepository = ApplicationContextProvider.getApplicatonContext().getBean(UserRepository.class);
}
Why is Spring's ApplicationContext.getBean considered bad?
EDIT: Beans that you declare in your config for your DispatcherServlet are not going to be available to any beans you declare or component scan in your contextConfigLocation config files. So in this case, if you're setting up your JPA config in your config file that you load for your DispatcherServlet there is no way to wire that in to beans your declare in your security config. You need to move any "core" bean config like that (datasource config, db connection pool config, JPA/Hibernate config, repository/service component scanning, etc.) into a config file that you load via the contextConfigLocation. Then that stuff will be available both to your security beans and your MVC beans. I think generally the idea is to only load MVC specific beans in your DispatcherServlet config (e.g. Controllers, views, request handlers, request scoped beans, etc.). That way you ensure you have a clean separation between MVC code and non-MVC code, with only a one-way dependency from the MVC code to the "core" code, and no dependencies on MVC code in your "core" code. This helps make your code more modular, and makes it easier to reuse your "core" code in other ways, specifically in unit tests.
(Original comment text was asking about how the security config is loaded, if it's in the contextConfigLocation or somewhere else.)

Categories

Resources