Spring-Hibernate Caching with Memcached - spring

I have an application whose back end has been made with Spring and Hibernate.
I Want to apply memcaching to make the application more scalable. At first i thought that i could integrate the second level cache of hibernate with memcache but the problem arouse was that all the HQL written in the application r like book.grade.id where Book & Grade are two separate entities, hence, the second level cache mechanism failed.
Can anyone recommend me a way to implement caching? I have had a look at EHCache but i want the Memcache implementation for now. My application will be hit by several servers but only 1 Database Server will exist. Given the required conditions, any recommendations?

Below mentioned are the steps you can follow.
pom.xml changes to include the abstract cache mechanism for memcache and client implementation using xmemcache.
com.google.code.simple-spring-memcached
spring-cache
3.1.0
<dependency>
<groupId>com.google.code.simple-spring-memcached</groupId>
<artifactId>xmemcached-provider</artifactId>
<version>3.1.0</version>
</dependency>
Note : You need to include cglib too as this is aop based.
configuration.xml file changes
**defining beans**
<bean name="cacheManager" class="com.google.code.ssm.spring.SSMCacheManager">
<property name="caches">
<set>
<bean class="com.google.code.ssm.spring.SSMCache">
<constructor-arg name="cache" index="0" ref="defaultCache"/>
<!-- 5 minutes -->
<constructor-arg name="expiration" index="1" value="300"/>
<!-- #CacheEvict(..., "allEntries" = true) doesn't work -->
<constructor-arg name="allowClear" index="2" value="false"/>
</bean>
</set>
</property>
</bean>
<bean name="defaultCache" class="com.google.code.ssm.CacheFactory">
<property name="cacheName" value="defaultCache" />
<property name="cacheClientFactory">
<bean name="cacheClientFactory"
class="com.google.code.ssm.providers.xmemcached.MemcacheClientFactoryImpl" />
</property>
<property name="addressProvider">
<bean class="com.google.code.ssm.config.DefaultAddressProvider">
<property name="address" value="x.x.x.x:11211" />
</bean>
</property>
<property name="configuration">
<bean class="com.google.code.ssm.providers.CacheConfiguration">
<property name="consistentHashing" value="true" />
</bean>
</property>
</bean>
Sample method...
#Cacheable(value="defaultCache", key="new Integer(#id).toString().concat('.BOOKVO')")
public BookVO getBookById(Integer id){
...
}
with this changes your method will hit the db only if the key is not found in the memcache server.

Related

How do I automatically reload my properties in my Spring XML appilcation context?

I’m using Spring 3.2.11.RELEASE. I currently have the following set up in my application context file for the purposes of loading a cron trigger based off a schedule defined in a properties file (the property = cron.schedule) …
<bean id="localPropertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:application.properties</value>
</property>
</bean>
…
<bean id="updateResourcesJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="myService" />
<property name="targetMethod" value="myMethod" />
<property name="concurrent" value="true" />
</bean>
<bean id="updateResourcesCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="myJob" />
<property name="cronExpression" value="${cron.schedule}" />
</bean>
My question is, I would like to create an XML configuration in my context file that allows me to edit my properties file and have everything automatically reloaded without having to restart my server or re-deploy my application. I have read several places about Apache Commons Configuration, but I can’t figure out how to take the above and rewrite an XML config that would utilize the configuration.
Thanks for any help, - Dave

Creating multiple SchedulerFactoryBean in Quartz

