Can HibernateTemplate coexist with EntityManager? - java

We have a spring 3 application that still uses the deprecated HibernateTemplate for persistence and want to migrate to the more modern JPA EntityManager.
Is it possible to use both APIs in parallel during the migration (possibly even both in a single transaction), so that we can do the migration in small steps?
Or will we have to do it big bang?

Sure, why not.
The easiest would be to drop your LocalSessionFactoryBean and HibernateTransactionManager configuration and replace it with LocalContainerEntityManagerFactoryBean and JpaTransactionManager, respectively.
Then to obtain a SessionFactory add the HibernateJpaSessionFactoryBean, which exposes the underlying SessionFactory for the EntityManagerFactory.
This way both technologies should peacefully coexist.
There are some reports that doing this leads to a an exception stating No CurrentSessionContext configured!. If you get it add the following to either your persistence.xml
<property name="hibernate.current_session_context_class" value="org.springframework.orm.hibernate4.SpringSessionContext"/>
or jpaProperties of the LocalContainerEntityManagerFactoryBean.
<property name="jpaProperties">
<props>
<prop name="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>
<props>
<property>

Related

Passing Multiple Provider/Broker URL Spring JMS ndi template

We are using Spring JMS integration for connecting our application to Tibco EMS product. Our jndi template is defined as follows bean:
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">${app.java.naming.factory.initial}</prop>
<prop key="java.naming.provider.url">${app.java.naming.provider.url}</prop>
</props>
</property>
</bean>
Value of app.java.naming.provider.url is defined in property file as of now as :
app.java.naming.provider.url=tcp://server1:7222
I want to make our application pass multiple provider urls is it possible as follows:
app.java.naming.provider.url=tcp://server1:7222,tcp://server2:7222,tcp://server3:7222,tcp://server4:7222
At given time only one server will up, but if other goes down we dont want to change config and re-deploy hence above mechanism.
How Spring JNDI template works with multiple provider urls.

Freemarker Templates Caching Shared Variable after refresh

I have a Spring MVC web app which uses FreeMarker for rendering the views and have come up with the following issue.
Within my FreeMarker config I declare a Singleton Spring bean as a FreeMarker variable and within my application I have provided the mechanism for the Singleton Bean to be dynamically refreshed (the bean contains the application config retrieved from the DB).
Now the problem is that when it is refreshed the previously rendered FreeMarker templates use the values within the older version yet if I navigate to a page not rendered since the container started it uses the new values.
The following is a snippet of my FreeMarker config:
<!-- FreeMarker config -->
<bean id="freemarkerViewConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPaths">
<array>
<value>/WEB-INF/freemarker</value>
<value>classpath:/WEB-INF/freemarker</value>
</array>
</property>
<property name="freemarkerSettings">
<props>
<prop key="datetime_format">dd/MM/yyyy</prop>
<prop key="number_format">#</prop>
<prop key="whitespace_stripping">true</prop>
<prop key="auto_import">
spring.ftl as spring,
custom-macros.ftl as custom,
</prop>
</props>
</property>
<property name="freemarkerVariables">
<map>
<entry key="xml_escape" value-ref="fmXmlEscape"/>
<entry key="html_escape" value-ref="fmHtmlEscape"/>
<entry key="config" value-ref="config"/>
</map>
</property>
</bean>
To refresh the config model I execute the following within my Controller class:
((XmlWebApplicationContext)applicationContext).refresh();
Having this configuration picks up the refreshed config model when accessing a page which hasn't been already rendered but won't recognise the change on pages already visited.
I have tried the following to enforce the 'refresh' of the variable with no luck:
In the controller after the context is refresh I clear the templateCache within the FreeMarker Config which has been autowired:
freeMarkerConfig.getConfiguration().clearTemplateCache();
I have also tried disabling the caching of templates within the FreeMarker config using the following property within freeMarkerSettings:
freemarker.cache.NullCacheStorage
Finally, its worth pointing out that when in debug and looking through the cache and configuration the Shared Variable does indeed reference the most up to date config model yet the page renders using the older version.
Any advice / guidance on how to resolve this?
ps I am using Spring v3.1.1.RELEASE and FreeMarker v2.3.19
Not quite a solution but I have fixed my issue but it is more a hack to be honest.
I changed the code to refresh my config by using the following command so only the config bean was recreated:
((DefaultListableBeanFactory) beanFactory).destroySingleton("config");
And then modified the freemarker config by removing the reference to the config model as regardless what I tried I could not get this to be refreshed. So the solution to my issues was then to modify the BaseController which every controller within the application extends exposing the config model available as a #ModelAttribute so it was available to all the views.
As I said doesn't really solve the underlying issue but I have solved my problem albeit in a unorthodox fashion.

