How do i check for a valid database connection using JDBCTemplate - spring

I am using JDBCTemplate in my spring boot application and successfully connected to my AWS rds instance, but i noticed using AutoWired im not entirely sure how the connection is made and how to check for a valid connection, i want to throw an exception if the connection to the database is invalid. this is the way it connects, it takes the database information from application.properties.
private JdbcTemplate jdbcTemplate;
public AwsBarcodeDao(#Autowired JdbcTemplate jdbc){
jdbcTemplate=jdbc;
}
there seems to be no indication of unsucessful connection until i try to do something like this, which is the actual query:
final String selectProductSql = "SELECT barcodeOrUpc, productName FROM DB WHERE barCodeOrUpc="+barcode+";";
products = jdbcTemplate.query(selectProductSql, new ProductRowMapper());

In your application.properties:
spring.datasource.validationQuery=your validation query
spring.datasource.test-while-idle=true
spring.datasource.time-between-eviction-runs-millis=30000
other props can be:
testOnBorrow
testOnReturn
validationQueryTimeout
commons-dbcp has a configuration property validationQuery, this combined with testOnBorrow and testOnReturn could cause the statements you see.
c3p0 has preferredTestQuery, testConnectionOnCheckin, testConnectionOnCheckout and idleConnectionTestPeriod

Related

How to get schema name from DataSource or Connection object

I want to get the schema name from my DataSource or Connection object so that it can be used in my SQL queries dynamically. I'm using DB2 and there is no implementation of connection.getSchema() in DB2 driver.
I'm using DataSource to get connection. Since connection.getSchema() is not working, I tried another approach as given below
connection.getMetaData().getURL()
But this is returning connection URL without schema information like below:
jdbc:db2://servername:1446/DBName
But i have given schema information in the URL while creating the datasource in embeddable Container.
jdbc:db2://servername:1446/DBName:currentSchema=mySchema
I need to get schema name to use it in query. Somebody knows how to get schema name.
Try the SQL statement
values current schema
The Db2BaseDataSource has a property currentSchema, along with a getter and a setter.
There's also a property called user .
setter:
db2ds.setCurrentSchema("fred");
getter:
String x = db2ds.getCurrentSchema() ;

Spring Data Neo4J #Index(unique = true) does not working

I want to make userName property in User node as a unique.
I used below code but it doesn't create a unique constraint in the Neo4j database.
#Property(name = "name")
#Index(unique = true)
private String usreName;
FYI, I'm using the Neo4j Server version: 3.3.6 (community) With Spring Boot 2.
but if I create a constraint in the Neo4j Browser by myself, it works.
CREATE CONSTRAINT ON (user:User) ASSERT user.userName IS UNIQUE
Is there a way to force Spring Data Neo4J to create unique properties, without creating them by myself in Database?
You need to configure the auto index manager if you want the application code create the constraints.
You can find the best fitting option in the documentation:
https://docs.spring.io/spring-data/neo4j/docs/current/reference/html/#reference:indexing:creation
Just a note on this topic: Think about the auto index creation like Hibernate's DDL support. It is a helper at development time. You should not use assert and update in production environments but only validate.
Reason
In Spring Data Neo4j 4, index management concerns were removed from
the mapping framework entirely.
(from Index Management in Spring Data Neo4j)
Solution
#Autowired
private SessionFactory sessionFactory;
#PostConstruct
public void createIndexesAndConstraints() {
Session session = sessionFactory.openSession();
Result result = session.query("CREATE INDEX ON :User(userName)", Collections.EMPTY_MAP);
}
You can configure the mode our auto index manager works in through application.properties
spring.data.neo4j.auto-index=validate # or
# spring.data.neo4j.auto-index=update
# spring.data.neo4j.auto-index=assert
Default mode is none. Apart from that, what #meistermeier says applies.
Also, Neo4jOperations was deprecated in SDN 4 something and has been removed in SDN 5. Use Session instead for operations "near" the database.
Thank you #ThirstForKnowledg for your answer. But I have 3 other Questions:
1- I'm using Spring Boot 2, and I can not see Neo4jOperations in my classpath to import it.
2- Should I put this in my Entity node or in another bean?
3- What about after running my application two or more times? I think it would cause an exception for the second time or more.

Spring Data JPA order with NullHandling (Postgres)

I have a problem with NullHandling in Spring Data. I am trying to pass custom NullHandling to my findAll method of repository - something like below:
Page<Developer> developerPage = developerRepository.findAll(
new PageRequest(0, 2, new Sort(new Sort.Order(Sort.Direction.ASC, "user").nullsFirst()))
);
However, I have option show-sql set to true and in logs I see that in query which is passed to the database there is nothing mention about null handling. I get wrong results (even more different results for Postgres and H2 but I understand it is the difference between default null handling for each database). Configuration for Postgres is:
spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost/postgres?useUnicode=yes&characterEncoding=UTF-8
spring.datasource.username=postgres
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.properties.hibernate.globally_quoted_identifiers=true
spring.jpa.show-sql=true
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
What is the problem here? Is custom null handling supported in Spring Data JPA?
Edit:
I found out that query order part for JPA is created in QueryUtils class in method toOrders(..). What is interesting - Sort implementation from spring data is mapped to Sort implementation of JPA where there is no support for null handling. There is also a jira issue that describes that it is not supported but it is from 2014: https://jira.spring.io/browse/DATACMNS-491
you can use this property in app.yml
spring.jpa.hibernate.order_by.default_null_ordering: last

jdbcTemplate batchUpdate issue

In my spring batch application i am trying to update the records in Writer using JdbcTemplate batchUpdate. But niether changes are reflecting in DB nor the job gets completed. when i check in JOB_EXECUTION in spring META-TABLES EXIT_CODE shows as UNKNOWN.
List<Object[]> objects = new ArrayList<Object[]>();
for(Item item : items){
Object[] objectsArray = new Object[]{item.getName(),item.getValidToDate(),item.getAccountNo(),item.getCode()};
objects.add(objectsArray);
}
iagJdbcTemplate.batchUpdate(updateSql,objects);
And my update query is like this
UPDATE ACCOUNT_INFO SET ADDRESS= ?,DATE=? WHERE ACCOUNT=? AND CODE=?;
ACCOUNT table has composite primary key which is a combination of ACCOUNT & CODE.
NOTE : When i run the same with INSERT query it just works fine.
Please do let me know where i am going wrong.
Issue is resolved. There is nothing wrong in the jdbcTemplate or in update query. It is some other environment related issue. Same configuration will work fine. No need to change the configurations. Thanks all.

Spring Hibernate : Multiple resultset mapping

I want to understand the limitations of Spring's Data repository.
While querying the database, it seems that Spring repository can only return entities, or a collection of same type, like string/int etc. It makes sense because the Spring Repository is a function and a function can only return one result.
So what if I need to execute a complexe sql by using #Query annotation, and expect more than one result? like a collection of entityies and a number.
I don't think it is possible with Spring Repository, so if i'm wrong, please correct me.
And more importantly, how could I do that by using spring?
No, it's not possible that I know of for the Repository to work with queries, but the Repository is used by a Spring ServiceImpl anyway and you can Inject an EntityManager into the serviceImpl and use that. For example see Getting started with Spring Data JPA:
#PersistenceContext
private EntityManager em;
TypedQuery query = em.createQuery("select a from Account a where a.customer = ?1", Account.class);
query.setParameter(1, customer);
return query.getResultList();

Resources