Read template from the database - VelocityEngine - spring

I am storing the templates I use with velocity in the DB and I wan to configure it to read the templates from the DB.
my bean definition is:
<bean id="velocityEngineBasedOnDB" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
<property name="velocityProperties">
<map>
<entry key="resource.loader" value="ds"/>
<entry key="ds.resource.loader.class" value="org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader"/>
<entry key="ds.resource.loader.resource.table" value="tb_velocity_template"/>
<entry key="ds.resource.loader.resource.keycolumn" value="id_template"/>
<entry key="ds.resource.loader.resource.templatecolumn" value="template_definition"/>
<entry key="ds.resource.loader.resource.datasource" value-ref="dataSource"/>
</map>
</property>
</bean>
but I got java.lang.ClassCastException: 'resource.datasource' doesn't map to a String object.
So how I configure the data source as string?

Works for me
<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
<property name="velocityProperties">
<map>
<entry key="resource.loader" value="ds"/>
<!--<entry key="ds.resource.loader.class" value="org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader"/>--><!--should be left out-->
<entry key="ds.resource.loader.resource.table" value="templates" />
<entry key="ds.resource.loader.resource.keycolumn" value="tid" />
<entry key="ds.resource.loader.resource.templatecolumn" value="template" />
<entry key="ds.resource.loader.resource.timestampcolumn" value="updated" />
<entry key="ds.resource.loader.instance" value-ref="dataSourceLoader" />
<entry key="ds.resource.loader.cache" value="true" />
</map>
</property>
</bean>
Data Source Loader:
<bean id="dataSourceLoader" class="org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader"> <property name="dataSource" ref="myDataSource"/><!-- myDataSource is a com.mchange.v2.c3p0.ComboPooledDataSource type--> </bean>

You have to configure another bean with id "datasource" and that will allow Spring to instantiate an instance of a class inheriting from java.sql.Datasource. It may be an OracleDataSource, for example if your database is Oracle.

you should set ds.resource.loader.instance ref a spring bean,eg:
<bean id="resourceLoader"
class="xx.common.mail.MongoDataSourceResourceLoader"
p:mongoTemplate-ref="mongoTemplate"/>
<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
<property name="velocityProperties">
<map>
<entry key="resource.loader" value="ds"/>
<entry key="ds.resource.loader.instance" value-ref="resourceLoader"/>
</map>
</property>

<entry key="ds.resource.loader.resource.datasource" value-ref="dataSource"/>
value-ref doesnt work for me
change to value="datasource" and try.
It may be that value-ref support is added in higher versions (if any).
I am using Velocity 1.7

<!-- myDataSource is a com.mchange.v2.c3p0.ComboPooledDataSource type-->
<bean id="dataSourceLoader" class="org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader">
<property name="dataSource" ref="myDataSource"/>
</bean>

Related

What is the Alternative to RmiRegistryFactoryBean for ConnectorServerFactoryBean as RmiRegistryFactoryBean is deprecated?

I am having an exsiting code where we are using org.springframework.remoting.rmi.RmiRegistryFactoryBean.
I am upgrading our Spring version and looks like RmiRegistryFactoryBean is deprecated in latest spring(spring-context.jar) version.
below is the code snippit I am using
<bean id="registry"
class="org.springframework.remoting.rmi.RmiRegistryFactoryBean">
<property name="port" value="{jmx.port}" />
<property name="clientSocketFactory" ref="sslRMIClientSocketFactory" />
<property name="serverSocketFactory" ref="sslRMIServerSocketFactory" />
</bean>
<bean id="serverConnector"
class="org.springframework.jmx.support.ConnectorServerFactoryBean"
depends-on="registry">
<property name="serviceUrl"
value="service:jmx:rmi://0.0.0.0:{jmx.port}/jndi/rmi://0.0.0.0:{jmx.port}/drsrmi" />
<property name="environment">
<map>
<entry key="jmx.remote.jndi.rebind" value="true"/>
<entry key="jmx.remote.tls.need.client.authentication" value="true"/>
<entry key="jmx.remote.rmi.server.socket.factory" value-ref="sslRMIServerSocketFactory"/>
<entry key="jmx.remote.rmi.client.socket.factory" value-ref="sslRMIClientSocketFactory"/>
<entry key="com.sun.jndi.rmi.factory.socket" value-ref="sslRMIClientSocketFactory"/>
</map>
</property>
</bean>
Now my ConnectorServerFactoryBean depends on registry. How can i handel this now is there any alternative for RmiRegistryFactoryBean or I can create ConnectorServerFactoryBean without registry?

