how can get the datasource configuration for spring from persistence.xml? - java

I need a spring datasource like:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="<driver>"/>
<property name="url" value="<url>" />
<property name="username" value="<user>" />
<property name="password" value="<pass>" />
</bean>
I need to obtain driver, url, user, pass from persistence.xml.
Tanks a lot!

Here is my snippet for doign the same, you will obviously have to use your BasicDataSource instead of the ComboPooledDataSource I use. But they are pretty much the same, replace getDriverClass() with driverClassName, apparently.
#Autowired
private ComboPooledDataSource dataSource;
public String myMethod() {
return dataSource.getDriverClass());
}

Do you want to print it, or use it in your application for connecting to the dB?
If later one is the case, then, create a bean for sessionFactory, set hibernateProperties for the same where you can inject datasource as well.
In java code, autowire sessionFactory object (or set it using a setter method) and call getCurrentSession method for the same.
For getting various attributes, use chained getter methods to return datasource and extract all the details.
Let me know if you face any issue or need more details for the same.

Related

Does datasource need to be in prototype scope in spring jdbc

When we using spring jdbc , first we define a dataSource bean and inject it when creating jdbcTemplate object . What I want to know is do we need to define this dataSource in prototype scope. Unless there is only one dataSource object for whole application . I think this affects to reduce application performance.
Here is how I have defined dataSouce inside spring configuration file.
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/testdb" />
<property name="username" value="root" />
<property name="password" value="123" />
</bean>
In my DAO class I have autowired dataSOurce as below.
#Repository
public class RecordDAOImpl {
JdbcTemplate jdbcTemplate = null;
#Autowired
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
}
Let me know what is the best way to define dataSource for spring mvc web application.
What I want to know is do we need to define this dataSource in prototype scope
No we don't need. I guess it wouldn't be good idea, we can use some kind of connection pool datasource and singleton scope bean.
We can also have multiple databases and provide for each own datasource singleton scoped, there is not any problem with that.
Let me know what is the best way to define dataSource for spring mvc web application.
There is nothing wrong with defining your data Sources in xml files (although many devs seem to avoid xml). I like to do it using java config, since I feel like its easier to read.
Depending on driver and database it would look more or less like that:
#Configuration
class DatasourceConfig {
#Bean
DataSource datasource() {
PGPoolingDataSource dataSource = new PGPoolingDataSource();
dataSource.setPassword("pass");
dataSource.setPortNumber(123);
dataSource.setUser("user");
dataSource.setMaxConnections(10);
return dataSource;
}
}

How to verify whether a connection pool has beem set up in spring MVC web app?

