No qualifying bean of type 'org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder' available - sql-server

In Java project, I am using Sprig Boot 1.5.3.RELEASE. It is connecting with two databases i.e. MongoDB and Microsoft SQLServer. When I run it with spring-boot:run goal, it works fine. However, when I try to run it with package goal then below error is reported by test cases despite the fact that those test cases are not connecting to SQL Server database:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1486)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:467)
.....
.....
MediationTest.java (Java class containing test cases generating above error)
#RunWith(SpringRunner.class)
#DataMongoTest(excludeAutoConfiguration = EmbeddedMongoAutoConfiguration.class)
#SpringBootTest(classes = { Application.class })
public class MediationTest {
#Autowired
private SwiftFormat swiftFormat;
......................
......................
MsqlDbConfig.java
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(entityManagerFactoryRef = "msqlEntityManagerFactory", transactionManagerRef = "msqlTransactionManager", basePackages = { "com.msql.data" })
public class MsqlDbConfig {
#Bean(name = "msqlDataSource")
#ConfigurationProperties(prefix = "msql.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
#Bean(name = "msqlEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean msqlEntityManagerFactory(
EntityManagerFactoryBuilder builder,
#Qualifier("msqlDataSource") DataSource dataSource) {
return builder.dataSource(dataSource)
.packages("com.utils.msql.info")
.persistenceUnit("msql").build();
}
#Bean(name = "msqlTransactionManager")
public PlatformTransactionManager msqlTransactionManager(
#Qualifier("msqlEntityManagerFactory") EntityManagerFactory msqlEntityManagerFactory) {
return new JpaTransactionManager(msqlEntityManagerFactory);
}
}
application.properties
spring.data.mongodb.uri=mongodb://dev-abc-123:27017/db
msql.datasource.url=jdbc:sqlserver://ABC-SQL14-WXX;databaseName=dev
msql.datasource.username=dev
msql.datasource.password=*****
msql.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
msql.jpa.hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.EJB3NamingStrategy
spring.jpa.show-sql=true

The spring-boot:run goal is defined by the Mojo included within the spring-boot-maven-plugin project. You can find it here. https://github.com/spring-projects/spring-boot/blob/8e3baf3130220a331d540cb07e1aca263b721b38/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RunMojo.java.
The requiresDependencyResolution scope is set to Test. This will include the dependencies from each phase on the classpath. Take a look at the specification here. https://maven.apache.org/developers/mojo-api-specification.html
The package goal provided by Maven wouldn't include these additional dependencies on the classpath and I believe that is the cause of your issues.
Spring Boot provides a repackage goal which is what should be used for building out executable spring-boot applications.
However, to get more to the point. I think if you update your test to exclude an additional class it might fix your problem.
#DataMongoTest(excludeAutoConfiguration = {EmbeddedMongoAutoConfiguration.class, HibernateJpaAutoConfiguration.class})

Related

Camel route with Spring Batch: No JobLauncher

