How to enable H2 Database Server Mode in Spring Boot - java

I'm using a H2 database with a file using Spring Boot.
In my application.properties, I have this entry:
spring.datasource.url=jdbc:h2:file:c:/Testprojekte/spring-boot-h2-db
But now I would like to be able to look at the database while running the application, which currently isn't possible because I need to have the database running in server mode in order to do so. In the documentation I found that I have to add AUTO_SERVER=TRUE to the URL but this doesn't solve the problem.
So, what do I have to change to be able to connect to that database from different processes at the same time ?
thanks for any help!
Thorsten

You can start the H2 TCP server as a bean:
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<!-- <scope>runtime</scope> -->
</dependency>
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Bean(initMethod = "start", destroyMethod = "stop")
public Server h2Server() throws SQLException {
return Server.createTcpServer("-tcp", "-tcpAllowOthers", "-tcpPort", "9092");
}
}
Then connect to it from your IDE with the following params (password - empty):
url: jdbc:h2:tcp://localhost:9092/mem:testdb
user: sa
More info is here and here.

You can enable h2 web console to access your h2 in memory or in file database using a web interface in your browser.
therefor add in application.properties the lines:
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
after that restart your spring boot application and check http://localhost:8080/h2-console with your browser.

Related

Timestamp of restart of spring application

I have a microservice based on spring boot. I have a spring cloud configserver as well in-place. So depending upon the changes in the configserver microservice restart automatically.
So now i need to grab the timestamp when the application got restarted.
Is it possible to do so in the same microservice?
You can listen to spring events such as the ContextStartedEvent. There's a tutorial here that lays it out:
#EventListener
public void handleContextStartedEvent(ContextStartedEvent ctxStartEvt) {
System.out.println("Context Start Event received.");
}
yes, possible by adding the actuator and enabling the startup endpoint.
step1: Add the below dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.5.4</version>
</dependency>
step2: Add the below property into the application.properties files.
management.endpoints.web.exposure.include=startup
step3: Setup a little amount of buffer memory to store the startup info and it won't affect the performance at anywhere in your application.
#SpringBootApplication
public class StartupTrackingApplication {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(StartupTrackingApplication.class);
app.setApplicationStartup(new BufferingApplicationStartup(2048));
app.run(args);
}
}
step: Hit the below URL using CURL like below or a POST call from POSTMAN. Then you will be seeing all startup-related info like when the startup started and ended. e.t.c.
curl 'http://localhost:8080/actuator/startup' -X POST | jq
For more explanation, view reference
In the response json, node "timeline"."startTime" is the exact startup timestamp when the applicant has started its startup job.

Spring Boot app not connecting to the database specified in application.property for Mongodb

I have developer Application in Spring boot and exported the war file and placed it in tomcat 9 server. When I try to test the API in Rest client the app is connecting to test DB instead of the DB which I declared in application.property for mongodb, below is my application.property
Database name.
spring.data.mongodb.database=IndianFarms
Mongo server host.
spring.data.mongodb.host=localhost
Mongo server port.
spring.data.mongodb.port=27017
logging
logging.level.org.springframework.data=debug
logging.level.=error
spring.jackson.default-property-inclusion=NON_NULL
Can any one help me in this.
After lot of search and research in came to know that spring boot auto configure lot of things internally. Declaration in application.properties file is not working.
We have to programmatically do this. Below is how I did it. Now Spring boot is connection to correct database which is in my case IndianFarms. #Smile thanks your suggestion helped me to find out exact cause.
#Configuration
public class MongoConfig {
#Bean
public MongoDbFactory mongoDbFactory() {
MongoClient mongoClient = new MongoClient("127.0.0.1:27017");
return new SimpleMongoDbFactory(mongoClient, "IndianFarms" );
}
#Bean
public MongoTemplate mongoTemplate() {
return new MongoTemplate(mongoDbFactory());
}
}

Spring Boot Test using Neo4j embedded database with JDBC Bolt driver

Is it possible to connect to an embedded Neo4j database the same way you would do with an H2 in-memory database to mock an Oracle database?
I've tried to do this:
final BoltConnector boltConnector = new BoltConnector("bolt");
graphDb = new GraphDatabaseFactory()
.newEmbeddedDatabaseBuilder(DB_PATH)
.setConfig(boltConnector.type, BOLT.name())
.setConfig(boltConnector.enabled, TRUE)
.setConfig(boltConnector.listen_address, listenAddress("127.0.0.1", 7688))
.setConfig(boltConnector.encryption_level, DISABLED.name())
.setConfig(GraphDatabaseSettings.auth_enabled, FALSE)
.newGraphDatabase();
And then make a request using the JDBC Bolt driver with the following spring.datasource configuration:
spring:
profiles: test
datasource:
driver-class-name: org.neo4j.jdbc.bolt.BoltDriver
url: jdbc:neo4j:bolt://127.0.0.1:7688/?nossl
But I always get the following error:
Unable to connect to 127.0.0.1:7688, ensure the database is running and that there is a working network connection to it.
Of course the embedded database works when I use the graphDb instance and execute requests against it. But I want my application to connect to the embedded database as it does when connecting to a remote Neo4j database.
This is for testing purpose.
I finally RTFM...
I had the following dependency in my pom.xml:
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j</artifactId>
<version>3.4.0</version>
</dependency>
Then I found this: https://neo4j.com/docs/java-reference/current/tutorials-java-embedded/#tutorials-java-embedded-bolt
The documentation is a bit outdated because it uses deprecated configuration. But they explain this:
The Neo4j Browser and the official Neo4j Drivers use the Bolt database
protocol to communicate with Neo4j. By default, Neo4j Embedded does
not expose a Bolt connector, but you can enable one. Doing so allows
you to connect the services Neo4j Browser to your embedded instance.
And they make clear the correct dependency to use is:
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-bolt</artifactId>
<version>3.4.0</version>
</dependency>