Spring configuration: TypeMismatchException

Using Spring 3.2 and Quartz 1.8. I've configured a org.springframework.scheduling.quartz.JobDetailBean as follows:
<bean id="a" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.MyJob" />
...
</bean>
I'd like to change this configuration so that the jobClass refers to a bean instance so that I can set some properties on the bean:
<bean id="b" class"com.MyJob">
<constructor-arg name="arg" value="1"/>
</bean>
<bean id="a" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" ref="b" />
...
</bean>
When launching the app with this config, I get
org.springframework.beans.TypeMismatchException: Failed to convert property value of type 'com.MyJob' to required type 'java.lang.Class' for property 'jobClass'.
Why is that? I assume it's because the jobClass property requires a class and not an instance, so how do I get around that?
Found a solution. You can inject some properties into the jobDataAsMap, which in turn injects them into setters into you jobClass (or can be retrieved programmatically from the JobExecutionContext.jobDetail in your jobClass).
<bean id="a" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.MyJob" />
<property name="jobDataAsMap">
<map>
<entry key="propA" value="10" />
<entry key="propB" value="3" />
</map>
</property>
</bean>

Envers doesn't insert records

I'm trying to integrate Envers in my project. I'm using Hibernate-envers 3.5.5-Final, Hibernate-core 3.5.5-Final, spring 3.0.7.RELEASE.
For DAO Layer, I'm using a GenericDaoHibernate class.
My applicationContext.xml contains:
<property name="eventListeners">
<map>
<entry key="post-insert" >
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="post-update">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="post-delete">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="pre-collection-update">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="pre-collection-remove">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="post-collection-recreate">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
</map>
</property>
The audit tables for the annotated classes are created, but by adding or updating a row in the entity table, no row is inserted in the _AUD tables or in the REVINFO.
So, I added a new listener org.hibernate.ejb.event.EJB3PostInsertEventListener as :
<property name="eventListeners">
<map>
<entry key="post-insert" >
<list>
<bean class="org.hibernate.envers.event.AuditEventListener" />
<bean class="org.hibernate.ejb.event.EJB3PostInsertEventListener" />
</list>
</entry>
<entry key="post-update">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="post-delete">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="pre-collection-update">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="pre-collection-remove">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="post-collection-recreate">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
</map>
</property>
The problem persists, and now no record is inserted in the entity tables.
Any suggestion is welcome.
Thanks.
OK.
I solved the problem.
Firstibale, it seems that with the Hibernate-core 3.5.5-Final, we don't need org.hibernate.ejb.event.EJB3PostInsertEventListener, so in our ApplicationContext-config.xml we should have just this config :
<property name="eventListeners">
<map>
<entry key="post-insert" >
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="post-update">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="post-delete">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="pre-collection-update">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="pre-collection-remove">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="post-collection-recreate">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
</map>
</property>
Secondly, in our case our project uses two transction managers, so for the services annotated #Transactionnal we have to mention the name of the proper transaction manager used, that means that all services should be annotated as #Transactionnal(value="NAME_TX_MANAGER"). The source of this problem is that Envers doesn't work properly if we have an auto-commit (If I understood well its documentation).
I hope that may be helpful for the other visitors if the face the same difficulties.

spring batch admin showing jobs as not launchable