In one of my question asked earlier I got to know that DriverManagerDataSource is NOT intended for production use. So I changed my configuration. I know I am using DBCP which is also outdated and a lot of other connection pools are available like HIkariCP and BOneCP but
I wish to understand the way how to verify that a pool has been setup
or not?
On searching a lot I got some answer at the following link
How would you test a Connection Pool
but I didn't get a way to verify programmatically. Also I cannot debug my jar files used for connection pooling because no source code is available. I dont know why but I can't change my jars for offical reasons.
The following are my configuration (OLD and NEW)
OLD
<bean id="webLogicXADataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="#[csa.db.driver]" />
<property name="url" value="#[csa.db.url]" />
<property name="username" value="#[csa.db.username]" />
<property name="password" value="#[csa.db.password]" />
</bean>
NEW
Using DBCP connection pool
<bean id="webLogicXADataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="#[csa.db.driver]" />
<property name="url" value="#[csa.db.url]" />
<property name="username" value="#[csa.db.username]" />
<property name="password" value="#[csa.db.password]" />
</bean>
OTHER ELEMENTS:(Thus far I have kept them same like they were earlier)
Place holder
<bean id="placeholderConfig"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>file:${DB_PROPERTIES}</value>
</list>
</property>
<property name="placeholderPrefix" value="#[" />
<property name="placeholderSuffix" value="]" />
</bean>
Transaction Manager
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="webLogicXADataSource" />
<qualifier value="inventoryTxManager"/>
</bean>
DAOIMPL SAMPLE BEAN
<bean id="inventoryDao"
class="com.lxnx.fab.ce.icce.inventoryRoutingInvoice.dao.InventoryDaoImpl">
<property name="dataSource" ref="webLogicXADataSource" />
<property name="transactionManager" ref="transactionManager" />
Right now all the DAO classes in my project are singleton(no prototype property set for any of the beans)
The following is the sample java code of the DAOImpl.java class where I need to do all the transactions:
DAOImpl.java
public class InventoryDaoImpl implements InventoryDao {
private final static ISmLog iSmLog = Instrumentation
.getSmLog(LNConstants.SYSTEM_LOG_NAME);
private JdbcTemplate jdbcTemplate;
private DataSource dataSource;
private PlatformTransactionManager transactionManager;
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
this.dataSource = dataSource;
}
public void setTransactionManager(
PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
#Transactional private void insertRelatedInfoData(
InventoryModel inventoryModel) {
final List<String> relatedLniList = inventoryModel.getArrRelatedLni();
final String documentLni = inventoryModel.getDocumentLNI();
String sql = "INSERT INTO SCSMD_REPO.INV_RELATED_INFO(LNI, RELATED_LNI) VALUES(?,?)";
jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
#Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
String relatedLni = relatedLniList.get(i);
ps.setString(1, documentLni);
ps.setString(2, relatedLni);
}
#Override
public int getBatchSize() {
return relatedLniList.size();
}
});
}
}
I am not getting any errors. Just wanted to verify If a pool has been setup U wish to verify the same
Are all configurations fine or did I miss something?? Please help me out with you valuable answers. thanks
If you don't have logs enable then you can't verify it. however there is one more donkey logic.
every database server will have timeout functionality. if db not hit by application after some time connection will break. for example mysql server will break it's connection from application after 8 hour (if there is no hit from application). you check modify timeout to minimum time (say 30 min)in mysql config file and check after 30 minutes you get connection close exception in you appication, when you hit db
The easiest way, as explained, would be to examine the logs. It's quite likely that a connection pool will log something, at least if your logging level is low enough.
Another way would be to examine the class of the Connection that the datasource returns. If you're dealing with a connection pool, the class will be a wrapper or a proxy class for that pool. The wrapper/proxy class makes sure that when you call close() the connection isn't really closed, it's just returned to the pool for further use. For example if you were to use HikariCP as your pool, you could check if(connection instanceof IHikariConnectionProxy) to see if the pool is being used.
Adding that kind of code in your software would be a bad idea in practically all cases. If you don't know whether a connection pool is being used or not, it's not something you solve with code. It's something you solve by reading and studying more.
You've also named your bean webLogicXADataSource even though nothing seems to support it being an XA datasource. Are you perhaps working on things a bit too advanced for you?

Spring declare component in xml

I am mostly using #Autowired and #Component annotations in my project. However, I am going to use DataSource class for database actions.
So, I use this is in my dispatcher-servlet.xml :
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/market"/>
<property name="username" value="root"/>
<property name="password" value=""/>
</bean>
In my dao class, My setter for the dataSource is :
#Autowired
private DataSource dataSource;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
this.jdbcTemplateObject = new JdbcTemplate(dataSource);
}
However this is not doing the trick. My jdbcTemplateObject is null.
If I dont use "context:component scan ..." and use classical spring beans instead, without utilizing #Autowired annotation, all works good.
I can use my database. However, I dont want to declare all the beans one by one in my xml file. As the project grows, it is not going to be practical. How can I solve this problem ? Is it possible to declare dataSource in my dispatcher-servlet.xml as component, so #Autowired works on dataSource ?
When you use #Autowired on fields Spring will look for dependencies and inject them right there there is no point if setter method here.
You do not need to worry about how spring is going to inject the dependency. It will take care of complete life cycle.
For more on Spring's Dependecy Injection visit this link.
You have annotated the field with #Autowired which tells spring to inject the dependency directly into the field. If you really want to use the setter annotate the setter with #Autowired instead of the field.
#Autowired
public void setDataSource(DataSource ds) { ... }
However I strongly suggest to not create a JdbcTemplate for each bean that needs one (it is quite heavy to create). The JdbcTemplate is a thread-safe object, once constructed. So instead of creating a new one for each bean that needs one (in the setDataSource method) just create a single JdbcTemplateand inject that.
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
Then in your dao.
#Autowired
private JdbcTemplate jdbcTemplate;
Or what I like to do..
private final JdbcTemplate jdbcTemplate;
#Autowired
public YourRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate=jdbcTemplate;
}
This way you cannot construct an illegal object, whereas with setter based injection you could. While maintaining the possibility to inject one for testing purposes.
Another note, the DriverManagerDataSource is nice for testing but not for production usage, for that use a real connection pool like HikariCP or Tomcat JDBC.

