Springboot can't get the loaded data from h2 database - spring-boot

I am using a h2 database for runtime as well as for testing. However when I run a test trying to fetch the data from the database, it doesn't get me the records during the integration test. I'm preloading the data using data.sql. How can I use the same database for my integration tests as well. Below is my configuration
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
#Test
void testUsers() throws Exception {
mockMvc.perform(get("/getUsersById/12")
.contentType("application/json")).andExpect(jsonPath("$",hasSize(1)));
}
data.sql
insert into USER values('12','test','user');
insert into USER values('23','test','user');

Related

Can vertx and traditional jdbc clients work together in quarkus?

In my quarkus project, I have added the following dependencies to create a non-blocking asynchronous project
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-vertx</artifactId>
</dependency>
<dependency>
<groupId>io.smallrye.reactive</groupId>
<artifactId>smallrye-mutiny-vertx-web-client</artifactId>
</dependency>
But now I want to write data to mysql database, so I want to add the following dependency to the project
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm-panache</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-mysql</artifactId>
</dependency>
But it seems that this database driver and orm are blocking, so what I want to ask is, does vert.x work with traditional jdbc in quarkus?
Another question is, is the quarkus framework an asynchronous, non-blocking framework? What is its relationship to vert.x? When the qurakus framework Added vert.x dependency, did the whole project require non-blocking?
Quarkus can be reactive or non reactive, it depends which extensions you choose to use.
Hibernate ORM Panache is for when you want to access the database in a non reactive way using Hibernate ORM and Panache.
The same is true for JDBC, it's not reactive so you have to use something else if you want your whole app to be reactive.
In this scenario, you probably want to try these two extensions:
quarkus-hibernate-reactive-panache: See the Hibernate Reactive with panache quickstart for an example
quarkus-reactive-mysql-client: For allowing reactive access to the db. See the guide for Vert.x SQL Clients on the quarkus website
On the Quarkus website, there is also an intro on reactive for Quarkus.
Example of how to use the Vert.x SQL client from the guide:
#Path("fruits")
public class FruitResource {
#Inject
io.vertx.mutiny.mysqlclient.MySQLPool client;
}
client.query("DROP TABLE IF EXISTS fruits").execute()
.flatMap(r -> client.query("CREATE TABLE fruits (id SERIAL PRIMARY KEY, name TEXT NOT NULL)").execute())
.flatMap(r -> client.query("INSERT INTO fruits (name) VALUES ('Orange')").execute())
.flatMap(r -> client.query("INSERT INTO fruits (name) VALUES ('Pear')").execute())
.flatMap(r -> client.query("INSERT INTO fruits (name) VALUES ('Apple')").execute())
.await().indefinitely();
Example with Hibernate Reactive and Panache from the quickstart:
#Entity
public class Fruit extends PanacheEntity {
#Column(length = 40, unique = true)
public String name;
public Fruit() {
}
public Fruit(String name) {
this.name = name;
}
}
#GET
public Uni<List<Fruit>> get() {
return Fruit.listAll(Sort.by("name"));
}
A complete list of quickstarts for Quarkus is available on GitHub.
Look for the ones with the word reactive and you will have several examples with different extensions.
To conclude, one approach is to replace the Hibernate ORM and JDBC extensions with the following:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-reactive-panache</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-reactive-mysql-client</artifactId>
</dependency>
Answer to your questions:
is the quarkus framework an asynchronous, non-blocking framework? What is its relationship to vert.x?
Quarkus is designed to work with popular Java standards, frameworks, and libraries. So, it being reactive or not depends from which extensions you pick and how you design your app. Vert.x is one of the tools that are available to you (See What's Quakrkus?)
When the quarkus framework Added vert.x dependency, did the whole project require non-blocking?
No. For example, you can have both the JDBC driver and the Vert.x SQL client extensions on the classpath and get one or the other via injection when you need to use them.

Start spring-boot project without datasource configuration on application.properties

I have a spring-boot project where the database configuration should be saved in the first time the user execute the application, after ask for the connection data (server url, username and password). the application.properties file embbed in the WAR file of the application should be something like that:
security.basic.enabled=false
# THYMELEAF (ThymeleafAutoConfiguration)
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
spring.thymeleaf.cache=false
# Multipart Configuration
spring.servlet.multipart.maxFileSize = 150MB
spring.servlet.multipart.maxRequestSize = 150MB
spring.servlet.multipart.fileSizeThreshold = 5MB
# Setting max size of post requests to 6MB (default: 2MB)
server.tomcat.max-http-post-size=157286400
After the first run, a second application.properties should be created with the database configuration. But right now, when I try run the project with the configuration above, it do not start, showing the following error message:
***************************
APPLICATION FAILED TO START
***************************
Description:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class
Action:
Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).
without give the application the change to generate the second configuration file, with the database properties.
How I could force the application to run this first time, even without the database stuff?
update
Ok, then I get rid of this error message by keeping this 2 dependencies on my pom.xml:
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.4.1</version>
</dependency>
and now the applications runs without error, and I am able to open the installation page to create the database on the postgresql server and import the initial data (user data included).
But I notice that this initial data is not being stored on the postgresql server (despite the datababse and all the tables are being created normally). I suspect they are being created on the hyperSql database on memory, what do not help me at all.
My guess is that's happen because I autowire some Dao classes for this entities on my InstallService class, and the code only create the data on the postgresql where I directly make the connection with this specific server.
Considering the method responsible by populate de initial data on my database is something like that:
public void criarUsuario(String user, String pass, String nome, String sobrenome, String email) {
Usuario novo = new Usuario();
novo.setUsername(user);
novo.setPassword(pass);
novo.setFirstName(nome);
novo.setLastName(sobrenome);
novo.setEmail(email);
novo.setEnabled(true);
novo.setLocked(false);
novo.setCredenciais(new ArrayList<Credencial>());
novo.getCredenciais().add( credencialDao.findBy("nome", "admin") );
usuarioDao.insert(novo);
...
}
What I could change here to persist this data on the postgresql database, instead of the hyperSql database?
update 2
Now I managed to run the application even with only the postgresql dependency om my pom.xml. I did that by adding a initial configuration on my first application.properties (locatd on /src/main/resources):
spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/appdata
spring.datasource.username=...
spring.datasource.password=..
spring.datasource.continue-on-error=true
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.show-sql=false
spring.jpa.hibernate.ddl-auto=none
spring.jpa.generate-ddl=false
But when I try access the application on the browser, I got an error saying the database not exist (of course not, when I run the application the first time I have a specific flow to create database, tables and populate initial data).
is there any way to supress this "database not exist" error when I run the project?

