I am using an Oracle connection pool by using the following Spring configuration for my datasource:
<bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource">
<property name="connectionCachingEnabled" value="true" />
<property name="URL" value="myUrl" />
<property name="user" value="myUserName" />
<property name="password" value="myPassword" />
<property name="connectionCacheProperties">
<util:properties>
<prop key="InitialLimit">5</prop>
<prop key="MinLimit">5</prop>
<prop key="MaxLimit">30</prop>
<prop key="MaxStatementsLimit">20</prop>
</util:properties>
</property>
</bean>
I would like to expose the statistics of this pool via JMX so that I can monitor the pool to see how many connections are in the pool, how many are busy, etc.
I am connecting to an Oracle 10g server with the oracle 11.2.0.3.0 jdbc driver.
How do I do this?
Try this -
MethodNameBasedMBeanInfoAssembler
public class MethodNameBasedMBeanInfoAssembler
Subclass of AbstractReflectiveMBeanInfoAssembler that allows to
specify method names to be exposed as MBean operations and attributes.
JavaBean getters and setters will automatically be exposed as JMX
attributes.
You can supply an array of method names via the managedMethods
property. If you have multiple beans and you wish each bean to use a
different set of method names, then you can map bean keys (that is the
name used to pass the bean to the MBeanExporter) to a list of method
names using the methodMappings property.
If you specify values for both methodMappings and managedMethods,
Spring will attempt to find method names in the mappings first. If no
method names for the bean are found, it will use the method names
defined by managedMethods.
For example -
...
<bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean">
<property name="locateExistingServerIfPossible" value="true" />
</bean>
<bean id="mbeanExporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="assembler">
<bean class="org.springframework.jmx.export.assembler.MethodNameBasedMBeanInfoAssembler">
<property name="managedMethods">
<list>
<value>getNumActive</value>
<value>getMaxActive</value>
<value>getNumIdle</value>
<value>getMaxIdle</value>
<value>getMaxWait</value>
<value>getInitialSize</value>
</list>
</property>
</bean>
</property>
<property name="beans">
<map>
<entry key="dataSource:name=DataSource" value-ref="dataSource"/>
</map>
</property>
<property name="server" ref="mbeanServer" />
</bean>
For Enabling JMX in Hibernate, EhCache, Quartz, DBCP and Spring
Kindly refer the http://nurkiewicz.blogspot.com/2011/12/enabling-jmx-in-hibernate-ehcache-qurtz.html
Related
below is my hibernate.xml file this file , for any query in sql i will use session factory for query but in this i am using a property name dataSource where it is refered to database connection,so for every query i am calling session factory and and for every call it is calling dataSource and making a new connection rather than that i want to make only one connection and make multiple queries one for each request is it possible
i am using hibernate for sql queries
i am using below hibernate.xml as i have learnt from http://www.mkyong.com/spring/maven-spring-hibernate-mysql-example/
hibernate.xml:
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>resources/database/Token.xml</value>
</list>
</property>
</bean>
datasource.xml:
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/get"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
<property name="initialSize" value="3"/>
<property name="minPoolSize" value="1" />
<property name="maxPoolSize" value="3" />
</bean>
</beans>
Update: i have made my code connection pooling but how to make it open only one connection at start of application and use same connection for every request
as you can see for every call to session factory it calls dataSource and it makes a connection i want to stop it
Two considerations.
First of all is that you can configure all your beans in only one xml file, not need to keep different files for hibernate and spring (the Spring one is enough).
Second: you can use a datasource that supports pooling connection and more configuration like C3P0.
An example of how to declare it is:
<bean id="yourDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/get" />
<property name="user" value="username" />
<property name="password" value="password" />
<property name="minPoolSize" value="1" />
<property name="maxPoolSize" value="3" />
<property name="preferredTestQuery">
<value>select null from dual</value>
</property>
<property name="testConnectionOnCheckin">
<value>true</value>
</property>
<property name="idleConnectionTestPeriod">
<value>1000</value>
</property>
</bean>
If you want to reuse connections, you need to use DataSource implementation which supports connection pooling.
The example here is for dbcp library. There is also Tomcat implementation.
In order to use it you need to add the library to the dependencies and update the configuration of the DataSource with the implementation class and the configuration values for the connection pool.
I am not sure I understand your issue but, how are you configuring your sessionfactory? Is your sessionfactory a spring bean?
If it is spring bean, then it is singleton by default, which means only one instance of sessionfactory exists for the entire application and is shared. In that case your assumption that you are creating a new sessionfactory which then creates a new datasource is wrong.
If you are manually creating your sessionfactory in code, then you need to implement the singleton design pattern by yourself.
private static SessionFactory seesionFactory = null;
private static final SessionFactory makeSessionFactory()
{
try {
if (sessionFactory==null)
seesionFactory = new Configuration().configure().buildSessionFactory();
} catch (HibernateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return seesionFactory;
}
I am configuring Spring to use JPA by using Hibernate implementation. However I don't understand the process completly. I have gotten it to work by following different blogs etc. I have used EJB 3.1 and there I had a persistence.xml. However in spring I declared a LocalContainer...Bean and provided some properties to it, and I have no persistence.xml. Could someone explain how it works in Spring and what the declared bean is?
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="packagesToScan" value="com.company.domain" />
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.PostgreSQL82Dialect
</prop>
</props>
</property>
</bean>
There are different flavors of Spring Configuration with JPA, one which requires persistence.xml and other which requires just bean declarations(no persistence.xml).
I am going to take up the Case-2 in your scenario:
The main reasons we want a persistence.xml is because of the following reasons:
Database connectivity details.
Java classes which are treated as Entities or packages in which to scan for Entities.
Other vendor specific settings like hibernate.show_sql or similar stuff.
Now if spring provides a way to mention all this together in bean configurations then there is no need to have the persistence.xml.
In case of your bean definitions, lets break it down.
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="packagesToScan" value="com.company.domain" />
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.PostgreSQL82Dialect
</prop>
</props>
</property>
</bean>
First property, dataSource already contains the database settings.
Second property, jpaVendorAdapter is a property specific to Spring
Third property, packagesToScan this is a property of Spring to scan for entities, this we either do in persistence.xml by using "class" tags by mentioning each class FQN.
Fourth property, jpaProperties as the name suggests can either be in Spring or in persistence.xml
e.g.
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL82Dialect" />
Since you have all the configurations already in Spring bean, there's no need to have a persistence.xml
Just to add a FootNote:
Spring 3.1 provides an alternative: LocalContainerEntityManagerFactoryBean that accepts a 'packagesToScan' property, specifying base packages to scan for #Entity classes.
Hope this answer your queries.
I was wondering how one would go about getting an object from a remote JNDI in Spring 3. Where do you specify the URL, how do you set it all up in a context file, etc. I have found some disperate information suggesting this is possible, but no singular source for how to do it for a JNDi that is on a different server.
You could use, for example, the JndiObjectFactoryBean class within a basic configuration like this one:
<bean id="someId" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="yourLookupNameGoesHere" />
<property name="jndiEnvironment">
<props>
<prop key="java.naming.provider.url">yourRemoteServerGoesHere:PortGoesHere</prop>
<prop key="java.naming.factory.initial">yourNamingContextFactoryGoesHere</prop>
<prop key="java.naming.factory.url.pkgs">yourPackagePrefixesGoHere</prop>
<!-- other key=values here -->
</props>
</property>
<!-- other properties here-->
</bean>
You can then specify other environment properties as needed and you can also simplify your configuration by using the Spring jee schema.
expanding on the above with an example for connecting to a remote activeMQ server in JBoss EAP7 using CAMEL Jms component.
You will need these 3 beans in your Spring XML application context:
<bean id="remoteQCF" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="${factoryJndiName}" />
<property name="jndiEnvironment">
<props>
<prop key="java.naming.provider.url">http-remoting://${remoteHost}:${remotePort}</prop>
<prop key="java.naming.factory.initial">org.jboss.naming.remote.client.InitialContextFactory</prop>
<!-- other key=values here <prop key="java.naming.factory.url.pkgs">yourPackagePrefixesGoHere</prop> -->
</props>
</property>
</bean>
<bean id="remoteQCFproxy"
class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
<property name="targetConnectionFactory" ref="remoteQCF" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</bean>
<bean id="jmsremote" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory" ref="remoteQCFproxy" />
</bean>
where each ${xxx} denotes a value that you shall supply in place or with a property placeholder in your application context.
If you do not need a user and password to open a JMS queue connection, you may omit the second bean and reference directly the first bean as connectionFactory in the Camel JmsComponent bean.
The 'jmsremote' bean can then be used in CAML URI's like "jmsremote:queue:myQueue1"
What is this error about? "No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here".
My spring config file looks something like this.
<bean id="jndiDataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:/devDS</value>
</property>
</bean>
<bean id="stsaDBFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="jndiDataSource" />
<property name="annotatedClasses">
<list>
<value>xx.yy.zz.User</value>
<value>xx.yy.UserResponse</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbmddl.auto">create</prop>
</props>
</property>
</bean>
<!-- ################################### Aspects ################################################## -->
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="stsaDBFactory" />
</property>
</bean>
All the DAO test passes when i test them outside of the container using junit. When I deploy it in jBoss as a portal app,I get this exception. Also it works fine if i remove the portal specific configuration and make it a simple web app and deploy it on jboss.Any idea?
You have defined a TransactionManager in your spring config but you are trying to execute a hibernate query in a method that is not transactional. Try adding #Transactional to your method or class.
I got around this problem by specifying the current_session_context_class in hibernate config to be "thread", as per the simple configuration shown in the hibernate configuration documentation.
But it recommends that its not safe for production usage.
Trying to add the following in your hibernate config should also help:
<property name="current_session_context_class">org.hibernate.context.ThreadLocalSessionContext</property>
Check out http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/architecture.html#architecture-current-session for more details.
I am currently in the process of upgrading an application from Hibernate 3.2 to Hibernate 3.3. I though I'd stick with the default connection pool (Hibernate changed its default from Commons DBCP to c3p0) as I don't have any good reason to choose a non-default pool. At least non but having used DBCP before.
The upgrade went pretty much without any problems so far. The only thing I can't get to work is passing properties to the underlying MySQL JDBC4Connection. Up to now, I used DBCP's BasicDataSource.addConnectionProperty(String,String) to pass properties (useUnicode=true, characterEncodin=UTF-8, characterSetResults=UTF-8, zeroDateTimeBehavior=convertToNull).
However, I can't find any way to do the same with c3p0 other than including them in the JDBC URL. (That's something I'd like to avoid as I wanna keep the URL configurable without forcing users to include those parameters.)
So far, I've tried to use a ConnectionCustomizer without success. Any other suggestions?
Once again a question I answer myself (another self-learner? yes, please!):
com.mchange.v2.c3p0.ComboPooledDataSource has a property "properties". Interestingly, setting properties after user and password overrides them. But setting properties before user and password works as expected.
Follow up for the self answer.
An example of a spring way of configuring this:
The Data source bean:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="properties" ref="mysqlConnectionProperties"></property>
<property name="driverClass" value="${jdbc.driver}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- c3p0 combo pooled data source settings -->
<property name="initialPoolSize" value="3" />
<property name="minPoolSize" value="3" />
<property name="maxPoolSize" value="50" />
<property name="maxIdleTime" value="7200" />
<property name="maxStatements" value="200" />
<property name="idleConnectionTestPeriod" value="270" />
<property name="preferredTestQuery">
<value>SELECT 1</value>
</property>
</bean>
The properties bean:
<bean id="mysqlConnectionProperties" class="java.util.Properties">
<constructor-arg>
<props>
<prop key="useTimezone">true</prop>
<prop key="serverTimezone">America/Chicago</prop>
<!-- add any other properties you have -->
</props>
</constructor-arg>
</bean>