Insert external data into persistence.xml

I want my persistence.xml to set some of its properties dynamically, to be specific:
<property name="hibernate.connection.password" value="password"/>
<property name="hibernate.connection.username" value="username"/>
I can build a class that could provide me the data I need, but I don't know how to set the class up in a way that it works like this:
<property name="hibernate.connection.password" value="${my.clazz.pass}"/>
<property name="hibernate.connection.username" value="${my.clazz.user}"/>
I have tried to set the class up like this
public class clazz{
String pass;
String user;
public clazz(){
//do stuff to set pass and user
}
//getter/setter
}
But that does not work. I haven't found a way here or in google, but I have seen the ${my.clazz.smth}-way several times.
So, how can I set that up? :)
Thanks in advance!
So, resolved this a while ago, but I still didn't answer:
Anthony Accioly pointed me to the right direction:
I added this to my applicationContext.xml's entityManagerFactory
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitPostProcessors">
<bean class="my.package.SetupDatabase">
</bean>
</property>
//the other stuff
</bean>
The corresponding class, in this case I use hibernate:
package my.package;
public class SetupDatabase implements PersistenceUnitPostProcessor {
private String username;
private String password;
private String dbserver;
public void SetupDatabase(){
//do stuff to obtain needed information
}
public void postProcessPersistenceUnitInfo(MutablePersistenceUnitInfo pui) {
pui.getProperties().setProperty("hibernate.connection.username", username );
pui.getProperties().setProperty("hibernate.connection.password", password);
pui.getProperties().setProperty("hibernate.connection.url", dbserver );
}
}
This way the setup is done just once when starting the whole thing up, but the required data may be 'outsourced'.
Thanks again for pointing me to the right direction!
The value placeholder ${my.clazz.smth} that you refer to is usually read from a properties file as opposed to a class directly.
This is done using Spring's PropertyPlaceholderConfigurer.
Here is an example of a project which combined the Hibernate & Spring.
If you really need to delay the configuration until runtime (e.g., to obtain the database credentials from an external source such as a Web service) you can do it with Hibernate API Programatic Configuration, particularly Ejb3Configuration for legacy versions of Hibernate or ServiceRegistryBuilder (v 4.X)...
But be warned that, to the best of my knowledge, there is no way to dynamically update the username and password of a PersintenceUnit. You will have to build another EntityManagerFactory from a new Configuration instance (a quite expensive operation) every time that you need to change it's properties.
Anyway, unless you have a really good reason to, do not manage database credentials from your application, delegate it to a JNDI-Bound DataSource instead.
Ejb3Configuration cfg = new Ejb3Configuration()
// Add classes, other properties, etc
.setProperty("hibernate.connection.password", "xxxx")
.setProperty("hibernate.connection.username", "yyyy");
EntityManagerFactory emf= cfg.buildEntityManagerFactory();

Spring Security 3.0 with jdbc

I read the "Spring Security 3 database authentication with Hibernate"! But I don't know how I should implementate it into my project!
In which document I have to set the password/username/drivers/url for the database?
I have different column titles like OPERATOR_ID/USR_ID/PASSWORD
OPERATOR_ID should be the login name, USR_ID the role and the password for the login
Please, maybe you could post an example which implements my questions? Maybe for a checkout or a *.war file?
I dont think there is any configuration as such for doing this. You have to implement the UserDetailsService which has only one method loadUserByUsername to load the user and you have to implement the same to load your user information from your database using hibernate.
See here
You would need to configure a JDBCDaoImpl bean which takes a Datasource as a parameter. How you retrieve the Datasource is up to you, you may grab it from the app server or use something like Spring's DriverManagerDatasource Here is some (pseudo) config
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"><value>your.driver.classname</value></property>
<property name="url"><value>yourDatabaseUrl</value></property>
<property name="username"><value>yourUsername</value></property>
<property name="password"><value>yourPassword</value></property>
</bean>
<bean id="dao" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
<property name="DataSource" ref="datasource" />
...
</bean>

Categories

Resources