how to configure cache in hibernate with jboss? ? And test as well in kumud console?

Does any one know, how to configure cache for hibernate with jboss ?
My clear question is I am using JPA and Jboss. Every time I call JPA method its creating entity and binding query.
My persistence properties are
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
<property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.SingletonEhCacheProvider"/>
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.use_query_cache" value="true"/>
And I am creating entity manager the way shown below:
emf = Persistence.createEntityManagerFactory("pu");
em = emf.createEntityManager();
em = Persistence.createEntityManagerFactory("pu")
.createEntityManager();
Is there any nice way to manage entity manager resource insted create new every time or any property can set in persistance. Remember it's JPA.
The question is not clear, there are many second level cache providers for Hibernate and they are not application server specific.
To enable the second level cache, you need to set the following properties in Hibernate configuration file hibernate.cfg.xml:
<property name="hibernate.cache.use_second_level_cache">true</property>
And if you want to also enable query result caching:
<property name="hibernate.cache.use_query_cache">true</property>
Then, declare the name of a class that implements org.hibernate.cache.CacheProvider - a cache provider - under the hibernate.cache.provider_class property. For example, to use JBoss Cache 2:
<property name="hibernate.cache.provider_class">org.hibernate.cache.jbc2.JBossCacheRegionFactory</property>
Of course, the JAR for the provider must be added to the application classpath.
That's for the Hibernate side. Depending on the chosen cache provider, there might be additional configuration steps. But as I said, there are many second level cache providers: EHCache, JBoss Cache, Infinispan, Hazelcast, Coherence, GigaSpace, etc.

Spring jta-transaction-manager

