I have a JAR that embedded within a webservice that has local Gemfire Caching. The problem that I am trying to solve is expiration of this data.
I have created a custom expiration timer that will set each entries expiration in seconds and have tied a listener to check for afterInvalidate(EntryEvent e).
Here is my region declaration in spring
<bean id="rse-region" class="org.springframework.data.gemfire.RegionFactoryBean"
p:name="rse-region" p:cache-ref="gemfire-cache-embedded">
<property name="cacheListeners">
<array>
<bean class="CustomListener"/>
</array>
</property>
<property name="attributes">
<bean class="org.springframework.data.gemfire.RegionAttributesFactoryBean"
p:enableGateway="false"
p:statisticsEnabled="true"
p:dataPolicy="NORMAL"
p:customEntryTimeToLive-ref="customExpiration">
</bean>
</property>
</bean>
What I am trying to do is a bit different than how I have setup. What I am trying to do is once the initial entry is put into the region I want a Time to Live on that region. Is it possible to do Time to Live on a local gemfire region?
It is. Spring Data GemFire provides for region time-to-live.
Related
We have Spring scheduled job with cron expression which is configured in database. I need to change schedule time without restart the application server. But i could not achieve this and i have tried many ways using SO solutions in other link, but none worked for me. Below is my code snippet.
Scheduler time will get from database during dispatcher servlet initializing and assign in the property variable test.scheduler
Scheduler.java
#Scheduled(cron = "${test.scheduler}")
public void testScheduler() {
System.out.println("Dynamic Scheduler Run Test"+new java.util.Date().getTime());
}
dispatcher-servlet.xml
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="properties">
<bean class="org.apache.commons.configuration.ConfigurationConverter" factory-method="getProperties">
<constructor-arg>
<bean class="org.apache.commons.configuration.DatabaseConfiguration">
<constructor-arg>
<ref bean="dataSource" />
</constructor-arg>
<constructor-arg value="TABLE_NAME" />
<constructor-arg value="TABLE_KEY" />
<constructor-arg value="TABLE_VALUE" />
</bean>
</constructor-arg>
</bean>
</property>
</bean>
From the table (TABLE_NAME), there is column's key is test.scheduler & value is 0 0/5 * * * ?
As far as I am aware, SpEL won't let you change the value of your scheduler once it has been initialised.
If you are using Spring Boot, you will be able to use Actuator to trigger a refreshed event:-
http://localhost:8080/actuator/refresh
In which case, you can make the bean implement RefreshedScope and update your scheduler by triggering the RefreshScopeRefreshedEvent:
#EventListener(RefreshScopeRefreshedEvent.class)
public void onRefresh(RefreshScopeRefreshedEvent event) {
// Read the database, update the scheduler.
}
An example implementation of this can be seen here.
This might not be the perfect solution to your problems but I am posting it for visibility and to help others.
An alternative solution may involve using a Trigger to determine the next execution time. An example StackOverflow answer can be seen here.
I'm configuring a pool of objects using apache commons pool2. It seems the objects in the pool are only created when an attempt is made to borrow an object. I'd like the objects to be created up front, so I have a minimum number of objects ready when the first one needs to be borrowed.
My spring configuration looks something like this:
<bean id="webSocketConnectionPool" class="org.apache.commons.pool2.impl.GenericObjectPool">
<constructor-arg ref="webSocketConnectionFactory"/>
<constructor-arg ref="webSocketConnectionPoolConfig"/>
</bean>
<bean id="webSocketConnectionFactory" class="com.blah.WebSocketConnectionFactory" />
<bean id="webSocketConnectionPoolConfig" class="org.apache.commons.pool2.impl.GenericObjectPoolConfig">
<property name="maxIdle" value="300"/>
<property name="maxTotal" value="1000"/>
<property name="minIdle" value="10"/>
</bean>
I can see the pool is created when the app starts, but the minIdle setting doesn't seem to result in my desired behaviour. The create() method on the factory is only called when the first object is borrowed.
Any tips would be appreciated.
Thanks
My solution was to add some logic to the init method of the class with the connection pool as a member, to add objects. Hopefully this will help someone else in the future.
connectionPool.addObjects(connectionPool.getMinIdle());
I wanted to know how I can perform user locking (or the best way to perform the same) i.e. if a user is already logged in from a device and tries to login from another device, he/she should be notified that a session is already available for that user and an option to close other session and start a new one.
Framework Used Spring-MVC + hibernate 4.1.
And one more thing: how can I set a list of some user hashmap object in application context?
That can be done with Spring Security and Conncurrent Session Control. You can define how many sessions may exist concurrently and decide what to do if the maximum exceeds.
Their is a simple xml configuration in spring security for the same. First you have to register the SessionRegistry bean. I have used default class of SessionRegistryImpl of spring security for Session registry like :
<bean id="sessionRegistry"
class="org.springframework.security.core.session.SessionRegistryImpl" />
After that we have to register the ConcurrentSessionControlStrategy with container and tell it the maximum session allowed per user.
Example:
<bean id="sessionStrategy"
class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
<constructor-arg name="sessionRegistry" ref="sessionRegistry" />
<property name="maximumSessions"
value="${security.config.sessionStrategy.maximumSessions.value}" />
<property name="exceptionIfMaximumExceeded" value="true" />
</bean>
security.config.sessionStrategy.maximumSessions.value is the integer value specified in property file. By varying the maximumSessions property value we can define maximum concurrent users easily.
This is regarding Spring OpenSessionInViewFilter using with #Transactional annotation at service layer.
i went through so many stack overflow post on this but still confused about whether i should use OpenSessionInViewFilter or not to avoid LazyInitializationException
It would be great help if somebody help me find out answer to below queries.
Is it bad practice to use OpenSessionInViewFilter in application
having complex schema.
using this filter can cause N+1 problem
if we are using OpenSessionInViewFilter does it mean #Transactional not required?
Below is my Spring config file
<context:component-scan base-package="com.test"/>
<context:annotation-config/>
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="resources/messages" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/jdbc.properties" />
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.databaseurl}" p:username="${jdbc.username}"
p:password="${jdbc.password}" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
<!--
<prop key="hibernate.hbm2ddl.auto">create</prop>
-->
</props>
</property>
</bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
OpenSessionInView is a servlet filter than just Open a hibernate session and store it in the SessionHolder for the thread that is serving the request. With this session opened, hibernate can read the Lazy initialized collections and objects when you use this in the rendering stage of the request. This session can be accessed when you invoke SessionFactory.getCurrentSession().
But, OpenSessionInView just opens the session and it doesn't begin any transactions. With a session opened you can read objects from database but, if you want to do something in a transaction you need #Transactional annotations or other mechanism to demarcate the begin and the end of the transaction when you want.
Then the answer of the questions:
Is it bad practice to use OpenSessionInViewFilter in application having complex schema.
This is a good practice if you need avoid the LazyInitializationException and the overload is just open new Hibernate Session and close it at the end of the request for each request.
Using this filter can cause N+1 problem
I use this filter in many projects and not cause any problem.
if we are using OpenSessionInViewFilter does it mean #Transactional not required?
No. You only have a Hibernate Session opened in the SessionHolder of the thread, but if you need Transactions you need put #Transactional.
Throwing in my 0.02c here (and expanding on Fernando Rincon's excellent answer):
You shouldn't be using a OpenSessionInView filter just because you need to get around a LazyInitializationException. Its just going to add another layer of confusion and complexity to your system. You should know from your system design exactly where you are going to need to access collections on the front end. From there, it's easy and (in my experience) more logical to build a controller method to call a service method to retrieve your collection.
However if you have another problem that using the OpenSessionInView filter solves, and as a happy side effect you then have a session open, then I don't see the harm in using it to access your collections. However, I'd say that if you use the OpenSessionInView to fetch a collection object in one place, you should refactor your code in other places to do the same thing so as the strategy used to fetch collections is standardised across your application.
Weigh up the costs of this refactor against the cost of writing the controller & service methods to determine if you should be using a OpenSessionInView filter.
OpenSessionInViewFilter is a servlet filter that binds a hibernate session to http request and for all db operations, transactional and non transactional, same hibernate session is used for a given http request. This exposes db layer to web layer that makes it anti-pattern.
My experience is that this makes the code difficult to debug when we want to make changes to java objects and do not want those to get reflected in database. Since the hibernate session is always open, it expects to flush the data in database.
This should be used only when JS base rest services are there with no service layer in between.
The typical usage pattern for OpenSessionInViewFilter is that some Entity is lazily loaded but during the view rendering phase the view needs some attribute of this Entity that was not loaded initially thus necessitating the need to fetch this data from the database. Now typically the transaction demarcation is made to happen in the service layer of your web application so by the time the view rendering takes place the view is working with a detached entity which results in a LazyInitializationException when accessing the unloaded attribute.
From this url https://developer.jboss.org/wiki/OpenSessionInView :
The problem
A common issue in a typical web-application is the rendering of the view, after the main logic of the action has been completed, and therefore, the Hibernate Session has already been closed and the database transaction has ended. If you access detached objects that have been loaded in the Session inside your JSP (or any other view rendering mechanism), you might hit an unloaded collection or a proxy that isn't initialized. The exception you get is: LazyInitializationException: Session has been closed (or a very similar message). Of course, this is to be expected, after all you already ended your unit of work.
A first solution would be to open another unit of work for rendering the view. This can easily be done but is usually not the right approach. Rendering the view for a completed action is supposed to be inside the first unit of work, not a separate one. The solution, in two-tiered systems, with the action execution, data access through the Session, and the rendering of the view all in the same virtual machine, is to keep the Session open until the view has been rendered.
As an alternative, consider loading the Entity with just the right amount of data required by your view. This can be accomplished by using DTO projections. This article lists some of the downsides of using the Open Session In View pattern : https://vladmihalcea.com/the-open-session-in-view-anti-pattern/
I need to load a specific applicationContext.xml file according to a given system property. This itself loads a file with the actual configuration. Therefore I need two PropertyPlaceHolderConfigurer, one which resolves the system param, and the other one within the actual configuration.
Any ideas how to do this?
Yes you can do more than one. Be sure to set ignoreUnresolvablePlaceholders so that the first will ignore any placeholders that it can't resolve.
<bean id="ppConfig1" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<property name="locations">
<list>
<value>classpath*:/my.properties</value>
</list>
</property>
</bean>
<bean id="ppConfig2" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="false"/>
<property name="locations">
<list>
<value>classpath*:/myOther.properties</value>
</list>
</property>
</bean>
Depending on your application, you should investigate systemPropertiesMode, it allows you to load properties from a file, but allow the system properties to override values in the property file if set.
Another solution is to use placeholderPrefix property of PropertyPlaceholderConfigurer. You specify it for the second (third, fourth...) configurer, and then prefix all your corresponding placeholders, thus there will be no conflict.
<bean id="mySecondConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="classpath:/myprops.properties"
p:placeholderPrefix="myprefix-"/>
<bean class="com.mycompany.MyClass" p:myprop="${myprefix-value.from.myprops}"/>
Beware -- there might be a bug related to multiple configurers. See http://jira.spring.io/browse/SPR-5719 for more details.
I'm unable to get multiple to work locally... but I'm not yet blaming anyone but myself.
On my own side, playing with PropertyPlaceholderConfigurer both properties :
order (should be lower for first accessed/parsed PPC)
ignoreUnresolvablePlaceholders ("false" for first accessed/parsed PPC, "true" for next one)
and also give 2 distinct id(s) to both PPC (to avoid one to be overwritten by the other)
works perfectly
Hope it helps
You can't do this directly, and this JIRA issue from Spring explains why (check the comment from Chris Beams for a detailed explanation):
https://jira.springsource.org/browse/SPR-6428
However, he does provide a workaround using Spring 3.1 or later, which is to use the PropertySourcesPlaceholderConfigurer class instead of PropertyPlaceholderConfigurer class.
You can download a Maven-based project that demonstrates the problem and the solution from the Spring framework issues github:
https://github.com/SpringSource/spring-framework-issues
Look for the issue number, SPR-6428, in the downloaded projects.
We have the following approach working:
<util:properties id="defaultProperties">
<prop key="stand.name">DEV</prop>
<prop key="host">localhost</prop>
</util:properties>
<context:property-placeholder
location="file:${app.properties.path:app.properties}"
properties-ref="defaultProperties"/>
System property app.properties.path can be used to override path to config file.
And application bundles some default values for placeholders that cannot be defined with defaults in common modules.
Just giving 2 distinct ids worked for me. I am using spring 3.0.4.
Hope that helps.
In case, you need to define two PPC's (like in my situation) and use them independently. By setting property placeholderPrefix, you can retrieve values from desired PPC. This will be handy when both set of PPC's properties has same keys, and if you don't use this the property of ppc2 will override ppc1.
Defining your xml:
<bean name="ppc1"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" ref="ref to your props1" />
<property name="placeholderPrefix" value="$prefix1-{" />
</bean>
<bean name="ppc2"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" ref="ref to your props2" />
<property name="placeholderPrefix" value="$prefix2-{" />
</bean>
Retrieving during Run time:
#Value(value = "$prefix1-{name}")
private String myPropValue1;
#Value(value = "$prefix2-{name}")
private String myPropValue2;