Spring Boot cannot read from Oracle database after application restart - java

My spring boot application cannot read from an Oracle DB instance.
If I configure the application to automatically create the schema and populate the DB via a data.sql file, then it works perfectly, like so:
spring:
datasource:
initialization-mode: always
...
jpa:
hibernate:
ddl-auto: create
But then if I then change the configuration to:
spring:
datasource:
initialization-mode: never
...
jpa:
hibernate:
ddl-auto: validate
and then restart the spring boot application, it can no longer read from the DB, even though all the tables and data that it created before the restart is still there in the DB.
Has anyone experienced this issue before? Or would you know where I could even start to try debugging it?
This is the Oracle version:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
This is the driver I'm using:
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<scope>runtime</scope>
</dependency>
And the version of JPA:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
and it's spring boot version 2.3.3
UPDATE:
The appears to happen after I write to the DB via Spring Boot, i.e. insert a new record, and then restart the application.

Related

Connect to microsoft sql server from spring jpa

I am using microsoft sql server,
If i open intellij, open new database connection in database tool window =>
and in advanced type i add:
The connection works. However now i want to connect to this ms sql server with spring jpa. So what i am using is:
spring.datasource.url=jdbc:jtds:sqlserver://<host>:<port>;instance=<instance>;domain=<domain>;useNTLMv2=true
spring.datasource.username=<user>
spring.datasource.password=<password>
spring.datasource.driverClassName=net.sourceforge.jtds.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.SQLServerDialect
And it just says "login for user failed"
In my pom i am using:
<!-- jpa -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>${spring.jpa.version}</version>
</dependency>
<dependency>
<groupId>jtds</groupId>
<artifactId>jtds</artifactId>
<version>1.2</version>
</dependency>
Why does it work with database tool window, but not with jpa?
Thanks for help!
Your are mixing JDBC driver connecting with sprig data JPA connection, for JPA proper connection you can change the drive class name to
spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
Then the dialect can be
spring.jpa.hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
And finally add the proper url and remove JDBC driver relavent dependencies
spring.datasource.url=jdbc:sqlserver://localhost;databaseName=<dbname>
Remaining properties will be same as your, see both examples in here .

How does a service that deployed in the spring-cloud-dataflow-server connect to another database instead of the database that the dataflow-sever use?