I have run into a problem where I have two classes extending QuartzJobBean. The problem I am facing is to create two SchedulerFactoryBean. I did my research and found that setting the property schedulerName solves the problem. This did not work for me. I used #Qualifier also. If I create the two beans of SchedulerFactoryBean , Spring doesn't know which scheduler to refer to. I have two CronTriggers.
Code:
<!--
<bean name="quartzSchedulerR" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.task.QuartzScheduler" />
<property name="jobDataAsMap">
<map>
<entry key="rRSImpl" value-ref="rRSService" />
<entry key="SRObject" value-ref="SRObject"/>
</map>
</property>
</bean>
<bean id="cronTriggerR"
class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="quartzSchedulerR" />
<property name="cronExpression" value="0 30 12 ? * MON *" />
</bean>
<bean id="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false">
<property name="schedulerName" value="scheduleOne"/>
<property name="schedulerContextAsMap">
<map>
<entry key="rSchedulerServiceImpl" value-ref="rSchedulerServiceImpl"></entry>
</map>
</property>
<property name="jobDetails">
<list>
<ref bean="quartzSchedulerR" />
</list>
</property>
<property name="triggers">
<list>
<ref bean="cronTriggerR" />
</list>
</property>
</bean> -->
<bean id ="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false">
<property name="schedulerContextAsMap">
<map>
<entry key="rSSImpl" value-ref="rSSImpl"></entry>
</map>
</property>
</bean>
<bean id="jobDetailFactory" class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean">
<property name="targetBeanName">
<idref local="jobDetail" />
</property>
</bean>
<bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailBean" scope="prototype">
<property name="jobClass" value="com.scheduler.SMTPMailJob " />
<property name="jobDataAsMap">
<map>
<entry key="rSSeImpl" value-ref="rSSImpl" />
<entry key="fUtil" value-ref="fUtil" />
<entry key="rService" value-ref="rService" />
<entry key="fusion" value-ref="fusion"/>
<entry key="fcproperties" value-ref="fcproperties"/>
</map>
</property>
</bean>
<bean id="jobTriggerFactory"
class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean">
<property name="targetBeanName">
<idref local="jobTrigger" />
</property>
</bean>
<bean id="jobTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"
scope="prototype">
</bean>
Currently I comment out the first scheduler and the application works as expected. But if I uncomment it, the second scheduler stops working. Any workaround for this issue.. ? Any help is appreciated.
EDIT: There is no error but I know that the job isn't scheduled. The error is basically that spring doesn't find a unique bean for com.quartz.Scheduler when both the SchedulerFactoryBean are defined. Basically how to configure multiple SchedulerFactoryBean for totally isolated classes.. ?
Please can you explain why do you need two scheduarfactorybeans.
As per spring doc, FactoryBean that creates and configures a Quartz Scheduler, manages its lifecycle as part of the Spring application context, and exposes the Scheduler as bean reference for dependency injection.
This means you cant have multiple instances of the bean.
Also as per your code you are trying to schedule multiple jobs which can be done using one schedularFactoryBean. Create Multiple job beans and their corresponding triggers and add them as list to the schedular factoryBean. All the triggers will be invoked as per configuration irrespective of whether it is a cron trigger or simple trigger.

Use of Heritrix's HtmlFormCredential and CredentialStore

I am attempting to add authentication to my Heritrix configuration. My .cxml file has the following:
<bean id="preconditions" class="org.archive.crawler.prefetch.PreconditionEnforcer">
<property name="credentialStore">
<ref bean="credentialStore" />
</property>
</bean>
<bean id="fetchHttp" class="org.archive.modules.fetcher.FetchHTTP">
<property name="credentialStore">
<ref bean="credentialStore" />
</property>
<property name="shouldProcessRule">
<bean class="org.archive.modules.deciderules.DecideRuleSequence">
<property name="rules">
<list>
<bean class="org.archive.modules.deciderules.recrawl.IdenticalDigestDecideRule">
<property name="decision" value="REJECT" />
</bean>
<bean class="org.archive.modules.deciderules.ResourceNoLongerThanDecideRule">
<property name="contentLengthThreshold" value="54" />
<property name="useHeaderLength" value="true" />
<property name="decision" value="REJECT" />
</bean>
</list>
</property>
</bean>
</property>
</bean>
<bean id="exampleCredential" class="org.archive.modules.credential.HtmlFormCredential">
<property name="domain" value="example.com" />
<property name="loginUri" value="https://example.com/user?destination=%2f" />
<property name="formItems">
<map>
<!-- username/password -->
<entry key="name" value="something#something.com"/>
<entry key="pass" value="genericpassword"/>
<!-- hidden inputs -->
<entry key="form_build_id" value="form-asdf" />
<entry key="form_id" value="user_login" />
<!-- submit -->
<entry key="op" value="submit"/>
</map>
</property>
</bean>
<bean id="credentialStore" class="org.archive.modules.credential.CredentialStore">
<property name="credentials">
<map>
<entry key="exampleCredential" value-ref="exampleCredential" />
</map>
</property>
</bean>
I also set the logging for FetchHTTP and PreconditionEnforcer to FINE, but nothing seems to be happening. No logging output is appearing from either modules and the pages that are pulled down clearly are those of an un-authenticated view.
I find it somewhat unclear as to how to use the CredentialStore, considering that I've spent a good amount of time reading through the specifications, which are patchy at best when it comes to authentication and websites.
Anyone know how to set up authentication in Heritrix, please help.
Update:
Logging didn't work because eclipse didn't know about my HERITRIX_HOME variable, so it never even read the logging configuration file.
I changed the bean exampleCredential's domain property from:
<property name="domain" value="example.com" />
to:
<property name="domain" value="www.example.com" />
and now the login page is enqueued, but now the logger spits out the following for all queued files:
org.archive.crawler.prefetch.PreconditionEnforcer.innerProcessResult() PolitenessEnforcer doesn't understand uri's of type dns (ignoring)
org.archive.modules.deciderules.ResourceNoLongerThanDecideRule.evaluate() Error: Missing HttpMethod object in CrawlURI. dns:secure.www.example.com
and none of the files are downloaded or crawled. So though I made progress, it didn't lead me anywhere. There is not much logging information to go off of.
I also asked this question on the Heritrix forms: http://tech.groups.yahoo.com/group/archive-crawler/message/8235 and Noah Levitt had the idea to add the login page as a seed to my crawl. Everything now seems to be working without much issue.
My conclusion is that I had everything set up correctly in my config file, but was missing the actual page seed that I needed.

