I need to initialize a DataSource given url and driver.
Its need to be generic enough to support Oracle and SQL Server.
the app is running on jboss 5.
provided sample for both:
<db-connection name="TEST-ORACLE">
<url>jdbc:oracle:thin:#test:1521:ins1</url>
<driver>oracle.jdbc.xa.client.OracleXADataSource</driver>
<user>user</user>
<password>{ENCR}oRloKFKlqXs=</password>
<min-size>5</min-size>
<max-size>30</max-size>
<idle-timeout-minutes>1</idle-timeout-minutes>
</db-connection>
<db-connections>
<db-connection name="TEST-MSSQLSERVER">
<url>jdbc:jtds:sqlserver://server:1433/db;ProgramName=program;SelectMethod=cursor;useLOBs=false</url>
<driver>net.sourceforge.jtds.jdbc.Driver</driver>
<user>user</user>
<password>{ENCR}oRloKFKlqXs=</password>
<min-size>40</min-size>
<max-size>80</max-size>
<idle-timeout-minutes>1</idle-timeout-minutes>
</db-connection>
The OracleXADataSource is implementing the inteface DataSource so its quit easy... but im not sure that generic enough.
EDIT
I wonder what should be the way to achive that if i have multipile db connections and multipile instances / schemas in those connections.....
my current code looks like:
private DataSource getDataSourceForTanent(TenantConfig i_Tenant) {
DataSource result = null;
ClassLoader loader = DBConnector.class.getClassLoader();
try {
Class driverClass = loader.loadClass(i_Tenant.getDriver());
Object driver = driverClass.newInstance();
if(driver instanceof OracleDataSource){
((OracleDataSource)driver).setURL(i_Tenant.getUrl());
((OracleDataSource)driver).setUser(i_Tenant.getUser());
((OracleDataSource)driver).setPassword(i_Tenant.getPassword());
result = (DataSource) driver;
} else if(driver instanceof Driver){
Properties prop = new Properties();
prop.put("user", i_Tenant.getUser());
prop.put("password", i_Tenant.getPassword());
prop.put("min-size", i_Tenant.getMinSize());
prop.put("max-size", i_Tenant.getMaxSize());
prop.put("idle-timeout-minutes", i_Tenant.getIdleTimeoutMinute());
Connection con = ((Driver)driver).connect(i_Tenant.getUrl(), prop);
if(con != null){
//TODO: SQLServer handling
}
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
TenantConfig is a java bean holding the xml properties.
Here's a generic code snippet to get a DataSource by JNDI name:
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");
DataSource ds = (DataSource)envContext.lookup("jdbc/mydatasource");
But from your XML file I am not sure what the JNDI name is. What XML dialect is it?
Related
In my spring project, I have a service class to create my database and tables. After create the database (which is being done successfully), this method is called:
public void create_tables(String maquina, String usuario, String senha) {
System.out.println("create_tables");
create_properties(maquina, usuario, senha);
Configuration config = new Configuration();
Properties props = new Properties();
FileInputStream fos;
try {
fos = new FileInputStream( "database.properties" );
props.load(fos);
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
config.setProperties(props);
try {
String url = props.getProperty("jdbc.url");
Connection conn = DriverManager.getConnection(url,usuario,senha);
SchemaExport schema = new SchemaExport(config, conn);
schema.create(true, true);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
insert_default_values();
}
But, despite in the Eclipse console display that the schema was exported successfully, no table is created in my database.
Anyone can see what's wrong here?
UPDATE
database.properties
#propriedades
#Sat May 10 12:52:57 BRT 2014
jdbc.url=jdbc\:postgresql\://localhost\:5432/horario
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
hibernate.show_sql=false
jdbc.user=<<my database user>>
jdbc.Classname=org.postgresql.Driver
hibernate.hbm2ddl.auto=update
jdbc.pass=<<my password>>
HibernateConfig.java -> https://github.com/klebermo/webapp_horario_livre/blob/master/src/com/horariolivre/resources/HibernateConfig.java
Entity classes -> https://github.com/klebermo/webapp_horario_livre/tree/master/src/com/horariolivre/entity
Dao classes -> https://github.com/klebermo/webapp_horario_livre/tree/master/src/com/horariolivre/dao
Try adding following code snippet:
config.addAnnotatedClass(com.horariolivre.entity.Atributo.class);
config.addAnnotatedClass(com.horariolivre.entity.Autorizacao.class);
...
Is this what you are looking for?
I have a requirement of trying to achieve transaction propagation across multiple stateful beans
I have 3 Stateful EJB;s in my application.. The start and end transaction is controlled be an external java application through remote interface method invocation.
#Remote
#Stateful
public class MyEJB1 implements RemoteEJB1{
#EJB
private RemoteEJB2 ejb2;
#Resource
UserTransaction utx;
public void startTransaction() {
try {
utx.begin();
} catch (NotSupportedException e) {
throw new EJBException(e);
} catch (SystemException e) {
throw new EJBException(e);
}
}
public void commitTransaction() {
try {
utx.commit();
} catch (SecurityException e) {
throw new EJBException(e);
} catch (IllegalStateException e) {
throw new EJBException(e);
} catch (RollbackException e) {
throw new EJBException(e);
} catch (HeuristicMixedException e) {
throw new EJBException(e);
} catch (HeuristicRollbackException e) {
throw new EJBException(e);
} catch (SystemException e) {
throw new EJBException(e);
}
}
public RemoteEJB2 getEJB2() {
return ejb2;
}
}
public class MyEJB2 implements RemoteEJB2{
#EJB
private RemoteEJB3 ejb3;
#Resource(name = "java:jboss/datasources/MyDS")
private DataSource ds;
public RemoteEJB3 getEJB3() {
return ejb3;
}
#TransactionAttribute(TransactionAttributeType.MANDATORY)
public void insertElement(String elementName) {
PreparedStatement pStat = null;
Connection con = null;
try {
con = ds.getConnection();
String sql = "insert into TRANSACTIONTEST(COL1,COL2) values(?,?)";
pStat = con.prepareStatement(sql);
pStat.setString(1, elementName);
pStat.setDouble(2, Math.random());
pStat.executeUpdate();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class MyEJB3 implements RemoteEJB3{
#Resource(name="java:jboss/datasources/MyDS")
private DataSource ds;
#TransactionAttribute(TransactionAttributeType.MANDATORY)
public void updateElement(String newName) {
PreparedStatement pStat = null;
Connection con = null;
try{ con = getDs().getConnection();
String sql ="update TRANSACTIONTEST set COL1=?";
pStat = con.prepareStatement(sql);
pStat.setString(1, newName);
pStat.executeUpdate();
}catch(Exception ex){
ex.printStackTrace();
}finally{
try {
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Test Class:
public class MyTest{
public static void main(String[] args) throws Exception {
final Hashtable jndiProperties = new Hashtable();
jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
final Context context = new InitialContext(jndiProperties);
MyEJB1 ejb1 = context.lookup("ejb:/EJBTrials/MyEJB1!edu.in.ejbinterfaces. RemoteEJB1?stateful");
ejb1.startTransaction();
RemoteEJB2 ejb2 = ejb1.getEJB2();
ejb2.insertElement (“Test”);
RemoteEJB3 ejb3 = ejb2.getEJB3();
ejb3.updateElement (“UpdatedTest”);
ejb1.commitTransaction();
}
}
I would ideally like the whole transaction(record insertions in db) to be completed after invocation of commitTransaction() on RemoteEJB1 bean.
I tried combination of BMT for EJB1 and CMT for EJB2 and EJB3 which lead to EJBTransactionRequiredException being thrown
I tried to make all beans as BMT. However according to EJB3.1 spec BMT cannot be propagated across multiple beans.
Could you let me know of any ideas/links which I could use to solve this problem?
Reference Application Server : JBOSS AS 7.1
Could you let me know of any ideas/links which I could use to solve this problem?
If I understand your issue correctly, wath you need is called Client-Managed trasaction demarcation. UnLike Container Maneged Transaction, in this case the client is responsable to set the transaction boundaries (start and commit/rollback the transaction). You can get some ideas of how to implement it here.
I write a code to connect to database from servlet.I want to use properties.but it does not work.i think i my code or properties file has problem.please help me to correct it.
try
{
Properties prop=new Properties();
FileInputStream in = new FileInputStream(System.getProperty("WEB-INF/dbConnection.properties"));
prop.load(in);
in.close();
String drivers = prop.getProperty("jdbc.drivers");
String connectionURL = prop.getProperty("jdbc.url");
String username = prop.getProperty("jdbc.username");
String password = prop.getProperty("jdbc.password");
Class.forName(drivers);
con=DriverManager.getConnection(connectionURL,username,password);
System.out.println("Connection Successful");
..
and this is my properties file
jdbc.driverClassName=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:#192.168.101.84:1521:orcl
jdbc.username=user1
jdbc.password=123
Instead of
FileInputStream in = new FileInputStream(System.getProperty("WEB-INF/dbConnection.properties"));
use
InputStream in = getClass().getResourceAsStream("dbConnection.properties");
try {
FileReader reader = new FileReader("Full Path");
Properties prop = new Properties();
prop.load(reader);
String drivers = prop.getProperty("jdbc.driverClassName");
String connectionURL = prop.getProperty("jdbc.url");
String username = prop.getProperty("jdbc.username");
String password = prop.getProperty("jdbc.password");
Class.forName(drivers);
Connection con = DriverManager.getConnection(connectionURL, username, password);
System.out.println("Connection Successful");
} catch (SQLException sqle) {
// TODO: Add catch code
sqle.printStackTrace();
} catch (FileNotFoundException fnfe) {
// TODO: Add catch code
fnfe.printStackTrace();
} catch (IOException ioe) {
// TODO: Add catch code
ioe.printStackTrace();
} catch (ClassNotFoundException cnfe) {
// TODO: Add catch code
cnfe.printStackTrace();
}catch (Exception e) {
// TODO: Add catch code
e.printStackTrace();
}
This part:
(System.getProperty("WEB-INF/dbConnection.properties"));
is actually referring to your classpath, try removing WEB-INF/ or just leave /, for checking root folder.
Or you can specify the fully qualified name, i.e : "C:\\foo\\test\\...\\dbConnection.properties" or "/app/blah/.../dbConnectionProperties"
For Class name, in the properties file you have defined the driver as 'jdbc.driverClassName'
but when passing variable you just pass as 'jdbc.drivers'
I have a Servlet which initializes its DataSource in the Servlets init method (because it is accessed there the first time). When the servlet is getting loaded I get the following exception message
Cannot create JDBC driver of class '' for connect URL 'null'
But when the first request is processed the jndi lookup works fine and the DataSource is initialized properly.
Here is my DataSource class:
public class PostgresDataSource{
private static DataSource dataSource;
static {
try {
dataSource = (DataSource) new InitialContext().lookup("java:/comp/env/jdbc/somedb");
} catch (NamingException e) {
Log.logger.fatal("Failed to initialize DB!");
Log.logger.error(e.getMessage());
e.printStackTrace();
}
}
public static Connection checkOut(){
if ( dataSource != null )
{
try {
return dataSource.getConnection();
} catch (SQLException e) {
Log.logger.error("Failed to establish DB connection!");
Log.logger.error(e.getMessage());
e.printStackTrace();
return null;
}
}
else
{
Log.logger.error("Failed to check out DB-Connection: Postgres DataSource not initialized!");
return null;
}
}
public static void checkIn( Connection dbcon){
if ( dataSource != null )
{
try {
dbcon.close();
} catch (SQLException e) {
Log.logger.error("Failed to close DB connection!");
e.printStackTrace();
}
}
else
{
Log.logger.error("Cannot check in DB-Connection: Postgres DataSource not initialized!");
}
}
}
Anyone encountered the same problem? What's the reason for this and how to solve it?
Instead of using
dataSource = (DataSource) new InitialContext().lookup("java:/comp/env/jdbc/somedb");
Please use the following, this may solve the problem
InitialContext context = new InitialContext();
Context envCtx = (Context) context.lookup("java:comp/env");
dataSource = (DataSource) envCtx.lookup("jdbc/somedb");
how can I place my mysql database url, username and password in a file and how can I access them to use in my java code instead of hard coding them. I've tried google but am not getting clear direction
Create a properties file. You can load it by the Properties API.
E.g. config.properties:
url = jdbc:mysql://localhost:3306/dbname
username = foo
password = bar
Then you can load and read it as follows (after you've placed it in the classpath):
Properties config = new Properties();
config.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("config.properties"));
String url = config.getProperty("url");
String username = config.getProperty("username");
String password = config.getProperty("password");
// ...
/**
* Function that connects to a DB and data fro connection is loaded from a properties file
* #param fileName
* #return the connection to DB or null if any problem
*/
public java.sql.Connection connect_to_database_from_properties(String fileName)
{
Properties prop = new Properties();
InputStream is;
try {
is = new FileInputStream(fileName);
prop.load(is);
String url=prop.getProperty("url");
String un=prop.getProperty("username");
String pass=prop.getProperty("password");
System.out.println("URL: "+url+" UN: "+un+" PASS: "+pass);
is.close();
Class.forName("com.mysql.jdbc.Driver");
java.sql.Connection conection =DriverManager.getConnection(url, un, pass);
return conection;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}