Spring boot - Rest Call client without embedded tomcat

I have been trying to figure out an issue with spring boot and as i am new to spring I thought of getting some help here.
I have a spring boot based java application which runs as a daemon and makes some GET request to a remote server. (Acts only as a client).
But my spring boot application internally starts an embedded tomcat container.
My understanding is that if the java app acts as a server, it would need tomcat. But my application being only a consumer of remote machine's GET APIs, why would it need an embedded tomcat ?
In my pom file I have specified spring-boot-starter-web,
on assumption that it is needed for even making GET calls.
But after doing some research on disabling embedded tomcat, I found a solution.
To make following changes,
#SpringBootApplication(exclude = {EmbeddedServletContainerAutoConfiguration.class,
WebMvcAutoConfiguration.class})
&
in application.yml
spring:
main:
web-environment: false
With the application.yml changes, my jar is not even getting started, aborts directly, without even logging anything in logback logs.
Now, if i remove the application.yml change, my jar starts (only with first change in #SpringBootApplication anno.) but goes into some exception.
[main] o.s.boot.SpringApplication : Application startup failed
org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
My Doubts here are,
1) Is tomcat, be it standalone or embedded, really needed for a application which just makes GET API calls to remote machine ?
2) How do i overcome this exception and safely remove the embedded tomcat and still perform the GET API calls ?
You seem to be on completely the wrong track here, starting from a web application template and then trying to turn off the web application aspect.
Far better to start from a regular commandline client template and go from there, as detailed in the relevant Spring Guide.
Basically the application reduces to
#SpringBootApplication
public class Application {
private static final Logger log = LoggerFactory.getLogger(Application.class);
public static void main(String args[]) {
SpringApplication.run(Application.class);
}
#Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
#Bean
public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
return args -> {
Quote quote = restTemplate.getForObject(
"http://gturnquist-quoters.cfapps.io/api/random", Quote.class);
log.info(quote.toString());
};
}
}
And the pom to
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>
I had this problem. All I wanted was to have a Client making REST requests. Unfortunately I had a dependency which was embedding Jetty, and Jetty was always started.
In order to disable Jetty all I needed to do was to add in applications.properties the following entry:
spring.main.web-application-type=none
That fixed it.
Here is the most simple solution for me, make spring boot application just a restful api consumer.
Replace the dependence
implementation("org.springframework.boot:spring-boot-starter-web")
with
implementation("org.springframework.boot:spring-boot-starter-json")
RestTemplate and jackson are available in the project without embedded tomcat.
Answering your questions:
1) embedded by defaut - not needed for clients HTTP requests;
2) You can use CommandLineRunner for spring boot applications without any web:
#SpringBootApplication
public class SpringBootConsoleApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(SpringBootConsoleApplication.class, args);
}
#Override
public void run(String... args) {
// TODO: start you thread here to execute client HTTP REST requests (or any other job you need)
}
}
This will disable web completelly - no issues with manual miss-configuration.
Here is some docs:
http://www.baeldung.com/spring-boot-console-app
You also need replase spring-boot-starter-web dependency with spring-boot-starter:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
From your question, i assume you want your application to keep running in background and it makes some get calls in it's life cycle. If that's the case, then
answering your first question, yes, you need an embedded tomcat or
jetty or need to deploy your application to an external application
server.
Second, to get rid of the exception your facing, don't exclude
EmbeddedServletContainerAutoConfiguration and
WebMvcAutoConfiguration class as it's needed for default embedded
tomcat auto configuration.

Spring Boot, Spring Data JPA, CrudRepository, file based read only database packaged in JAR

I wrote an application using Spring Boot, Spring Data JPA and h2 file based database. All works just fine effortlessly... Thanks Spring.
Now I try to deliver some system data in another read only h2 file based database. It's possible to package my "system.db" in the JAR and access it with Spring Data JPA?
How configure my "system dataSource" and how structure my code... Always effortless?
I have:
1) my.package.app.Application
#Configuration
#ComponentScan
#EnableAutoConfiguration
public class Application {
public static void main(final String[] args) {
new SpringApplication(Application.class).run(args);
}
}
2) my.package.app.repo the root package of my repositories (CrudRepository)
3) config/application.properties
spring.datasource.url: jdbc:h2:file:~/MyApp/data/default
spring.datasource.username: sa
spring.datasource.password: sa
spring.datasource.driverClassName=org.h2.Driver
spring.jpa.hibernate.ddl-auto: validate

Categories

Resources