I have a spring mvc webapp with spring batch built into it. I am having some issues getting my spring batch jobs to be launchable in the spring batch admin console. This is what I see when I go to the jobs page...
All of my jobs are coming up as launchable=false. I was wondering how I can fix this. I read some documentation about why this would be so and it said that I need to use a AutomaticJobRegistrar.
I tried this but it didn't change anything. I've put my spring batch job configuration below. Would appreciate it someone could tell me what is missing.
thanks
<beans profile="pre,prod">
<bean id="jobLauncher"
class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
</bean>
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"
parent="abstractCustDbJdbcDao">
<property name="transactionManager" ref="custDbTransactionManager" />
<property name="databaseType" value="db2" />
<property name="tablePrefix" value="REPMAN.BATCH_" />
</bean>
<bean id="jobExplorer"
class="org.springframework.batch.core.explore.support.JobExplorerFactoryBean"
parent="abstractCustDbJdbcDao" />
<bean class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor">
<property name="jobRegistry" ref="jobRegistry" />
</bean>
<bean id="jobLoader" class="org.springframework.batch.core.configuration.support.AutomaticJobRegistrar">
<property name="applicationContextFactories">
<bean class="org.springframework.batch.core.configuration.support.ClasspathXmlApplicationContextsFactoryBean">
<property name="resources" value="classpath*:/META-INF/spring/jobs/*.xml" />
</bean>
</property>
<property name="jobLoader">
<bean class="org.springframework.batch.core.configuration.support.DefaultJobLoader">
<property name="jobRegistry" ref="jobRegistry" />
</bean>
</property>
</bean>
<bean id="jobRegistry"
class="org.springframework.batch.core.configuration.support.MapJobRegistry" />
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="jobDetails">
<list>
<ref bean="dailyTranCountJobDetail" />
<ref bean="bulletinBarMsgUpdateJobDetail" />
<ref bean="updateLovCacheJobDetail" />
</list>
</property>
<property name="triggers">
<list>
<ref bean="dailyTranCountCronTrigger" />
<ref bean="bulletinBarMsgUpdateCronTrigger" />
<ref bean="updateLovCacheCronTrigger" />
</list>
</property>
</bean>
<!-- scheduling properties -->
<util:properties id="batchProps" location="classpath:batch.properties" />
<context:property-placeholder properties-ref="batchProps" />
<!-- triggers -->
<bean id="dailyTranCountCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="dailyTranCountJobDetail" />
<property name="cronExpression" value="#{batchProps['cron.dailyTranCounts']}" />
</bean>
<bean id="bulletinBarMsgUpdateCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="bulletinBarMsgUpdateJobDetail" />
<property name="cronExpression" value="#{batchProps['cron.bulletinBarUpdateMsg']}" />
</bean>
<bean id="updateLovCacheCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="updateLovCacheJobDetail" />
<property name="cronExpression" value="#{batchProps['cron.updateLovCache']}" />
</bean>
<!-- job detail -->
<bean id="dailyTranCountJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.myer.reporting.batch.JobLauncherDetails" />
<property name="group" value="quartz-batch" />
<property name="jobDataAsMap">
<map>
<entry key="jobName" value="job-daily-tran-counts" />
<entry key="jobLocator" value-ref="jobRegistry" />
<entry key="jobLauncher" value-ref="jobLauncher" />
</map>
</property>
</bean>
<bean id="bulletinBarMsgUpdateJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.myer.reporting.batch.JobLauncherDetails" />
<property name="group" value="quartz-batch" />
<property name="jobDataAsMap">
<map>
<entry key="jobName" value="job-bulletin-bar-msg-update" />
<entry key="jobLocator" value-ref="jobRegistry" />
<entry key="jobLauncher" value-ref="jobLauncher" />
</map>
</property>
</bean>
<bean id="updateLovCacheJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.myer.reporting.batch.JobLauncherDetails" />
<property name="group" value="quartz-batch" />
<property name="jobDataAsMap">
<map>
<entry key="jobName" value="job-update-lov-cache" />
<entry key="jobLocator" value-ref="jobRegistry" />
<entry key="jobLauncher" value-ref="jobLauncher" />
</map>
</property>
</bean>
</beans>
There are a few things this could be:
Where is the XML file you reference above located? It needs to be the META-INF/spring/batch/jobs directory in your WAR file (that's where Spring Batch Admin will look).
Don't configure common components in your XML file. That includes the jobLauncher, jobRepository, jobExplorer, jobLoader, or jobRegistry. That being said, I don't see an actual job defined in your XML file. The XML file needs one of those ;)
You can read more about adding your own job definitions to Spring Batch Admin: http://docs.spring.io/spring-batch-admin/reference/jobs.html#Add_your_Own_Jobs_For_Launching_in_the_UI