The case is that I have launched both Spring Cloud Data Flow Server and Shell apps in my local machine, and they all used the H2 memory database to store the tasks and jobs defination.
When I deployed the application that Used a H2 as the database to read data, it works perfect fine.
But when I want to deploy and run the application that read data from a local postgresql database, it just could not find it, and will then use the H2 again.
I have add postgresql dependency in my pom and also configure the properties in the application.properties , it works fine with spring batch in my local Intelij.
So my question is that how could I make my application still read data from the postgresql after it been deployed in the spring-cloud-data-flow-server? Thanks.
Configuration info:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version
<spring.cloud.task.version>2.0.0.RELEASE</spring.cloud.task.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-task-core</artifactId>
<version>${spring.cloud.task.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-task-batch</artifactId>
<version>${spring.cloud.task.version}</version>
</dependency>
You can control what datasource should be configured to SCDF, Tasks, Task-launcher, and even Composed Task Runner. The documentation for these options could be useful.
In your case, though, it sounds like you have 2 different databases: one for SCDF and the other for the Task that SCDF launches, which should be a pretty straightforward setup as long as the datasource properties are configured correctly on both the Boot apps.
It could be that either there's no Postgres driver in the classpath or the datasource properties aren't configured correctly. Review the docs of the connection properties for the supported databases - you could double check for correctness.

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>

Changing embedded database in Spring Boot from H2 to MySQL

Is there a way to change database in application that is almost done? I am encoutering many problems with H2 that does not occur in MySQL. For example ALTER TABLE yourtable AUTO_INCREMENT = 1; does not work and instead I had to use restart at which does not work as good as MySQL version. Also now I am having problems with datediff. So is it possible to change database in ongoing application?
Yes you can.
Include dependencies for MySql in your pom file:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
Create your repository interface for mysql that extends JpaRepository:
public interface SqlDAO extends JpaRepository<YourPOJO,Long>{
// you can use JpaRepository methods out of the box or write custom ones
}
Add properties for your sql, you can use .properties or .yml files. I use yaml:
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/coolDB
username: root
password: 123456
jpa:
hibernate:
ddl-auto: update
show-sql: true
Don't forget to run MySql database itself and you good to go.
Your Service now should be using your repository interface to communicate with Sql.
Here is a link for Jpa documentation and how to create your custom methods:
https://docs.spring.io/spring-data/jpa/docs/1.4.1.RELEASE/reference/html/jpa.repositories.html
Edit: you have to create database in mysql console manually, Spring won't do it for you. You can include .sql file into your resource directory to create dummy data or set sql settings further on, Spring will run that for you.

Spring Boot default H2 jdbc connection (and H2 console)

I am simply trying to see the H2 database content for an embedded H2 database which spring-boot creates when I don't specify anything in my application.properties and start with mvn spring:run. I can see hibernate JPA creating the tables but if I try to access the h2 console at the URL below the database has no tables.
http://localhost:8080/console/
I see suggestions like this one:
View content of embedded H2 database started by Spring
But I don't know where to put the suggested XML in spring-boot and even if I did, I don't want the h2console to be available anymore when an external database is configured so it is more likely that I need to handle this with some kind of conditional code (or maybe just allow spring to automatically handle it in the most ideal case where I only include H2 when a maven profile is activated).
Does anyone have some sample code showing how to get the H2 console working in boot (and also the way to find out what the jdbc connection string that spring is using is)?
This is how I got the H2 console working in spring-boot with H2. I am not sure if this is right but since no one else has offered a solution then I am going to suggest this is the best way to do it.
In my case, I chose a specific name for the database so that I would have something to enter when starting the H2 console (in this case, "AZ"). I think all of these are required though it seems like leaving out the spring.jpa.database-platform does not hurt anything.
In application.properties:
spring.datasource.url=jdbc:h2:mem:AZ;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
In Application.java (or some configuration):
#Bean
public ServletRegistrationBean h2servletRegistration() {
ServletRegistrationBean registration = new ServletRegistrationBean(new WebServlet());
registration.addUrlMappings("/console/*");
return registration;
}
Then you can access the H2 console at {server}/console/. Enter this as the JDBC URL: jdbc:h2:mem:AZ
As of Spring Boot 1.3.0.M3, the H2 console can be auto-configured.
The prerequisites are:
You are developing a web app
Spring Boot Dev Tools are enabled
H2 is on the classpath
Even if you don't use Spring Boot Dev Tools, you can still auto-configure the console by setting spring.h2.console.enabled to true
Check out this part of the documentation for all the details.
Note that when configuring in this way the console is accessible at: http://localhost:8080/h2-console/
I have found a nice tutorial about this topic:
https://springframework.guru/using-the-h2-database-console-in-spring-boot-with-spring-security/
Basically the correct JDBC URL for me was: jdbc:h2:mem:testdb
From http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
H2 Web Console (H2ConsoleProperties):
spring.h2.console.enabled=true //Enable the console.
spring.h2.console.path=/h2-console //Path at which the console will be available.
Adding the above two lines to my application.properties file was enough to access the H2 database web console, using the default username (sa) and password (empty, as in don't enter a password when the ui prompts you).
A similar answer with Step by Step guide.
Add Developer tools dependency to your pom.xml or build.gradle
Maven
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
Gradle
dependencies {
compile("org.springframework.boot:spring-boot-devtools")
}
Access the db from http://localhost:8080/h2-console/
Specify jdbc:h2:mem:testdb as JDBC URL
You should see the entity you specified in your project as a table.
For Spring Boot 2.1.1 straight from Spring Initialzr:
Default with devtools is http://127.0.0.1:8080/h2-console/
POM: spring-boot-starter, h2, spring-boot-starter-web, spring-boot-devtools
Without devtools - you need to set it in properties: spring.h2.console.enabled=true spring.h2.console.path=/h2-console
POM: spring-boot-starter, h2, spring-boot-starter-web
Once you get there - set JDBC URL: jdbc:h2:mem:testdb (The default one will not work)
I had only below properties in /resources/application.properties. After running spring boot, using this URL(http://localhost:8080/h2-console/), the table in H2 console was visible and read to view the table data, also you can run simple SQL commands. One thing, in your java code, while fetching data, the column names are upper-case, even though schema.sql is using lower-case names :)
spring.datasource.initialize=true
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=- 1;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.h2.console.enabled=true
Check spring application.properties
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
here testdb is database defined
Make sure h2 console have same value while connecting other wise it will connect to default db
For Spring Boot 2.3.3.RELEASE straight from Spring Initialzr:
POM: data jpa, h2, web
application properties: spring.h2.console.enabled=true
When you run the application look for line like below in the run console:
2020-08-18 21:12:32.664 INFO 63256 --- [ main] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:eaa9d6da-aa2e-4ad3-9e5b-2b60eb2fcbc5'
Now use the above JDBC URL for h2-console and click on Connect.
If you use Spring Boot's developer tools, it comes with H2 Console enabled by default. It can be accessed from /h2-console/. On the login interface, for input JDBC URL use value jdbc:h2:mem:testdb. Pay attention to mem string.
If you don't use Spring Boot's developer tools, you can enable the console in application.properties using spring.h2.console.enabled=true. This will enable console under /h2-console. If you want to change the URL then you can add another entry with spring.h2.console.path=my_console_path.
The default schema name is testdb.
More details in Spring Boot Documentation.
In order to get the tables all you need to do is create 2 sql files schema.sql(for table creation) and data.sql(data for the created tables). These files to be put in src/main/resources folder. Spring boot auto detects them and takes care of the rest during runtime.
If your using more than 2 DB in your project ensure to use specific files like (schema-h2.sql -- for h2 DB , schema-oracle.sql -- for oracle DB). The same to be followed for data.sql too.
Also ensure that you drop tables by adding drop table statement in your schema.sql as first statement. To avoid appending of duplicate records.
The link for spring boot is here.
My application.properties is as follows.
spring.datasource.url=jdbc:h2:~/file/Shiva;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.platform=h2
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
spring.datasource.initialize=true
spring.error.whitelabel.enabled=true
spring.h2.console.path=/console
spring.datasource.continue-on-error=true
spring.jpa.hibernate.ddl-auto=create
spring.hibernate.hbm2ddl.auto=update
spring.hibernate.show_sql=true
You can follow the steps in the below link.
https://springframework.guru/using-the-h2-database-console-in-spring-boot-with-spring-security/
I found that with spring boot 2.0.2.RELEASE, configuring spring-boot-starter-data-jpa and com.h2database in the POM file is not just enough to have H2 console working. You must configure spring-boot-devtools as below.
Optionally you could follow the instruction from Aaron Zeckoski in this post
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
Use jdbc:h2:mem:testdb as your path when logging into the H2 console.
Obviously if you have altered Spring Boot properties your datasource may be different, but it seems like you're struggling with how to find the default. That's all there is to it! You'll see your schema after logging in to H2.
I had made a very stupid mistake when I had this same problem. I had added H2 DB for running unit test cases and hence I had set the scope to test in pom.xml. While running the application using mvn spring:run I removed the scope and it works fine now.

Categories

Resources