EJB 3.0 -> Spring -> JPA (JTA as transaction manager)

I am currently working on a project that includes EJB 3.0 (stateless SB), JPA (Hibernate as the provider), JTA as transaction manager. The app server is JBoss AS 7. Spring is used for integrating EJB and JPA.
All seems to be working fine, except if there is any exception that occurs in the EJB, then the persistence unit is closed by Spring. On the subsequent request, the persistence unit is again created, which becomes time consuming and also should not happen in the ideal situation.
Below are the configuration details
persistence.xml
<persistence-unit name="test" transaction-type="RESOURCE_LOCAL">
<class>com.test.User</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
</properties>
</persistence-unit>
spring-application-context.xml
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<jee:jndi-lookup id="dataSource" jndi-name="java:/datasources/test" />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="false" />
<property name="database" value="MYSQL" />
<property name="showSql" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect"/>
</bean>
</property>
<property name="jpaPropertyMap">
<map>
<entry key="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"></entry>
<entry key="hibernate.current_session_context_class" value="jta" />
<entry key="hibernate.connection.release_mode" value="auto" />
</map>
</property>
<property name="persistenceUnitPostProcessors">
<list>
<bean class="com.transaction.processor.JtaPersistenceUnitPostProcessor">
<property name="jtaMode" value="true"/>
<property name="jtaDataSource" ref="dataSource"/>
</bean>
</list>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManagerName" value="java:/TransactionManager"></property>
<property name="autodetectUserTransaction" value="false"></property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
The class JtaPersistenceUnitPostProcessor is responsible for setting the transaction-type as JTA and the datasource to jta-datasource.
Could anyone please provide any help on this.
Thanks in advance.
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManagerName" value="java:jboss/TransactionManager" />
<property name="userTransactionName" value="java:comp/UserTransaction" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
you didn't specify any error message . you can add these lines in your configuration file .
I see you use JTA transaction manager and use that only if you use distributed Transaction and use JNDI. JTA tran. manager listens TX happening through connection acquired from JNDI datasource. If you have datasource created in your code and is not a part of Web container but is limited inside app. container in your web server, JTA wont work.
If you want to implement Tx manager with in a single app. context go for JPA transaction manager which is very reliable.

Hibernate (JPA,JSF 2.0, Spring) switch from HyperSQL to Oracle - Configuration is being ignored

i'm currently in the process of working on a midsized Webproject, using JSF 2.0 with Spring.As IDE i use Eclipse with JBoss Tools. The Webapp is deployed to a Tomcat v7.0 Server.
I use Hibernate/JPA/C3P0/ to connect to the Database (previously HyperSQL) I now tried to switch to an Oracle DB, which i did a number of times before and it never was a problem, however now it seems, that the changed configuartion is just being ignored. When i fire up the Server, it still uses the HyperSQl Driver and the old DB, although i cleaned the workdirectory of Tomcat, removed and redeployed the Webapp (which i built from scratch of course).
The project is split in two, one webapp and one service part. The project are dependent in Eclipse. However, although all of the businesslogic is implemented in the service layer, i can just remove it and the webapp doesn't throw an error and i can start it as if nothing has changed. This tells me that it must be cached somewhere and it is not refreshed on the server...I also deleted the server, added a freshly downloaded instance - still the same thing...Does anyone have an Idea what this could be about?
Here is my service.spring.xml:
<!-- Enable processing of #PersistenceContext and #PersistenceUnit -->
<context:annotation-config/>
<!-- Enable transaction configuration with #Transactional -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- Configure a c3p0 pooled data source -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="user"/>
<property name="password" value="password"/>
<property name="driverClass" value="oracle.jdbc.driver.OracleDriver"/>
<property name="jdbcUrl" value="jdbc:oracle:thin:#dburl"/>
<property name="initialPoolSize" value="1"/>
<property name="minPoolSize" value="1"/>
<property name="maxPoolSize" value="10"/>
</bean>
<!-- Configure the JPA entity manager factory with Hibernate -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false"/>
<property name="database" value="ORACLE"/>
<property name="generateDdl" value="true"/>
</bean>
</property>
<property name="persistenceUnitName" value="mygourmet"/>
</bean>
<!-- Configure transaction manager for JPA -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
And my persistence.xml:
<persistence-unit name="mygourmet" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="false" />
<property name="hibernate.use_sql_comments" value="false" />
<property name="hibernate.connection.autocommit" value="false" />
<property name="hibernate.cache.use_query_cache" value="false" />
<property name="hibernate.cache.use_second_level_cache" value="false" />
<property name="hibernate.hbm2ddl.auto" value="create" />
</properties>
I used the exact same configuration on another project and it works like a charm...Any hints are highly appreciated, thank you guys in advance!
Problem solved - i did a mvn clean install, generated new eclipse projects and imported them back into eclipse. It seems the changes in my service module were not recognized by eclipse.

Resources