Wiring spring beans through custom reporting context in grails

I am using Jasper Reports for my Grails based web application and I have a ReportingContext.xml which has beans for each report like report id/name mapping with the report template (jrxml). I need to know the basic steps to configure and setup the context xmls and how to load them into my reportscontroller at application startup.
The old application was in java/j2ee which used this reporting xml. We have to develop a similar system on grails.
Most of the context contains the jrxml to report name mapping but I am not able to understand some of the beans in the context.
Here is the sample content of the reporting context.xml , for 1 report
<beans>
<!-- ========================= REPORTING SERVICE WRAPPER ========================= -->
<bean parent="baseTransactionProxy" name="myReportingService">
<property name="proxyInterfaces" value="com.pack.my.reporting.service.myReportingService"/>
<property name="transactionAttributes">
<property name="target">
<bean parent="baseServiceSupport" class="com.pack.my.reporting.service.impl.myReportingServiceImpl">
<property name="reportManager" ref="reportManager"/>
<property name="mySecurityService" ref="mySecurityService"/>
<property name="businessUnitService" ref="businessUnitService"/>
</bean>
</property>
</bean>
<bean class="com.pack.my.reporting.manager.impl.ReportManagerImpl" id="reportManager">
<property name="reportRenderers">
<map>
<entry key="JasperPrint">
<entry key="siemJasperPrint">
</map>
</property>
<property name="reportDefinitionDao" ref="reportDefinitionDao"/>
<property name="reportDao" ref="reportDao"/>
<property name="sequenceGeneratorService" ref="sequenceGeneratorService"/>
<property name="reportLocation" value="file:${my_HOME}/reports"/>
<property name="reportDefinitions">
<map>
<entry key="businessUnitRoles">
<ref local="businessUnitRoles"/>
</entry>
<entry key="businessUnitRoleUsers">
<ref local="businessUnitRoleUsers"/>
</entry>
</map>
</property>
<property name="parameterPromptCodeMap">
<bean class="org.apache.commons.collections.map.CaseInsensitiveMap">
<constructor-arg>
<map>
<entry value="1" key="businessUnit"/>
<entry value="1" key="businessUnitKey"/>
<entry value="2" key="globaluser"/>
<entry value="2" key="USERID"/>
<entry value="2" key="USER_ID"/>
<entry value="2" key="GLOBALUSERKEY"/>
<entry value="3" key="identityCertification"/>
<entry value="3" key="CERTIFICATIONID"/>
<entry value="3" key="CERTIFICATION_ID"/>
<entry value="4" key="startDate"/>
</map>
</constructor-arg>
</bean>
</property>
</bean>
<!--- Report Groups Business Unit reports Group 1 Users reports -->
<bean class="com.pack.my.reporting.domain.ReportDefinition" id="businessUnitRoles">
<property name="reportName" value="Business Unit Roles Report"/>
<property name="reportFiles">
<map>
<entry value="BusinessUnitRoles.jrxml" key="JasperPrint"/>
</map>
</property>
<property name="promptForBusinessUnit" value="true"/>
<property name="reportGroup" value="1"/>
<property name="displayName" value="report.businessUnitRoles.name"/>
<bean class="com.pack.my.reporting.domain.ReportDefinition" id="businessUnitUsers">
</bean>
</beans>
Add dependencies to grails-app/conf/BuildConfig.groovy
Copy the above file to /grails-app/conf/spring/resources.xml
Read Grails and Spring - Reference Documentation
The resources.xml is not built by default anymore, as only resources.groovy exists in the spring dir. Just copy your spring context file to resources.xml.

Resources