I am working on a Java Rest Service with Spring MVC (4.2.0.RELEASE) including a Neo4j database. Therefore Spring Data Neo4j (4.1.1.RELEASE) is used.
The SDN configuration looks like this:
#Configuration
#ComponentScan(basePackages = { "com.xxx.yyy" })
#EnableNeo4jRepositories(basePackages = "com.xxx.yyy.dao.repo")
#EnableTransactionManagement
public class Neo4jConfig extends Neo4jConfiguration {
#Autowired
private ApplicationProperties properties;
#Bean
public SessionFactory getSessionFactory() {
return new SessionFactory(getConfiguration(), "com.xxx.yyy.dao.beans");
}
#Bean
public Neo4jOperations neo4jTemplate() throws Exception {
return new Neo4jTemplate(getSession());
}
#Bean
public org.neo4j.ogm.config.Configuration getConfiguration() {
org.neo4j.ogm.config.Configuration config = new org.neo4j.ogm.config.Configuration();
config.driverConfiguration().setDriverClassName(this.properties.getNeo4jDriver())
.setURI(this.properties.getNeo4jEndpoint())
.setCredentials(this.properties.getNeo4jUser(), this.properties.getNeo4jPassword());
return config;
}
#Bean
#Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public Session getSession() throws Exception {
return super.getSession();
}
}
The application is deployed on a Tomcat7 in production environment. Everything works like a charm if there is only one version of the application deployed and the version flag is not filled in.
For a zero downtime deployment I want to use the version flag on the tomcat to deploy multiple versions. If I do so the application is not working anymore because of a NullPointerException in the org.neo4j.ogm.context.RestModelMapper.
Stacktrace:
java.lang.NullPointerException
at org.neo4j.ogm.context.RestModelMapper.mapEntity(RestModelMapper.java:153) ~[neo4j-ogm-core-2.0.1.jar:?]
at org.neo4j.ogm.context.RestModelMapper.map(RestModelMapper.java:76) ~[neo4j-ogm-core-2.0.1.jar:?]
at org.neo4j.ogm.session.delegates.ExecuteQueriesDelegate.query(ExecuteQueriesDelegate.java:94) ~[neo4j-ogm-core-2.0.1.jar:?]
at org.neo4j.ogm.session.delegates.ExecuteQueriesDelegate.query(ExecuteQueriesDelegate.java:73) ~[neo4j-ogm-core-2.0.1.jar:?]
at org.neo4j.ogm.session.Neo4jSession.query(Neo4jSession.java:313) ~[neo4j-ogm-core-2.0.1.jar:?]
This problem occurs only if I use the version flag on tomcat. Does anyboby know what is the problem here?
I finally solved this issue by changing the version of the OGM HTTP Driver and the Spring Data Neo4j dependency.
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-http-driver</artifactId>
<version>2.0.5</version>
</dependency>
With this settings the deployment with the Tomcat version flag https://tomcat.apache.org/tomcat-7.0-doc/config/context.html is now working.
Related
I'm trying to create integration tests for my Spring Boot app. The idea is to launch an embedded postgres db and run http calls with TestRestTemplate to my controllers.
The problem is my project has a dependency we use for redis queues.
<dependency>
<groupId>com.github.sonus21</groupId>
<artifactId>rqueue-spring-boot-starter</artifactId>
<version>2.9.0-RELEASE</version>
</dependency>
I've tried to mock out the dependencies and most of them work, but with this one it complains I guess because it is a #Configuration not a #Component:
Dependency config class:
#Configuration
#AutoConfigureAfter({RedisAutoConfiguration.class})
#ComponentScan({"com.github.sonus21.rqueue.web", "com.github.sonus21.rqueue.dao"})
public class RqueueListenerAutoConfig extends RqueueListenerBaseConfig {
public RqueueListenerAutoConfig() {
}
...
}
My test config class
#TestConfiguration
public class TestRestTemplateConfig {
#Bean
#Primary
#Order(Ordered.HIGHEST_PRECEDENCE)
public RqueueListenerAutoConfig rqueueListenerAutoConfig() {
return Mockito.mock(RqueueListenerAutoConfig.class);
}
....
}
I've tried with #AutoConfigureOrder(1) at my config class but the original RqueueListenerAutoConfig launches before anything and my mocked beans haven't been declared yet.
To be honest mocking every service on that dependency is a pain, but I haven't figured out a way to mock the whole dependency with a single configuration. I tried not loading the dependency when I'm on the test profile but since it runs spring context my code needs it.
My test class has the following config:
#SpringBootTest
#Import(TestRestTemplateConfig.class)
#ActiveProfiles("test")
public class TestClass {
...
}
Any clues?
Thanks.
Try
#EnableAutoConfiguration(exclude=RqueueListenerAutoConfig.class)
I am following https://spring.io/guides/gs/relational-data-access/ so in my main class I have:
#SpringBootApplication
#ComponentScan(basePackages = {"com.example"})
public class SpringGuideApplication implements CommandLineRunner {
private static final Logger log = LoggerFactory.getLogger(SpringGuideApplication.class);
#Autowired
JdbcTemplate jdbcTemplate;
public static void main(String[] args) {
SpringApplication.run(SpringGuideApplication.class, args);
}
#Override
public void run(String... strings) throws Exception {
log.info("Creating tables");
jdbcTemplate.execute("DROP TABLE clients IF EXISTS");
}
}
and at this point I receive error:
***************************
APPLICATION FAILED TO START
***************************
Description:
Field jdbcTemplate in com.example.spring_guide.SpringGuideApplication required a bean of type 'org.springframework.jdbc.core.JdbcTemplate' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'org.springframework.jdbc.core.JdbcTemplate' in your configuration.
Process finished with exit code 1
I understand error but to create #Bean JdbcTemplate I need to use:
#Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
but I don't want, I don't want any dataSource file I would like to have just in memory database. Is there any way to create JdbcTemplate bean without DataSource? Any how is this tutorial even work?
In pom.xml now I have:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
but also tried with
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<version>2.4.0</version>
</dependency>
without success.
That is the beauty of Spring-Boot. It saw you are using JdbcTemplate so it need to create datasource and since you didn't provide any information, it is failing. Even though you are using in memory database you need to provide these info, so spring-boot can create JdbcTemplate for you. I am not sure which in memory db you are using, but here is an example on how to use with H2. You can find these info on individual dB user documentation.
spring.datasource.url=jdbc:h2:mem:yourdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
I want to set up the database connection on Spring MVC with PostgreSQL, how do I do it?
I have tried google search but still, I have not found what I am looking for, so far I have added a PostgreSQL dependency on my project and here are the codes
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4-1206-jdbc42</version>
</dependency>
So where do I go from here?
how do I create the configuration files for db?
What is the default login credentials for db?
Where do I see the database table?
You need to configure your database connection. You can create a classe to configure this. For example:
#Configuration
public class DatabaseConfig {
#Bean
public DriverManagerDataSource getDataSource() {
DriverManagerDataSource bds = new DriverManagerDataSource();
bds.setDriverClassName("org.postgresql.Drive");
bds.setUrl("jdbc:mysql://localhost:5432/dbname");
bds.setUsername("user");
bds.setPassword("pass");
return bds;
}
}
And then, you can inject the datasource in your bens.
#Controller
public class MyController {
#Autowired
private DataSource dataSource;
}
Try to use Spring boot with spring data. Is very simple to configure a database connection and create repositories for data manipulations (CRUD). See this https://dzone.com/articles/spring-boot-with-spring-data-jpa
I'm encountering the following error only when running Test class.
This occurs only with Spring Boot 2 (M3 for now), while it's OK with Spring Boot 1.5.3. MyBatis 1.3.1-SNAPSHOT seems not available/published, so I use 1.3.0.
java.lang.IllegalArgumentException:
Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
Also, no problem so far when launching external Tomcat with JNDI lookup: mappers and beans are loaded fine.
build.gradle
compile("org.mybatis.spring.boot:mybatis-spring-boot-starter:${myBatisBootVersion}")
compile('org.springframework.boot:spring-boot-starter-web') {
exclude module: "spring-boot-starter-tomcat"
}
compile("mysql:mysql-connector-java:6.0.6")
compile("org.springframework.boot:spring-boot-starter-log4j2:${springBootVersion}")
compileOnly("javax.servlet:javax.servlet-api:3.1.0")
testCompile("javax.servlet:javax.servlet-api:3.1.0")
testCompile('org.springframework.boot:spring-boot-starter-test')
testCompile("org.mybatis.spring.boot:mybatis-spring-boot-starter-test:1.3.0")
Application.java
#Configuration
#SpringBootApplication(exclude = JmxAutoConfiguration.class)
#MapperScan("eu.davidea.avocadoserver.persistence.mybatis.mappers")
public class Application extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(final String[] args) {
SpringApplication.run(Application.class, args);
}
}
application.properties
spring.profiles.active=test
application-local.properties (picked up at local deployment)
spring.datasource.jndi-name='java:comp/env/jdbc/avocadoDB'
ApplicationTests.java
#ActiveProfiles("test")
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class ApplicationTests {
#Test
public void contextLoads() {
}
}
application-test.poperties (picked up when launching tests)
spring.datasource.url=jdbc:mysql://...
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=...
spring.datasource.password=...
What's wrong in this configuration for when switching to Spring Boot 2 ?
Project will be available in Github somehow soon.
I found a solution myself:
Since I was using external Tomcat, I removed from the classpath the Hikari conn pool because not used, but during JUnit test phase a JDBC connection pool was missing, so I put it back.
I'm trying to create a SpringBoot application which uses solr repositories. I'm following this tutorial:
http://docs.spring.io/spring-data/solr/docs/current/reference/html/#solr.repositories
which says to configure my application with the following class (Example 43):
#Configuration
#EnableSolrRepositories
class ApplicationConfig {
#Bean
public SolrClient solrClient() {
EmbeddedSolrServerFactory factory = new EmbeddedSolrServerFactory("classpath:com/acme/solr");
return factory.getSolrServer(); // getSolrServer does not exist
}
#Bean
public SolrOperations solrTemplate() {
return new SolrTemplate(solrClient());
}
}
The problem is if I do that it doesn't recognise getSolrServer() as a method of factory. Indeed, if you look at the most recent API for EmbeddedSolrServerFactory you don't find that method, but it apparently existed in a previous version of the same class.
Maybe it was renamed from getSolrServer to getSolrClient, for some reason, from one version to another.
Here's my dependencies in the pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-solr</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Anyway, I tried to change getSolrServer to getSolrClient, but the return type, i.e. SolrClient, is now incompatible. If I try to return org.apache.solr.client.solrj.embedded.EmbeddedSolrServer, it gives me an error because it doesn't find org.apache.solr.client.solrj.embedded...
Another problem using this would be that SolrTemplate doesn't require a EmbeddedSolrServer, so this is not a good option...
I am using eclipse not spring suite, Assuming spring suite using latest version of spring-boot-starter-data-solr ( 1.4.2 ) and you need to add an entry for solr-core 5.x in your pom.
Since EmbeddedSolrServer is extending SolrClient, follows Java IS-A relationship and it should be compatible with SolrClient. This binary is part of solr-core.
Your code need to use getSolrClient itself and it should be compatible with SolrClient
Dependencies in pom.xml is as follows
Here we go with our code base without any errors.
Instead of creating SolrClient bean, create EmbeddedSolrServerFactoryBean object and pass that object to solr template to create SolrTemplate object. Here is my config file:
#Configuration
#EnableSolrRepositories(basePackages = "com.ida.*.repository")
#Profile("dev")
public class SolrConfigDev {
#Autowired
private Environment environment;
#Bean
public EmbeddedSolrServerFactoryBean solrServerFactoryBean() {
EmbeddedSolrServerFactoryBean factory = new EmbeddedSolrServerFactoryBean();
factory.setSolrHome(environment.getRequiredProperty("solr.solr.home"));
return factory;
}
#Bean
public SolrTemplate solrTemplate() throws Exception {
return new SolrTemplate(solrServerFactoryBean().getObject());
}
}
In addition, you have to add solr-core to you pom.xml file.
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-core</artifactId>
<version>5.5.3</version>
</dependency>
More information about this topic, you can find here in this blog by Petri Kainulainen.