I wasn't able to identify if ConcurrentMapCacheFactoryBean would provide a distributed cache. Intuition says no because the docs mentioned "used within a Spring container" but I would like to confirm because the configuration for it seems to be the simplest!
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/cache/concurrent/ConcurrentMapCacheFactoryBean.html
FYI I have the following bean in my xml
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean
class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"
name="testCache"/>
</set>
</property>
</bean>
Related
It seems that the built in workflow activities are being executed twice. I am testing the checkout workflow and the DecrementInventoryActivity is removing the quantity from the sku twice.
Is this a known bug or am I doing something wrong?
I created the workflow like so:
<!-- Checkout Workflow Configuration -->
<bean id="blCheckoutWorkflow" class="org.broadleafcommerce.core.workflow.SequenceProcessor">
<property name="processContextFactory">
<bean class="org.broadleafcommerce.core.checkout.service.workflow.CheckoutProcessContextFactory"/>
</property>
<property name="activities">
<list>
<bean p:order="6000" id="blDecrementInventoryActivity" class="org.broadleafcommerce.core.checkout.service.workflow.DecrementInventoryActivity">
<property name="rollbackHandler" ref="blDecrementInventoryRollbackHandler" />
</bean>
<bean p:order="7000" id="blCompleteOrderActivity" class="org.broadleafcommerce.core.checkout.service.workflow.CompleteOrderActivity">
<property name="rollbackHandler" ref="blCompleteOrderRollbackHandler" />
</bean>
<bean p:order="9999999" class="com.mycompany.workflow.checkout.NotifyExternalInventorySystem" />
</list>
</property>
<property name="defaultErrorHandler">
<bean class="org.broadleafcommerce.core.workflow.DefaultErrorHandler">
<property name="unloggedExceptionClasses">
<list>
<value>org.broadleafcommerce.core.inventory.service.InventoryUnavailableException</value>
</list>
</property>
</bean>
</property>
</bean>
Starting with Broadleaf 4.0, the DecrementInventoryActivity was added by default to the blCheckoutWorkflow. See the 3.1.10-4.0.0 migration notes at http://www.broadleafcommerce.com/docs/core/4.0/migration-notes/3.1-to-4.0-migration/3.1.10-to-4.0-migration, in the section "Inventory Management".
This also goes for the defaultErrorHandler, and you can remove the blCompleteOrderActivity (that has always been managed in the framework). Basically, your customized blCheckoutWorkflow bean should change to:
<bean id="blCheckoutWorkflow" class="org.broadleafcommerce.core.workflow.SequenceProcessor">
<property name="activities">
<list>
<bean p:order="9999999" class="com.mycompany.workflow.checkout.NotifyExternalInventorySystem" />
</list>
</property>
</bean>
Starting with Broadleaf 3.0, any modifications to the blCheckoutWorkflow bean undergo the Broadleaf XML merging processing (which merges bean ids like blCheckoutWorkflow's list of activities). In your case, since the DecrementInventoryActivity is already defined in the core framework XML file and your definition of blCheckoutWorkflow merges with it, the final result is 2 instances of the DecrementInventoryActivity.
I asked a similar question, but based on the responses, I did a bad job describing what I am after. I have a spring 4 webapp that loads properties from a properties file. We consume those properties both via the "${proper.name"} expressions in spring, as well as by injecting a properties object into some of our classes.
We want to move most of the properties to a database table and make them reloadable. However, a few need to stay in local properties, potentially overriding the database setting. These should also be loaded dynamically after the app is running.
I know that once a particular bean is injected, it won't get reloaded, that doesn't concern me, it's up to that module to handle that. But I am having trouble getting the behavior I want. In particular, I have implemented an AbstractConfiguration from apache commons configuration to get the dual source and overriding I am after. But while it works for injecting the properties object, expressions loaded with "${prop.name}" don't work at all.
How can I get them to work? Did I override the wrong thing? Is it just some config detail?
<bean id="sysProperties" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="databaseConfigurator" />
<property name="targetMethod" value="getProperties"/>
</bean>
<bean id="databaseConfigurator" class="my.util.config.MyDatabaseConfigurator">
<property name="datasource" ref="dataSource" />
<property name="propertyFile" value="/WEB-INF/my.properties" />
<property name="applicationName" value="ThisApp" />
</bean>
<bean id="dbConfigFactory" class="org.apache.commons.configuration.ConfigurationConverter" factory-method="getProperties">
<constructor-arg ref="databaseConfigurator" />
</bean>
I haven't tested this, but I think it might work.
<bean id="sysProperties" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="databaseConfigurator" />
<property name="targetMethod" value="getProperties"/>
</bean>
<bean id="databaseConfigurator" class="my.util.config.MyDatabaseConfigurator">
<property name="datasource" ref="dataSource" />
<property name="propertyFile" value="/WEB-INF/my.properties" />
<property name="applicationName" value="ThisApp" />
</bean>
<bean name="PropertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" ref="CommonsConfigurationFactoryBean"/>
</bean>
<bean name="CommonsConfigurationFactoryBean" class="org.springmodules.commons.configuration.CommonsConfigurationFactoryBean">
<constructor-arg ref="databaseConfigurator"/>
</bean>
Here's what I am trying to do. I have a spring batch job which triggers a bean with multiple properties. I want these properties to be divided into separate beans for organizational purposes.
So I currently have this:
<bean id="runSQL" class="Tasklet"
scope="step">
<property name="sourceSQL"
value="SQL STATEMENT HERE" />
<property name="targetSQL"
value="SQL STATEMENT HERE"></property>
<property name="filePath" value="#{jobParameters['OUTPUT.FILE.PATH']}"> </property>
</bean>
but I basically want this (not working due to lack of class definition and I don't know if #{souce.sourceSQL} is a valid way of grabbing bean properties):
<bean id="runSQL" class="Tasklet"
scope="step">
<property name="sourceSQL"
value="#{source.sourceSQL}" />
<property name="targetSQL"
value="#{target.targetSQL}"></property>
<property name="filePath" value="#{jobParameters['OUTPUT.FILE.PATH']}"> </property>
</bean>
<bean id="sourceSQL" class="Class not needed"
scope="step">
<property name="sourceSQL"
value="SQL STATEMENT HERE" />
</property>
</bean>
<bean id="targetSQL" class="Class not needed"
scope="step">
<property name="sourceSQL"
value="SQL STATEMENT HERE" />
</property>
</bean>
I have tried to reference the beans traditionally with
<ref bean="someBean"/>
but my Tasklet isn't designed to receive a bean, just the property values and I would prefer to leave the Tasklet as is. How do I get around this or alternative ways of storing this data for the beans?
You're on the right track with #{...}. If you want to reference a bean, stick a # in front of the Spring bean ID, for example #{#sourceSQL.sourceSQL} and #{#targetSQL.sourceSQL}.
See the documentation for the Spring Expression language.
I am using a Soap WS and I have to customize timeout configuration per operation. The customization is actually done with cxf and its http-conf:conduit, which cannot be customized to the operation level.
My actual configuration is :
<bean id="proxyFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="com.package.PortType" />
<property name="address" ref="URL_WS" />
</bean>
<bean id="URL_WS" class="java.lang.String">
<constructor-arg value="http://serveraddress/Service"/>
</bean>
<http-conf:conduit name="http://serveraddress/Service.*">
<http-conf:client ConnectionTimeout="10000" ReceiveTimeout="10000"/>
</http-conf:conduit>
With this configuration, all the timeout of this WS are up to 10000ms.
As explained above, I would like to customize it to the operation level, I have found this link and tried to follow the process, but I'm in front of a problem of implementation, but I only com.ibm.wsdl.util.xml.QNameUtils in my classpath which has for the factory-method :
public static QName newQName(Node paramNode), method which takes a org.w3c.dom.Node.
I tried to change the code with this implementation coming to:
<bean id="proxyFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="delegate">
<jaxws:client serviceClass="com.package.PortType" address="URL_WS" >
<jaxws:outInterceptors>
<bean class="com.package.CustomTimeoutInterceptor">
<property name="receiveTimeoutByOperationName">
<map key-type="javax.xml.namespace.QName" value-type="java.lang.Long">
<entry value="10">
<key>
<bean class="com.ibm.wsdl.util.xml.QNameUtils" factory-method="newQName">
<!-- I don't know what to put here -->
</bean>
</key>
</entry>
</map>
</property>
</bean>
</jaxws:outInterceptors>
</jaxws:client>
</property>
</bean>
The Node's implementation I have is com.sun.org.apache.xerces.internal.dom.NodeImpl. I don't know which NodeImpl' subclass I have to use and how to create it to make it working in a bean way, I'm kinda losing myself in the documentation with these different implementations and these different dom Levels.
I just would like to create an Object subClass of Node which would work in this QNameUtils method
OR
find a different way to customize my configuration
I finally solved this problem, here is the working solution:
I kept the CustomTimeoutInterceptor of the link, mixed the solution with the help of this link.
I also kept my initial configuration, and I found that the javax.xml.namespace.QName had a factory method. I just added this part to my configuration:
<!-- Creation of the bean for the interceptor -->
<bean id="timeoutSetter" class="com.package.CustomTimeoutInterceptor">
<property name="receiveTimeoutByOperationName">
<map key-type="javax.xml.namespace.QName" value-type="java.lang.Long">
<entry value="20000">
<key>
<bean class="javax.xml.namespace.QName" factory-method="valueOf">
<constructor-arg value="{http://serveraddress/Service}Operation1" />
</bean>
</key>
</entry>
</map>
</property>
</bean>
<!-- I had the interceptor the list of outInterceptors -->
<cxf:bus>
<cxf:outInterceptors>
<ref bean="timeoutSetter"/>
</cxf:outInterceptors>
</cxf:bus>
I would like to have multiple Hibernate SessionFactories in a spring application, all of them with identical configurations except for the DataSource. Ideally, I would acquire a particular SessionFactory by name. I need to be able to do this based on runtime state, and it isn't possible to determine which session factories I will need at application startup time. Basically, I need a SessionFactoryTemplate or something like it.
Is this possible? How do I go about doing it?
You might define an abstract bean and use bean inheritance. This means you'll have a bean definition that works as a template and you may have multiple beans just copying the attributes set by the parent bean.
Here's an example:
<bean id="abstractSessionFactory" abstract="true"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="mappingResources">
<list>
<value>product.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.HSQLDialect
</value>
</property>
</bean>
<bean id="mySessionFactory" parent="abstractSessionFactory">
<property name="dataSource" ref="myDataSource"/>
...
</bean>
<bean id="mySessionFactory2" parent="abstractSessionFactory">
<property name="dataSource" ref="myDataSource2"/>
...
</bean>
Using the attribute 'abstract' you ensure that bean won't be instantiated and it will be used just as a template.
More info here: link text
Are you sure you need multiple SessionFactories? If all the mappings/configurations are the same and you just have multiple identical databases (e.g. in a multi-tenant app?), then how about having a single SessionFactory that connects to a DataSource which dynamically supplies the appropriate database connection?
See this question for more details:
And this blog post on Dynamic DataSource Routing in Spring.
I have no idea what your current bean definition looks like now, but wouldn't you just ... define a second SessionFactory?
<bean id="mySessionFactory1"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource1"/>
<property name="mappingResources">
<list>
<value>product.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.HSQLDialect
</value>
</property>
</bean>
<bean id="mySessionFactory2"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource2"/>
...
</bean>
You could then simply just wire your DAOs up with one sessionFactory vs the other:
<bean id="myProductDao" class="product.ProductDaoImpl">
<property name="sessionFactory" ref="mySessionFactory1"/>
</bean>
<bean id="myCompanyDao" class="product.ProductDaoImpl">
<property name="sessionFactory" ref="mySessionFactory2"/>
</bean>
I don't know of an easy solution for your problem using Spring.
However, you could be able to use Hibernate Interceptors, provided that your particular databases/data-sources can be reached through one master/admin database connection. This blog post explains how in detail, but the gist of it is to dynamically replace table names in SQL statements that Hibernate generates, with qualified names identifying different databases. This is relatively easy to understand and maintain, and works well in my company's multi-tenant set-up.
Apart from that, you can try writing your own TransactionManager, using the HibernateTransactionManager as a starting point, adding support for working with multiple session factories. However, this would mean you having to really dive into Spring ORM support internals, and that is something I tried, but then scrapped in favor of the first approach. I'm sure it can be done with moderate effort, but the previous solution was already doing the job for us.