Using Spring:
can jta-transaction-manager use id as name so that I can pass it as REF to my service layer like below?
is tx:jta-transaction-manager can only be used for je22 container? I mean for Tomcat, I need to do it manually, like below:
<tx:jta-transaction-manager id="name_transactionmanager"/>
<bean id="projectService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"
ref="name_transactionmanager"/>
<property name="target">
<bean
class="com.company.project.company.services.ServiceImpl"
init-method="init">
<property
name="HRappsdao"
ref="HRappsdao"/>
<property
name="projectdao"
ref="projectdao"/>
</bean>
</property>
<property name="transactionAttributes">
<props>
<prop key="store*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="bulkUpdate*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_SUPPORTS,readOnly</prop>
</props>
</property>
</bean>
For question 2
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="userTransaction">
<bean class="org.springframework.transaction.jta.JotmFactoryBean"/>
</property>
</bean>
Can tx:jta-transaction-manager use id as name so that I can pass it as REF to my service layer like below?
The <tx:jta-transaction-manager> exposes the transaction manager as a Bean in the Spring context with the name "transactionManager".
Can tx:jta-transaction-manager only be used with a J2EE container?
Quoting the Chapter 9. Transaction management from the Spring documentation:
Is an application server needed for transaction management?
The Spring Framework's transaction
management support significantly
changes traditional thinking as to
when a J2EE application requires an
application server.
In particular, you don't need an
application server just to have
declarative transactions via EJB. In
fact, even if you have an application
server with powerful JTA capabilities,
you may well decide that the Spring
Framework's declarative transactions
offer more power and a much more
productive programming model than EJB
CMT.
Typically you need an application
server's JTA capability only if you
need to enlist multiple transactional
resources, and for many applications
being able to handle transactions
across multiple resources isn't a
requirement. For example, many
high-end applications use a single,
highly scalable database (such as
Oracle 9i RAC). Standalone transaction
managers such as Atomikos Transactions
and JOTM are other options. (Of course
you may need other application server
capabilities such as JMS and JCA.)
The most important point is that with
the Spring Framework you can choose
when to scale your application up to a
full-blown application server. Gone
are the days when the only alternative
to using EJB CMT or JTA was to write
code using local transactions such as
those on JDBC connections, and face a
hefty rework if you ever needed that
code to run within global,
container-managed transactions. With
the Spring Framework, only
configuration needs to change so that
your code doesn't have to.
So, as explained in the third paragraph, if you want to work with multiple transactional resources, you'll need global transactions which involve a JTA capable application server. And JTA capable application server means a real J2EE container or a non J2EE container (like Tomcat) with a standalone transaction manager like Atomikos, JOTM, Bitronix, SimpleJTA, JBossTS or GeronimoTM/Jencks.
FWIW, I've seen lots of complains about JOTM, I think that GeronimoTM/Jencks lacks of documentation, I can't really say anything about JBossTSArjunaTS (except that it's a rock solid product), SimpleJTA and Bitronix have both good documentation and Atomikos is an impressive product greatly documented too. Personally, I'd choose Bitronix or Atomikos.
PS: Honestly, if this sounds like Chinese to you, you should maybe consider using a single database (if this is an option, go for it!) or consider using a real J2EE container like JBoss or GlassFish as I wrote in a previous answer. No offense but all this JTA stuff is not trivial and taking the JOTM path is not that simple if you don't really understand why you need it.

JPA Multiple Transaction Managers

I have one applicationContext.xml file, and it has two org.springframework.orm.jpa.JpaTransactionManager (each with its own persistence unit, different databases) configured in a Spring middleware custom application.
I want to use annotation based transactions (#Transactional), to not mess around with TransactionStatus commit, save, and rollback.
A coworker mentioned that something gets confused doing this when there are multiple transaction managers, even though the context file is set configured correctly (the references go to the correct persistence unit.
Anyone ever see an issue?
In your config, would you have two transaction managers?
Would you have txManager1 and txManager2?
That's what I have with JPA, two different Spring beans that are transaction managers.
I guess you have 2 choices
If your use-cases never require updates to both databases within the same transaction, then you can use two JpaTransactionManagers, but I'm not sure you will be able to use the #Transactional approach? In this case, you would need to fallback on the older mechanism of using a simple TransactionProxyFactoryBean to define transaction boundaries, eg:
<bean id="firstRealService" class="com.acme.FirstServiceImpl"/>
<bean id="firstService"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="firstJpaTm"/>
<property name="target" ref="firstRealService"/>
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<!-- similar for your second service -->
If you are require a transaction spanning both databases, then you will need to use a JTA transaction manager. The API states:
This transaction manager is appropriate for applications that use a single JPA EntityManagerFactory for transactional data access. JTA (usually through JtaTransactionManager) is necessary for accessing multiple transactional resources within the same transaction. Note that you need to configure your JPA provider accordingly in order to make it participate in JTA transactions.
What this means is that you will need to provide a JTA transaction manager. In our application, we use config similar to the following:
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManagerName" value="appserver/jndi/path" />
</bean>
If you are deploying within an appserver, then the spring JtaTransactionManager needs to do a lookup to the real XA-compliant JTA transaction manager provided by the appserver. However, you can also use a standalone JTA transaction manager (but I haven't tried this myself yet)
As for configuring the Jpa persistence provider, I'm not that familiar. What JPA persistence provider are you using?
The code above is based on our approach, where we were using native Hibernate as opposed to Hibernate's JPA implementation. In this case, we were able to get rid of the two HibernateTransactionManager beans, and simply ensure that both SessionFactories were injected with the same JTA TM, and then use the tx:annotation-driven element.
Hope this helps
The only situation in which you can have two Spring transaction managers is if you never have both transactions open at one time. This is not intrinsically to do with distributed transactions - the same restrictions apply even if you want the two datasources to have completely separate (but potentially overlapping in time) transaction lifecyles.
Internally Spring's transaction managers all use Spring's TransactionSynchronizationManager which keeps a bunch of critical state in static ThreadLocal variables, so transaction managers are guaranteed to stomp all over each other's state.

Categories

Resources