the count sessionFactory.getStatistics().getTransactionCount() is 0 - spring

This question is to improve my understanding of how the transactions are managed within the sessions in spring hibernate. When I print getSessionFactory()getStatistics().getTransactionCount() , it prints '0' when getSessionFactory().getCurrentSession().getTransaction().isActive() is 'true'. I am really confused. Kindly clear the same for me .
Following is the piece of code in which I want the transaction to happen:
#Transactional(propagation=Propagation.REQUIRED)
public int insertNewRecord(){
System.out.println(getSessionFactory().getCurrentSession().getTransaction().isActive());//gives `true`
System.out.println(getSessionFactory().getCurrentSession().getStatistics()); //Gives statistics
System.out.println(getSessionFactory().getStatistics().getSessionOpenCount());// Gives 1
System.out.println(getSessionFactory().getStatistics().getTransactionCount());// Gives 0
}
My spring and Hibernate configuration:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mappingLocations">
<list><value>classpath:Employee.hbm.xml</value></list>
</property>
<property name="hibernateProperties">
<props>
<!-- SQL dialect -->
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<!-- Enable Hibernate's current session context -->
<!-- <prop key="hibernate.current_session_context_class">org.hibernate.context.internal.ThreadLocalSessionContext</prop> --><!-- org.hibernate.context.internal.ThreadLocalSessionContext -->
<!-- Disable the second-level cache -->
<prop key="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
<!-- Echo all executed SQL to stdout -->
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.generate_statistics">true</prop>
</props>
</property>
</bean>
Below is the transaction manager:
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="dataSource" ref="dataSource" />
<property name="sessionFactory" ref="sessionFactory" />
</bean>

Well, you might want to try executing that code a few times, since the getTransactionCount() method is documented as:
The number of transactions we know to have completed
So if you started with zero, but then you take a count in the middle of a transaction, the transaction has not completed yet, so the count would still be zero.
You might also want to add a call to isStatisticsEnabled() and print the result, just to double-check that stats are enabled.

Related

Upgrading hibernate version to 5.4 gives me 'no transaction is in progress'

I am trying to upgrade spring version(4.3) and hibernate version(5.4) and I am getting 'no transaction is in progress' exception, I am using HibernateTransactionManager and also I have tried with setting hibernate.transaction.coordinator_class to 'jta' as well as 'jdbc'. my configs are below
<bean id="MyTransactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="myAppSessionFactory"/>
</bean>
<bean id="myAppSessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" lazy-init="true">
<property name="mappingLocations">
<list>
<value>classpath:/mappings/UserGroupMembershipPOJO.hbm.xml</value>
<value>classpath:/mappings/UserGroupPOJO.hbm.xml</value>
<value>classpath:/mappings/UserDetailsPOJO.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.use_outer_join">false</prop>
<prop key="hibernate.jdbc.fetch_size">5</prop>
<prop key="hibernate.jdbc.batch_size">0</prop>
<prop key="hibernate.transaction.coordinator_class">jta</prop>
</props>
</property>
<property name="dataSource">
<ref bean="myDataSource"/>
</property>
</bean>
Hibernate now conforms with the JPA specification to not allow flushing updates outside of a transaction boundary. To restore 5.1 behavior, allowing flush operations outside of a transaction boundary, set hibernate.allow_update_outside_transaction=true.
hibernate-orm/migration-guide.adoc at 5.2 ยท hibernate/hibernate-orm

how to set sessionFactory instance only once for entire application?

I am Injecting sessionFactory Through xml file(applicationContext.xml) using this package org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean.
is there anyway to set the sessionFactory only once for entire web application? how can I achieve this ?
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<list>
<value>com.mahesh</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
</props>
</property>
</bean>
Unless you tell Spring otherwise, it will create each bean once per context (i.e. they will be singletons). Your XML will do just that, so it already does what you want.

Cannot get current session

