I have created a desktop application and I have connect it to a MySQL database with a database connection (bean/class) and I can CRUD. I have seen on the NetBeans site that they create a connection pool on a web application.
Is a connection pool the same with the class/bean on a desktop application?
Does this mean that i create a bean/class like a desktop application that is connected with to DB model(MVC), or do i have to do something else?
On a Glassfish server you do the connection pool with a wizard; on Apache you do not. Do I have to create the DB connection bean for Apache?
What are the practices (beans, something else?) to connect a DB to a web application?
I have also read about Hibernate, but I don't understand the use of it. Where can hibernate help? I mean, it's ORM, but what can Hibernate do for me so that my code is easier? I think I'm missing the point of ORM
Hibernate will help you with your transaction management. It will enable you to open several different connections to the database, and also give you warnings when you are using unavailable objects (like beans that gets pulled in from different threads).
A concrete example of where Hibernate's ORM will make your code easier is when you are querying the DB. Instead of writing the standard SQL queries as strings, you can use Criteria-queries.
In Java, DB connections always use a JDBC driver. No DB that I know of allows to run more than a single SQL command over a single connection at the same time, so each connection becomes bottleneck if your application can run several SQL commands at the same time (the usual case for web servers where hundreds of users can interact with the database at the same time).
UPDATE: What I'm saying is: You can easily daisy-chain commands over a single connection (like UPDATE ... ; COMMIT) but you can't send two UPDATE commands at the same time -- you always have to wait for the first command to complete before you can send the next. Some databases allow to send several commands in a single query but they are executed one after the other and not all at the same time. Think about it: If you could run several commands concurrently over a single connection, how would you know in which order they were executed?
On top of that, creating DB connections is expensive for most DBs. Hence they are created in advance during application startup and held in a pool. As soon as you "connect" to the database with the pooled JDBC driver, it picks an unused connection from the pool and returns it. That (almost) takes no time. When you "close" the connection, it's returned to the pool.
As an additional benefit, the pool can keep the connections alive. So you never need to worry about connection errors when you need a new connection (well, as long as the DB is running).
From the application side, this is either transparent (most JDBC drivers either pool internally today or they have a pooling API). If your JDBC driver doesn't, you can always use a pool like DBCP. The pool handles all the nasty details and you write your application against the pool API instead of using JDBC directly. The docs will tell you how to do it.
How Hibernate is a different beast. Hibernate is a layer on top of JDBC that can transform POJOs into SQL and back.
So instead of saying INSERT INTO data(ID, VALUE) values (?, ?), you can say
class Pojo { long id; String value; }
Pojo demo = new Pojo();
demo.value = "Test";
session.persist(demo);
and Hibernate will create the SQL for you and send it to the DB. At this stage, it doesn't make your life easier. Hibernate starts to shine when you change your Pojos:
class Pojo { long id; String value;
String name; // Oops ... forget the name
}
Pojo demo = new Pojo();
demo.name = "John";
demo.value = "Test";
session.persist(demo);
Hibernate will change the DB definition accordingly and update all the SQL commands it needs to load and save the objects.
Related
How can I check that a connection to db is active or lost using spring data jpa?
Only the way is to make a query "SELECT 1"?
Nothing. Just execute your query. If the connection has died, either your JDBC driver will reconnect (if it supports it, and you enabled it in your connection string--most don't support it) or else you'll get an exception.
If you check the connection is up, it might fall over before you actually execute your query, so you gain absolutely nothing by checking.
That said, a lot of connection pools validate a connection by doing something like SELECT 1 before handing connections out. But this is nothing more than just executing a query, so you might just as well execute your business query.
our best chance is to just perform a simple query against one table, e.g.:
select 1 from SOME_TABLE;
https://docs.oracle.com/javase/6/docs/api/java/sql/Connection.html#isValid%28int%29
if you can use Spring Boot. Spring Boot Actuator is useful for you.
actuator will configure automatically and after it has activated ,
you can get know database status to request "health"
http://[CONTEXT_ROOT]/health
and it will return , database status like below
{"status":"UP","db":{"status":"UP","database":"PostgreSQL","hello":1}}
I am using the following code to connect to a firebird database
public static Connection dbStatic;
...
public void getConnection(){
FBWrappingDataSource DataSource = new FBWrappingDataSource();
DataSource.setDatabase("localhost/3050:C:/MyDatabase.FDB");
DataSource.setDescription("TNS Development Database");
DataSource.setType("TYPE4");
DataSource.setEncoding("ISO8859_1");
DataSource.setLoginTimeout(10);
try {
dbStatic = DataSource.getConnection("UserName", "Password");
} catch (SQLException e) {
e.printStackTrace();
}
}
...and the following to disconnect:
...
dbStatic.close();
...
I am using Firebird 2.1 runing on a Windows 7-32 bit machine, with Java verstion 1.7, Jaybird version 2.2.8, Tomcat version 7.xx running on Win7-32bit, Browser is Chrome version something or other (newish) running Win XP SP3.
I use a third party tool called IBExpert to look at the number of connections and/or I run this statement:
select * from mon$attachments;
When I look at the number of connections to the database after the .close() statement runs the number does not decrease. Why is that? The number of connections do decrease if I wait long enough, or if the Tomcat server is restarted. Closing the browser does not affect the connections.
As Andreas already pointed out in the comments, FBWrappingDataSource is a connection pool. This means that the pool keeps physical connections open, and it hands out logical connections backed by the physical connections in the connection pool. Once you call close() on that logical connection, the physical connection is returned to the pool as available for reuse. The physical connection remains open.
If you want to close all connections, you need to call FBWrappingDataSource.shutdown(). This closes all physical connections that are not currently in use(!), and marks the data source as shutdown.
However, everything in package org.firebirdsql.pool should be considered deprecated; it will be removed in Jaybird 3. See Important changes to Datasources
If you just want a data source, use org.firebirdsql.pool.FBSimpleDataSource (with Jaybird 3 you will need to use org.firebirdsql.ds.FBSimpleDataSource instead).
If you want connection pooling, use a third party connection pool library like HikariCP, DBCP or c3p0.
That said, I want to point out several things you should consider:
Jaybird 2.2.8 is not the latest version, consider upgrading to 2.2.12, the current latest release of Jaybird.
Using a static field for a connection is generally not a good idea (especially with a web application), consider your design if that is really what you need. You might be better off making a data source the static field, and obtain (and close!) connections for a unit of work (ie: one request). It might also indicate that it would be simpler for you to just use DriverManager to create the connection.
Naming conventions: your variable DataSource should be called dataSource if you follow the common Java conventions
setLoginTimeout(Integer.parseInt(10)) should lead to a compilation error, as there is no method Integer.parseInt that takes an int, and the method itself already accepts an int.
I have configure mongo uri in property file as below,
spring.data.mongodb.uri=mongodb://db1.dev.com,db2.dev.com,db3.dev.com
spring.data.mongodb.database=mydb
I use mongoowl as a monitoring tool.
When i do a get request, it shows hits in every mongodb which ideally should be show only in one db right?
No, You are actually opening a cluster replica set connection, in this connection type spring actually connects to all 3 databases to maintain fail over conditions or to full fill "read from secondary" option(hence you see hits on all 3 databases), but however the read and write operations happen only on primary unless you have specified it to read from a secondary.
A console application executing under:
1). Multiple threads
2). Connection Pooling (as the database connections range could be 5 to 30) of type Microsoft Access using DBCP.
While executing this application at my end (not tested the database limit) it works fine. And whenever I try to introduce the same application on one of other machines it generates an error.
I'm wondering why this is happening as there is only the difference of machines here. So, it works perfectly at my end.
I don't know much about connection pooling but it seems whatever I have understood I have implemented as:
public class TestDatabases implements Runnable{
public static Map<String, Connection> correctDatabases;
#Override
public void run() {
// validating the databases using DBCP
datasource.getConnection(); // Obtaining the java.sql.Connection from DataSource
// if validated successfully °º¤ø,¸¸,ø¤º°`°º¤ø,¸,ø¤°º¤ø,¸¸,ø¤º°`°º¤ø,¸ putting them in correctDatabases
}
}
The above case is implemented using ExecutorService = Number of databases.
Finally, I'm trying to put them in a static Collection of Type
Map<String, Connection> and making use of it throughout the application. In other words: I'm trying to collect the connectionString along with the Connection in a Map.
In other parts of my application I'm simply dealing with multiple threads coming along with the Connection URL. So, to perform any database operations I'm calling the
Connection con = TestDatabases.correctDatases.get(connectUrl);
For that machine, this application works fine for around ~5 databases. And the error is always getting generated when I'm trying to fire the query using above Connection (con) as stmt.executeQuery(query);
As, I'm not able to reproduce this issue at my end, it seems something is going-on wrong with the Connection Pooling or I have not configured my application to deal with Connection Pooling correctly.
Just for your information, I'm correctly performing Connection close in finally block where my application terminates and this Application is using Quartz Scheduler as well. For Connection Pooling, a call to the following from TestDatabases class is done for setUp as:
public synchronized DataSource setUp() throws Exception {
Class.forName(RestConnectionValidator.prop.getProperty("driverClass")).newInstance();
log.debug("Class Loaded.");
connectionPool = new GenericObjectPool();
log.debug("Connection pool made.");
connectionPool.setMaxActive(100);
ConnectionFactory cf = new DriverManagerConnectionFactory(
RestConnectionValidator.prop.getProperty("connectionUrl")+new String(get().toString().trim()),
"","");
PoolableConnectionFactory pcf =
new PoolableConnectionFactory(cf, connectionPool,
null, null, false, true);
return new PoolingDataSource(connectionPool);
}
Following is the error I'm getting (at the other machine)
java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driver] System resource exceeded.
Following is the Database Path:
jdbc:odbc:DRIVER= {Microsoft Access Driver (*.mdb, *.accdb)};DBQ=D:\\DataSources\\PR01.mdb
Each of those database seems to be not much heavy (its ~ 5 to 15 MB of total size).
So, I'm left with the following solutions:
1). Correction of Connection Pooling or migrate to the newer one's like c3p0 or DBPool or BoneCP.
2). Introducing batch concept - in which I will schedule my application for each group of 4 databases. It could be very expensive to deal with as any time the other schedule may also collapse.
I’m pretty sure that this is Java related error but I can’t fathom out why.
Just done the migration to BoneCP which solved my problem. I guess due to multi-threaded environment the dpcp was not providing the connection from pool rather it was trying to hit the database again and again. Maybe I could have solved the dpcp issue but migrating to BoneCP also provides advantage of performance.
What is best/good/optimal way to monitor connection to database.
Im writing swing application. What I want it to do is to check connection with database every time period. I've tried something like this.
org.hibernate.Session session = null;
try {
System.out.println("Check seesion!");
session = HibernateUtil.getSessionFactory().openSession();
} catch (HibernateException ex) {
} finally {
session.close();
}
But that dosn't work.
Second question which is comming to my mind is how this session closing will affect other queries.
Use a connection pool like c3p0 or dbcp. You can configure such pool to monitor connections in pool - before passing connection to Hibernate, after receiving it back or periodically. If the connection is broken, the pool with transparently close it, discard and open a new one - without you noticing.
Database connection pools are better suited for multi-user, database heavy application where several connections are opened at the same time, but I don't think it's an overkill. Pools should work just fine being bound to max 1 connection.
UPDATE: every time you try to access the database Hibernate will ask the DataSource (connection pool). If no active connection is available (e.g. because database is down), this will throw an exception. If you want to know in advance when database is unavailable (even when user is not doing anything), unfortunately you need a background thread checking the database once in a while.
However barely opening a session might not be enough in some configurations. You'll better run some dummy, cheap query like SELECT 1 (in raw JDBC).