Spring session with redis - lost Principal

guys.
I migrated to Spring session with Redis implementation. I'm using spring boot and the only thing that i've made to start with this implementation is to add this
<!-- Spring Session with Redis -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- -->
in pom.xml and this in application.properties.
#Redis for session persistent
spring.session.store-type=REDIS
spring.redis.host=localhost
spring.data.redis.repositories.enabled=false
Everything is working fine, except that from time to time, the Principal (authneticated user is lost). I still have access to restricted pages, but Principal obejct is null. This leads to corrupted data, because I track the entries created from the speceific user.
Whan of the methods that have problem is:
public void addSamples(Integer distributorId, String articleNumber, Integer quantity, Principal user) {
Distributor distributor = distributorRepository.getOne(distributorId);
Tile tile = tileRepository.findByArticleNumber(articleNumber);
Merchandiser merchandiser = merchandiserRepository.findByUsername(user.getName());
Samples samples = new Samples();
samples.setMerchandiser(merchandiser);
samples.getSamplesPK().setDistributor(distributor);
samples.getSamplesPK().setTile(tile);
samples.setQuantity(quantity);
distributor.getSamples().add(samples);
distributorRepository.save(distributor);
}
I'm still logged and have access, but the merchandiser object is null..
What can be the reason for this ? Any help will be usefull.
Best regards.

How to block Cassandra from trying to connect automatically

I have this project where I'm trying to connect to different DB types based on configuration.
I have it working for Mongo and MySQL and switch by loading Beans by using #ConditionalOnProperty(name = "settings.data.source", havingValue = "mongodb")
Now I want to add Cassandra, but once I added the following dependency to my pom, it starts trying to connect to Cassandra nodes on localhost.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-cassandra</artifactId>
</dependency>
I want to have more control over when the Cassandra resources are loaded.
It doesn't try to connect automatically when I added Mongo dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
Anyone familiar with this behavior? How can I control this? I don't always need a Cassandra connection...
You may disable Cassandra auto configuration,
#SpringBootApplication
#EnableAutoConfiguration(exclude={CassandraDataAutoConfiguration.class})
Yep, That's it, thanks!
#EnableAutoConfiguration(exclude={
CassandraDataAutoConfiguration.class,
MongoDataAutoConfiguration.class,
MongoRepositoriesAutoConfiguration.class,
MongoAutoConfiguration.class})
For both my #SpringBootApplication and #Configuration classes.

Spring Data Projection not working

I want to use spring projection in my project. I am doing exactly as mentioned at this url http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections
interface NoAddresses {
String getFirstName();
String getLastName();
}
The only difference is my interface is public. and is not in the same package as the repository. Is that a requirement?
Still I see the whole entities are being returned, instead of just the projected columns.
I have
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.10.2.RELEASE</version>
</dependency>
Doesn't work. Do i need to add some dependency to make the projection work? I am not using spring-boot but just the spring-data stuff in my project, running on tomcat server.
thanks
Chahat

Resources