`
classpath:database.properties
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="packagesToScan" value="org.entity">
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<tx:annotation-driven/>
<!-- not working -->
<!-- <context:component-scan base-package="org.service"></context:component-scan> -->
`
this is my spring configuration file. Problem is that i am not getting current session in my repository classes which are marked with #Repository, I have annotated my service methods with #Transactional annotation.
However all the autowiring is working fine, the only problem is when i try to get current session in repository classes, and if I use bean tag to instantiate my repository and service beans it works. What am i doing wrong here?
Use the OpenSessionInView Filter or similar, that way you should have a Session available during the request lifecycle (Controller/ View rendering).

Spring - setting property value from JNDI

It is a bit of followup to my previous question
Spring and Hibernate - changing dialect
if for example I have this piece of .xml
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="SpringMVCTest" />
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect" >
</prop>
</props>
</property>
</bean>
now, I wanted to set hibernate.dialect to value that is exposed by jndi by jdbc/dialect, but when I put <jee:jndi-lookup jndi-name="jdbc/MyDataSource"/> I am getting Invalid content was found starting with element 'jee:jndi-lookup'. No child element is expected at this so I suspect that I can't put any tags in prop.
So, is there any way I can insert jndi resource to this property?
Not completely sure, but you should be able to use Spring-EL here, like this:
<jee:jndi-lookup id="dialect" jndi-name="..." />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="SpringMVCTest" />
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect" >#{dialect}</prop>
</props>
</property>
</bean>

Overriding global jta timeout in spring context in weblogic

Our Weblogic have global JTA timeout 30s, since our server is under high load setting such global timout to a bigger value can be critical for performace of the application.
So I want to override this JTA timeout with specific value in context of particular service.
I have root context for a number of webservices it has it's own global transaction manager:
<bean id="jtaTransactionManager" class="org.springframework.transaction.jta.WebLogicJtaTransactionManager">
<property name="transactionManagerName" value="javax.transaction.TransactionManager"/>
</bean>
annotation driven for this transation manager is on
<tx:annotation-driven proxy-target-class="true" transaction-manager="jtaTransactionManager"/>
and i have global hibernate session factory :
<bean id="parent.session.factory"
abstract="true"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
destroy-method="destroy"
p:dataSource-ref="dataSource.schedules">
<property name="hibernateProperties">
<props>
<prop key="hibernate.transaction.manager_lookup_class">
org.hibernate.transaction.WeblogicTransactionManagerLookup
</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
<prop key="hibernate.cache.use_second_level_cache">false</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.connection.autocommit">false</prop>
</props>
</property>
</bean>
Then I have the context of my webservice where I want to override the jta timeout:
Inherited local transaction manager:
<bean id="localTransactionManager" parent="jtaTransactionManager">
<property name="defaultTimeout" value="120"/>
</bean>
Bean with javax TransactionManager interface for hibernate:
<bean id="localEETransactionManager" factory-bean="localTransactionManager"
factory-method="getTransactionManager">
<property name="transactionTimeout" value="120"/>
</bean>
Session factory for Hibernate with lolcaly overrided TransactionManager with EE interface (javax.transaction.TransactionManager)
<bean id="sessionFactory" parent="parent.session.factory">
<property name="jtaTransactionManager" ref="localEETransactionManager"/>
<property name="annotatedClasses">
<list>
<value>com.example.City</value>
<value>com.example.State</value>
<value>com.example.Country</value>
</list>
</property>
</bean>
And finally the DAO with localy overrided WebLogicJtaTransactionManager:
<bean id="addressDao"
class="com.example.AddressDataAccessObjectImpl"
p:entityClass="com.example.City"
p:dataSource-ref="dataSource"
p:sessionFactory-ref="sessionFactory"
p:transactionManager-ref="localTransactionManager"/>
But when I run my application hibernate throws Caused by: weblogic.transaction.internal.TimedOutException: Transaction timed out after 30 seconds
And rolls back the transaction.
Maybe someone know what I'm doing wrong with those overrides?
PS This override works only for root context, if I do somthing like that:
<bean id="jtaTransactionManager" class="org.springframework.transaction.jta.WebLogicJtaTransactionManager">
<property name="transactionManagerName" value="javax.transaction.TransactionManager"/>
<property name="defaultTimeout" value="120"/>
</bean>
But that is not what I whant because it is still global for all application.

Resources