I'm deploying a Spring Batch job triggered by a Camel route. Here is the Spring Batch config:
#Configuration
#EnableBatchProcessing
public class JobConfig
{
...
#Bean(name = "personJob")
public Job personJob(JobCompletionNotificationListener personListener, Step personStep)
{
return jobBuilderFactory
.get(...)
.incrementer(new RunIdIncrementer())
.listener(...)
.flow(...)
.end()
.build();
}
...
The Camel route looks like this:
#ApplicationScoped
public class MyRouteBuilder extends RouteBuilder
{
#Override
public void configure() throws Exception
{
from("file://...")
...
.to("spring-batch:personJob?jobLauncherRef=jobLauncher");
}
Running the route above raises the following exception:
[ERROR] Caused by: org.apache.camel.ResolveEndpointFailedException: Failed to resolve endpoint: spring-batch://personJob?jobLauncherRef=jobLauncher due to: No JobLauncher named jobLauncher found in the registry.
[ERROR] Caused by: java.lang.IllegalStateException: No JobLauncher named jobLauncher found in the registry."}}}}
However, the documentation clearly states:
The #EnableBatchProcessing works similarly to the other #Enable*
annotations in the Spring family. In this case, #EnableBatchProcessing
provides a base configuration for building batch jobs. Within this
base configuration, an instance of StepScope is created in addition to
a number of beans made available to be autowired:
JobRepository: bean name "jobRepository"
JobLauncher: bean name "jobLauncher"
...
So, there should be a bean named "jobLauncher" of the type JobLauncher. Why isn't it found in the registry ?
Many thanks in advance,
Seymour

Flyway Core with Spring Boot gives error Circular depends-on relationship between 'delayedFlywayInitializer' and 'entityManagerFactory'

I want to import some data on the SQL server database, I'm using Spring Boot 2.3.4. I use also Hibernate to generate the tables.
I added flyway core in pom:
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
Created the configuration file:
import org.flywaydb.core.Flyway;
import org.springframework.boot.autoconfigure.flyway.FlywayMigrationInitializer;
import org.springframework.boot.autoconfigure.flyway.FlywayMigrationStrategy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
#Configuration
public class FlyWayConfiguration {
#Bean
FlywayMigrationInitializer flywayInitializer(Flyway flyway) {
return new FlywayMigrationInitializer(flyway, (f) ->{} );
}
#Bean
#DependsOn("entityManagerFactory")
FlywayMigrationInitializer delayedFlywayInitializer(Flyway flyway) {
return new FlywayMigrationInitializer(flyway, new FlywayMigrationStrategy() {
#Override
public void migrate(Flyway flyway) {
flyway.migrate();
}
});
}
}
I created a file on resources/db/migration/V1_0_1__InitialData.sql
Now I'm having this error
Error creating bean with name 'delayedFlywayInitializer' defined in class path resource
[com/ikun/mkj/config/MigrationConfiguration.class]: Circular depends-on relationship between
'delayedFlywayInitializer' and 'entityManagerFactory' at
org.springframework.beans.factory.support.AbstractBeanFactory
I don't know how to fix this, I searched for solution but couldn't make.
Can someone help me please?
Most likely u are deferring the Datasource initializing by adding :
spring.jpa.defer-datasource-initialization =true #set it to false
in your application.[yml/properties].
Removing it, or setting to false could fix your issue
as in the reference :
https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html
set spring.jpa.defer-datasource-initialization to true. This will
defer data source initialization until after any EntityManagerFactory
beans have been created and initialized. schema.sql can then be used
to make additions to any schema creation performed by Hibernate and
data.sql can be used to populate it.
And by default Flyway depends on Datasource , Datasource in defer mode will wait for EntityManagerFactory
and Ofc since we use flyway the default is to start Flyway before Jpa to ensure DB consistency
So we have a circular Dependency flyway->DS->EMF->Flyway

FailedToStartRouteException exception while using camel-spring-boot, amqp and kafka starters with SpringBoot, unable to find connectionFactory bean

I am creating an application using Apache Camel to transfer messages from AMQP to Kafka. Code can also be seen here - https://github.com/prashantbhardwaj/qpid-to-kafka-using-camel
I thought of creating it as standalone SpringBoot app using spring, amqp and kafka starters. Created a route like
#Component
public class QpidToKafkaRoute extends RouteBuilder {
public void configure() throws Exception {
from("amqp:queue:destinationName")
.to("kafka:topic");
}
}
And SpringBoot application configuration is
#SpringBootApplication
public class CamelSpringJmsKafkaApplication {
public static void main(String[] args) {
SpringApplication.run(CamelSpringJmsKafkaApplication.class, args);
}
#Bean
public JmsConnectionFactory jmsConnectionFactory(#Value("${qpidUser}") String qpidUser, #Value("${qpidPassword}") String qpidPassword, #Value("${qpidBrokerUrl}") String qpidBrokerUrl) {
JmsConnectionFactory jmsConnectionFactory = new JmsConnectionFactory(qpidPassword, qpidPassword, qpidBrokerUrl);
return jmsConnectionFactory;
}
#Bean
#Primary
public CachingConnectionFactory jmsCachingConnectionFactory(JmsConnectionFactory jmsConnectionFactory) {
CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory(jmsConnectionFactory);
return cachingConnectionFactory;
}
jmsConnectionFactory bean which is created using Spring Bean annotation should be picked by amqp starter and should be injected into the route. But it is not happening. When I started this application, I got following exception -
org.apache.camel.FailedToStartRouteException: Failed to start route route1 because of Route(route1)[From[amqp:queue:destinationName] -> [To[kafka:.
Caused by: java.lang.IllegalArgumentException: connectionFactory must be specified
If I am not wrong connectionFactory should be created automatically if I pass right properties in application.properties file.
My application.properties file looks like :
camel.springboot.main-run-controller = true
camel.component.amqp.enabled = true
camel.component.amqp.connection-factory = jmsCachingConnectionFactory
camel.component.amqp.async-consumer = true
camel.component.amqp.concurrent-consumers = 1
camel.component.amqp.map-jms-message = true
camel.component.amqp.test-connection-on-startup = true
camel.component.kafka.brokers = localhost:9092
qpidBrokerUrl = amqp://localhost:5672?jms.username=guest&jms.password=guest&jms.clientID=clientid2&amqp.vhost=default
qpidUser = guest
qpidPassword = guest
Could you please help suggest why during autoconfiguring connectionFactory object is not being used? When I debug this code, I can clearly see that connectionFactory bean is getting created.
I can even see one more log line -
CamelContext has only been running for less than a second. If you intend to run Camel for a longer time then you can set the property camel.springboot.main-run-controller=true in application.properties or add spring-boot-starter-web JAR to the classpath.
however if you see my application.properties file, required property is present at the very first line.
One more log line, I can see at the beginning of application startup -
[main] trationDelegate$BeanPostProcessorChecker : Bean 'org.apache.camel.spring.boot.CamelAutoConfiguration' of type [org.apache.camel.spring.boot.CamelAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
Is this log line suggesting anything?
Note - One interesting fact that exactly same code was running fine last night, just restarted my desktop and there is not even a single word changed and now it is throwing exception.
This just refers to an interface
camel.component.amqp.connection-factory = javax.jms.ConnectionFactory
Instead it should refer to an existing factory instance, such as
camel.component.amqp.connection-factory = #myFactory
Which you can setup via spring boot #Bean annotation style.

Database name containd dot in jdbc url spring boot

Dear all I am in the unfortunate sitution to connect to an sqlserver 2005 databae that was provided to me and contains o dot (.)
I have setup a configuration for spring boot like
#Configuration
public class CustomConfig {
#Bean
#Primary
public DataSource dataSource() {
return DataSourceBuilder
.create()
.username("myuname")
.password("mypass")
.url("jdbc:sqlserver://10.10.10.10:1433;databaseName=REALLY_BAD_NAME_V3.5;")
.driverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver")
.build();
}
}
And of course I get an exception stating com.microsoft.sqlserver.jdbc.SQLServerException: Database '5' does not exist. Make sure that the name is entered correctly.
I have tried in vain the following
.url("jdbc:sqlserver://10.10.10.10:1433;databaseName={REALLY_BAD_NAME_V3.5};")
that gives the same error and
.url("jdbc:sqlserver://10.10.10.10:1433;databaseName=REALLY_BAD_NAME_V3{.}5;")
And gives a malformed url exception after reading these instructions.
Any ideas?

Google App Engine Entity Relationship Annotations end up HTTP 500

I am creating a simple REST API via Google app engine. I have Task and Project objects. A Project can have one or more Tasks. Here is some details about these data objects:
#Entity
public class Project implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Key id;
private String title;
private String description;
private Date createdAt;
// Section 1
// #OneToMany(mappedBy = "project")
// private List<Task> tasks;
// ...
}
#Entity
public class Task implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Key id;
private String shortDescription;
private String longDescription;
private Date createdAt;
private Date dueDate;
private boolean completed;
// Section 2
// #ManyToOne
// #JoinColumn(name = "id_project")
// private Project project;
// ...
}
The way I implemented the class above works fine (Section 1 and Section 2 are commented out). However, what I want to do is to relate Task objects to Project. Whenever I remove the comments above and activate Section 1 and Section 2 the errors below occur.
The error appears for Project operations
HTTP ERROR 500
Problem accessing /api/project. Reason:
Could not initialize class com.aspect.todo.dao.EMFService
Caused by:
java.lang.NoClassDefFoundError: Could not initialize class com.aspect.todo.dao.EMFService
at com.aspect.todo.dao.Dao.getProjects(Dao.java:144)
at com.aspect.todo.server.ProjectService.get(ProjectService.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
...
The error appears for Task operations
HTTP ERROR 500
Problem accessing /api/task. Reason:
INTERNAL_SERVER_ERROR
Caused by:
java.lang.ExceptionInInitializerError
at com.aspect.todo.dao.Dao.getTasks(Dao.java:98)
at com.aspect.todo.server.TaskService.get(TaskService.java:24)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
...
Caused by:
javax.persistence.PersistenceException: Provider error. Provider: org.datanucleus.store.appengine.jpa.DatastorePersistenceProvider
at javax.persistence.Persistence.createFactory(Persistence.java:176)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:112)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:66
...
Caused by:
Errors were encountered when initialising the specified MetaData. See the nested exceptions for details
org.datanucleus.exceptions.NucleusUserException: Errors were encountered when initialising the specified MetaData. See the nested exceptions for details
at org.datanucleus.metadata.MetaDataManager.initialiseFileMetaDataForUse(MetaDataManager.java:892)
at org.datanucleus.metadata.MetaDataManager.loadPersistenceUnit(MetaDataManager.java:794)
at org.datanucleus.jpa.EntityManagerFactoryImpl.initialisePMF(EntityManagerFactoryImpl.java:488)
...
Caused by:
Found Meta-Data for class com.aspect.todo.model.Task but this class is not enhanced!! Please enhance the class before running DataNucleus.
org.datanucleus.exceptions.NucleusUserException: Found Meta-Data for class com.aspect.todo.model.Task but this class is not enhanced!! Please enhance the class before running DataNucleus.
at org.datanucleus.metadata.MetaDataManager.initialiseClassMetaData(MetaDataManager.java:2225)
at org.datanucleus.metadata.MetaDataManager.initialiseFileMetaData(MetaDataManager.java:2176)
at org.datanucleus.metadata.MetaDataManager.initialiseFileMetaDataForUse(MetaDataManager.java:881)
...
The weird thing is when I start with these sections commented out, compile and run and then activate only Section 2 and rerun it works fine. If close and reopen Eclipse try again the error occurs again.
NOTE: Datanucleus JDO/JPA version: v1
Found Meta-Data for class com.aspect.todo.model.Task but this class is not enhanced!!
Please enhance the class before running DataNucleus.
The fact is that the classes are not enhanced at runtime and you have to find a way to enhance them prior to runtime that works for your environment ... Maven, Ant, command-line, DataNucleus Eclipse plugin, or GAE Eclipse plugin.
If you are using ANT then add the below lines in your build.xml before </project> tag close
<target name="datanucleusenhance" depends="compile"
description="Performs JDO enhancement on compiled data classes.">
<enhance_war war="war" />
And give the following command when build the ant "ant datanucleusenhance runserver"
Hope this is useful, it took me a while to find the solution.
Just upgrade your GAE SDK, it solved the problem for me.
Found Meta-Data for class com.aspect.todo.model.Task but this class is not enhanced!!
Please enhance the class before running DataNucleus.
I'll show here a way to enhance classes in Gradle environment. Use the following configuration.
Dependencies:
dependencies {
appengineSdk 'com.google.appengine:appengine-java-sdk:<version>'
compile 'org.datanucleus:datanucleus-enhancer:<version>'
compile 'org.datanucleus:datanucleus-api-jpa:<version>' // or datanucleus-api-jdo
/* other dependencies */
}
Plugin:
(for gradle-appengine-plugin version 1.9.5 or higher)
appengine {
enhancer {
version = "v2"
api = "jpa" // or "jdo"
enhanceOnBuild = true
}
/*...*/
}
(for older versions of gradle-appengine-plugin)
appengine {
enhancerVersion = "v2"
}
To make enhance run automatically before creating the war in your build.gradle file:
war.dependsOn appengineEnhance
If you have problems executing task :appengineEnhance, try to run it with --stacktrace (to view the stacktrace) or --info (to find the location of the error log file) options.

Resources