Does anyone have examples of how to use DBMS_APPLICATION_INFO package with JBOSS?
We have a various applications which run within JBOSS and share db pools. I would like, at the start of each session these applications to identify themselves to the database using DBMS_APPLICATION_INFO so I can more easily track which sections of the application is causing database issues.
I'm not too familiar with session life cycles in JBOSS, but at the end of the day, what needs to happen is at the start and end of a transaction, this package needs to be called.
Has anyone done this before?
If you are using JBoss, you can use a "valid-connection-checker".
This class is normaly used to check the validity of the Connection.
But, as it will be invoked every time the Connection pool gives the user a Connection, you can use it to set the DBMS_ APPLICATION _INFO.
You declare such a class in the oracle-ds.xml like this:
<local-tx-datasource>
<jndi-name>jdbc/myDS</jndi-name>
<connection-url>jdbc:oracle:thin:#10.10.1.15:1521:SID</connection-url>
<driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
<security-domain>MyEncryptDBPassword</security-domain>
<valid-connection-checker-class-name>test.MyValidConn</valid-connection-checker-class-name>
<metadata>
<type-mapping>Oracle9i</type-mapping>
</metadata>
</local-tx-datasource>
Your class must implement the org.jboss.resource.adapter.jdbc.ValidConnectionChecker interface.
If you use Maven, you can include this interface with the following dependency:
<dependency>
<groupId>jboss</groupId>
<artifactId>jboss-common-jdbc-wrapper</artifactId>
<version>3.2.3</version>
<scope>provided</scope>
</dependency>
This interface has only one method: isValidConnection.
I copy my implementation:
public SQLException isValidConnection(Connection arg0) {
CallableStatement statement;
try {
statement = arg0.prepareCall("call dbms_application_info.set_client_info('"+getInfos()+"')");
statement.execute();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
Hope it helps !
BenoƮt
yes, you can write a wrapper class around your connection pool, and a wraper around the connection
so lets say you have:
OracleConnection conn=connectionPool.getConnection("java:scott#mydb");
Change it to:
public class LoggingConnectionPool extends ConnectionPool{
public OracleConnection getConnection(String datasourceName, String module, String action){
OracleConnection conn=getConnection(datasourceName);
CallableStatement call=conn.preparedCall("begin dbms_application_info.setModule(module_name => ?, action_name => ?); end;");
try{
call.setString(1,module);
call.setString(2,action);
call.execute();
finally{
call.close();
}
return new WrappedOracleConnection(conn);
}
Note the use of WrappedOracleConnection above. You need this because you need to trap the close call
public class WrappedOracleConnection extends OracleConnection{
public void close(){
CallableStatement call=this.preparedCall("begin dbms_application_info.setModule(module_name => ?, action_name => ?); end;");
try{
call.setNull(1,Types.VARCHAR);
call.setNull(2,Types.VARCHAR);
call.execute();
finally{
call.close();
}
}
// and you need to implement every other method
//for example
public CallableStatement prepareCall(String command){
return super.prepareCall(command);
}
...
}
Hope this helps, I do something similar on a development server to catch connections that are not closed (not returned to the pool).
In your -ds.xml, you can set a connection property called v$session.program and the value of that property will populate the PROGRAM column of each session in the V$SESSION view created for connections originating from your connection pool. I usually set it to the jboss.server.name property.
See here for an example.
Related
I'm learning about JDBC and I have learned the steps: open connection, execute statement, get result, etc. I know about Connection, Statements and the other interfaces, but I just found a tutorial with another class, the Connector class. And I don't understand what exactly we can do with this Connector class. I have made some app without this class and I don't understand why do I need the Connector class? Any feedback will be apreciated!
Here is the code:
public Set getAllUsers() {
Connector connector = new Connector();
Connection connection = connector.getConnection();
try {
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM user");
Set users = new HashSet();
while(rs.next())
{
User user = extractUserFromResultSet(rs);
users.add(user);
}
return users;
} catch (SQLException ex) {
ex.printStackTrace();
}
return null;
}
UPDATE:
This is the link where you can find the entire code: https://dzone.com/articles/building-simple-data-access-layer-using-jdbc
Your Connector is probably a class with a factory method:
the factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created.
Basically it is a utility class to create a Connection hiding the complexity of connection creation.
I am using the c3p0 library as my datasource object.
I want to create a JDBC helper class that helps reduce the boilerplate code that JDBC has and I am wondering if my implementation is correct and are following best practices? Also, if there is an already existing library that provides these functionalities, like QueryRunner, maybe?
Most of my queries returns a list of results of a specified column. Will it be okay if I use the following helper method for all my queries?
public List<String> retrieveSQLQuery(String sqlQuery, String column) {
List<String> values = new ArrayList<>();
try (Connection conn = getConnection();
PreparedStatement statement = conn.prepareStatement(sqlQuery);
ResultSet rs = statement.executeQuery(sqlQuery)) {
while (rs.next()) {
values.add(rs.getString(column));
}
} catch (SQLException e) {
e.printStackTrace();
}
return values;
}
The getConnection() method lives in a JDBCUtil class which provides the connection to the datasource object. This helper class will be extending JDBCUtil thus why it has access to that method.
I also know that frameworks like spring and Hibernate provide utilities, however, those frameworks are too large for my project.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm developing a java based application using NetBeans. My app opens with a window with asks the user to enter their credentials and based on data entered, a connection is established between the app and my MySQL client (I'm using JDBC for this purpose).
My issue: I want the connection object (which is declared and initialized after checking the credentials of the user) to be available for use in all my form. Previously, i have being doing this by passing the connection object from one form to another. But i don't want to do that! I want once this connection object is declared, it's made available to all the forms in the app.
I want the connection object (...) to be available for use in all my form
You should not have an open connection while your application lives. Instead, use a database connection pool of 1 or 2 connections that will be available for all the application and add a shutdown hook to close this data source when the application finishes. The connection pool will take care to maintain the connections alive and use low resources for it.
For example: your user opens the application and enters its credentials, then leaves the room because he/she has to do some paperwork and takes 30 mins, then goes back to the pc and try to use an option. If using a static Connection con object, you manually opened a physical connection to the database and you're in charge to control the connectivity for all these 30 minutes, and if you don't do any action in that time then probably the physical connection was closed by the database engine. If using a connection pool, this will take care of opening/closing physical connections and maintaining them in sleep state so your connection won't be lost.
Note that your Connection object and related resources (PreparedStatement, ResultSet, etc). should be in the narrowest possible scope.
Here's a minimal example of doing this using BoneCP as database connection pool.
public class ConnectionProvider {
private static DataSource dataSource;
private static boolean initialized = false;
public static void init(Map<String, String> conf) {
if (!initialized) {
//synchronization to avoid multiple threads accesing to this part of the method
//at the "same time"
synchronized(DataSourceProvider.class) {
//double validation in case of multi threaded applications
if (!initialized) {
//you may add more validations here
//in case you want to use another datasource provider
//like C3PO, just change this part of the code
BoneCPDataSource bds = new BoneCPDataSource();
bds.setDriverClass(conf.get("driver"));
bds.setJdbcUrl(conf.get("url"));
bds.setUsername(conf.get("user"));
bds.setPassword(conf.get("password"));
//this should be obtained as configuration parameter
bds.setMaxConnectionsPerPartition(2);
//you can add more BoneCP specific database configurations
dataSource = bds;
initialized = true;
}
}
}
}
public static Connection getConnection() {
if (dataSource == null) {
//this should be a custom exception in your app
throw new RuntimeException("Data Source was not initialized.");
}
return dataSource.getConnection();
}
}
And the client (once you have called the init method and provided the database configurations). I'm avoiding exception handling for brevity:
public class SomeDao {
private Connection con;
//using Dependency Injection by composition for DAO classes with connection
public SomeDao(Connection con) {
this.con = con;
}
public SomeEntity getSomeEntity(int id) {
String sql = "SELECT id, col1, col2 FROM someEntity WHERE id = ?";
//PreparedStatement and ResultSet go on the narrowest possible scope
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setInt(1, id);
ResultSet rs = pstmt.executeQuery();
SomeEntity someEntity = new SomeEntity();
if (rs.hasNext()) {
someEntity.setId(rs.getInt("id");
//similar for other columns...
}
//don't forget to close the resources after its usage
return someEntity;
}
}
public class SomeService {
public SomeEntity getSomeEntity(int id) {
//retrieving the connection at this level
//a service may access to several daos
Connection con = ConnectionProvider.getConnection();
//performing the operations against DAO layer
SomeDao someDao = new SomeDao(con);
SomeEntity someEntity = someDao.getSomeEntity(id);
//closing the connection. This is A MUST
//here the connection pool won't close the physical connection
//instead put it to sleep
con.close();
//return the proper data at a single point of the method
return someEntity;
}
}
Don't use the same Connection in your application! But what you want to achieve could be done using static variable. For example, add the following code to any of your classes, or create a new class for it:
private static Connection con = null;
public static Connection getConnection (String url)
{
if (con == null)
con = DriverManager.getConnection(url);
return con;
}
Then, call MyClass.getConnection("jdbc:mysql://localhost:3306/") or whatever the connection string is, and it will return one Connection that you could use for all classes.
I am trying to create a simple app with a SQLite database. I chose to use the SQLiteJDBC driver.
The code below is taken from the above website.
My question is about the line after public static void main...
It reads: Class.forName("org.sqlite.JDBC");
My question is, what does this line mean? And what does it do? It doesn't seem to be connected to the rest of the code. Class.forName() should return a class, but the line seems to stand alone inside the body. Whatever it returns isn't used by another part of the code, that I can see.
Please help clarify this. Thanks in advance.
public class Test {
public static void main(String[] args) throws Exception {
Class.forName("org.sqlite.JDBC");
Connection conn =
DriverManager.getConnection("jdbc:sqlite:test.db");
Statement stat = conn.createStatement();
stat.executeUpdate("drop table if exists people;");
stat.executeUpdate("create table people (name, occupation);");
PreparedStatement prep = conn.prepareStatement(
"insert into people values (?, ?);");
prep.setString(1, "Gandhi");
prep.setString(2, "politics");
prep.addBatch();
prep.setString(1, "Turing");
prep.setString(2, "computers");
prep.addBatch();
conn.setAutoCommit(false);
prep.executeBatch();
conn.setAutoCommit(true);
ResultSet rs = stat.executeQuery("select * from people;");
while (rs.next()) {
System.out.println("name = " + rs.getString("name"));
System.out.println("job = " + rs.getString("occupation"));
}
rs.close();
conn.close();
}
}
It loads a class dynamically. What does Class.forname method do? is a good article about it and it also explains why database drivers needs it:
Let's see why you need Class.forName() to load a driver into memory. All JDBC Drivers have a static block that registers itself with DriverManager and DriverManager has static an initializer only.
The MySQL JDBC Driver has a static initializer looks like this:
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
JVM executes the static block and the Driver registers itself with the DriverManager.
You need a database connection to manipulate the database. In order to create the connection to the database, the DriverManager class has to know which database driver you want to use. It does that by iterating over the array (internally a Vector) of drivers that have registered with it and calls the acceptsURL(url) method on each driver in the array, effectively asking the driver to tell it whether or not it can handle the JDBC URL.
The Class.forName statement is making sure that the class that implements the JDBC driver for sqlite3 is loaded and registered with the JDBC factory mechanism.
When you call DriverManager.getConnection(), it looks for classes that are registered and claim to be able to handle the connection string. If no such class is found, it can't create the connection.
I'm trying to generate some sql files in my java application.
The application will not execute any sql statements, just generate a file with sql statements and save it.
I'd like to use the java.sql.PreparedStatement to create my statements so that i don't have to validate every string etc. with my own methods.
Is there a way to use the PreparedStatement without the calling java.sql.Connection.prepareStatement(String) function, because I don't have a java.sql.Connection?
Take a look at this Java library: http://openhms.sourceforge.net/sqlbuilder/
I'm guessing that until you've got a sql connection, the parser won't know what rules to apply. I'm guessing that it's actually the SQL driver or even server that's compiling the sql statement.
Assuming your sql is simple enough, then how about using a cheap connection, like, say a sqlite connection.
SQLite will create a new database on the fly if the database you're attempting to connect to does not exist.
public Connection connectToDatabase() {
// connect to the database (creates new if not found)
try {
Class.forName("org.sqlite.JDBC");
conn = DriverManager.getConnection("jdbc:sqlite:mydatabase.db");
// initialise the tables if necessary
this.createDatabase(conn);
}
catch (java.lang.ClassNotFoundException e) {
System.out.println(e.getMessage());
}
catch (java.sql.SQLException e) {
System.out.println(e.getMessage());
}
return conn;
}
Not really. Preparing a statement in most cases means that it will be compiled by DBMS which is "hard" without connection.
http://java.sun.com/docs/books/tutorial/jdbc/basics/prepared.html
This is a dastardly devious problem, thankfully it's pretty easy to cope with:
public class PreparedStatementBuilder
{
private String sql; // the sql to be executed
public PreparedStatementBuilder(final String sql) { this.sql = sql; }
protected void preparePrepared(final PreparedStatement preparedStatement)
throws SQLException
{
// this virtual method lets us declare how, when we do generate our
// PreparedStatement, we want it to be setup.
// note that at the time this method is overridden, the
// PreparedStatement has not yet been created.
}
public PreparedStatement build(final Connection conn)
throws SQLException
{
// fetch the PreparedStatement
final PreparedStatement returnable = conn.prepareStatement(sql);
// perform our setup directives
preparePrepared(returnable);
return returnable;
}
}
To use, just write an anonymous class that overrides void preparePrepared(PreparedStatement):
final String sql = "SELECT * FROM FOO WHERE USER = ?";
PreparedStatementBuilder psBuilder = new PreparedStatementBuilder(sql){
#Override
protected void preparePrepared(PreparedStatement preparedStatement)
throws SQLException
{
preparedStatement.setString(1, "randal");
}};
return obtainResultSet(psBuilder);
Presto! You now have a way to work with a PreparedStatement without yet having built it. Here's an example showing the minimal boilerplate you'd otherwise have to copy paste to kingdom come, every time you wanted to write a different statement:
public ResultSet obtainResultSet(final PreparedStatementBuilder builder)
throws SQLException {
final Connection conn = this.connectionSource.getConnection();
try
{
// your "virtual" preparePrepared is called here, doing the work
// you've laid out for your PreparedStatement now that it's time
// to actually build it.
return builder.build(conn).executeQuery();
}
finally
{
try { conn.close(); }
catch (SQLException e) { log.error("f7u12!", e); }
}
}
You really really don't want to be copy pasting that everywhere, do you?
Try implementing PreparedStatement.
Example : class YourOwnClass implements PreparedStatement {
// 1. Do implement all the methods ,
2. Get the minimal logic to implement from OraclePreparedStatement(classes12.jar) or
sun.jdbc.odbc.JdbcOdbcCallableStatement
}