Spring data jpa add filter/interceptor - spring

I have used hibernate before, and have successfully added a filter that would intercept saves and entities who implemented a certain interface would have something logged.
Is it possible to do something similar in the new Spring Data, I have just started out using it.

Yes you can always add filters/interceptors with spring data
Following is an example:
<bean id="customizableTraceInterceptor" class="
org.springframework.aop.interceptor.CustomizableTraceInterceptor">
<property name="enterMessage" value="Entering $[methodName]($[arguments])"/>
<property name="exitMessage" value="Leaving $[methodName](): $[returnValue]"/>
</bean>
<aop:config>
<aop:advisor advice-ref="customizableTraceInterceptor"
pointcut="execution(public * org.springframework.data.jpa.repository.JpaRepository+.*(..))"/>
</aop:config>
reference: http://static.springsource.org/spring-data/data-jpa/docs/current/reference/html/

Related

How to define a PropertyPlaceholderConfigurer local to a specific bean?

I've been using org.springframework.beans.factory.config.PropertyPlaceholderConfigurer and in my experience ("citation needed" LOL) it sets the property values globally.
Is there a way to specify different PropertyPlaceholderConfigurer instances for different beans within the same application context xml?
My current code is similar to
<bean id="a" class="X">
<property name="foo" value="bar"/>
<property name="many" value="more"/>
</bean>
<bean id="b" class="X">
<property name="foo" value="baz"/>
<property name="number_of_properties" value="a zillion"/>
</bean>
I would like to do something like (pseudo-code below):
<bean id="a" class="X">
... parse the contents of "a.properties" here ...
</bean>
<bean id="b" class="X">
... parse the contents of "b.properties" here ...
</bean>
The above is non-working pseudo code to illustrate the concept; the point being, I want a different properties file to feed each bean.
WHY?
I want to have those specific properties in separate properties file and not in XML.
I think the following link can br helpful to you.
Reference Link
where #Value("${my.property.name}") annotation is used to bind the property file to a variable of type Properties which will reside in your bean class where you intend to use that properties file.
and you can define multiplte proprtiesplaceholder as below:
<bean id="myProperties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath*:my.properties</value>
</list>
</property>
</bean>
and use the id as reference in your bean variable to initialize properties file to the bean.
And it will be handy to include with placeholder bean.
Kindly refer Importance of Unresolvable Placeholder link for detailed info regarding its usage.
Hope this was helpful.

Can we replace Springframework annotations (#CacheConfig, #Cacheable, #CachePut) in the XMl file?

I am implementing a module with Spring Cache mechanism. The module is generic and can cache different type of entities. So I don't want to change the Java code and want the user to configure the applicationcontext.xml file accordingly. He can put the name of the different types of entities within the applicationcontext.xml and the code should work. For e.g. -
<context:annotation-config/>
<cache:annotation-driven cache-manager="cacheManager"/>
<context:component-scan base-package="com.nokia.oss.sure.adapter"/>
<bean id="NetworkEntityService" class="com.nokia.oss.sure.adapter.cache.NetworkEntityServiceImpl"/>
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" name="NetworkEntity"/>
</set>
</property>
</bean>
He may change NetworkEntity to ServiceEntity and so on.
So in the Java code I need to mention -
#CacheConfig(cacheNames={"NetworkEntity"})
Or I can put the same for every method -
#CachePut(cacheNames="NetworkEntity", key="#entity.sureName")
public Entity addEntity(Entity entity) {
return entity;
}
But as I stated earlier, I don't want to put the cache name "NetworkEntity" in the Java code, but want to put the same in the applicationcontext.xml file. Is it possible?
Furthermore is it possible to omit all the annotations in the Java file? If I just use AbstractApplicationContext context = new GenericXmlApplicationContext("applicationContext.xml"); is it possible to mention in the applicationContext.xml file what are the methods where I want to apply the #Cacheable annotation for e.g.
I searched a lot, couldn't find it anywhere.
Thanks
Nirmalya
I found out the answer. We can put the following in the applicationContext.xml -
<!-- define caching behavior -->
<cache:advice id="cacheAdviceInterface" cache-manager="cacheManager">
<cache:caching cache="NetworkEntity">
<cache:cacheable method="getEntity"/>
<cache:cache-put method="putEntity"/>
</cache:caching>
</cache:advice>
In that case we don't need to put the #CacheConfig, #CachePut etc annotations within the Java file.

Problem with AOP/AspectJ not executing on criterion

Does anyone know why the following AOP/AspectJ doesn't work in Examples 2,3 ?
Note: Example 1 works.
My goal is to intercept the firing of Hibernate Query's executeUpdate(), which occurs throughout the application. Hibernate Query is an interface, and I see in the code that the implementing class I get back is QueryImpl. So that is the class I want to target, although I've tried generic filters too.
XML
<aop:config>
<aop:aspect id="myAspect" ref="aspectBean">
<!-- EXAMPLE 1: SIMPLE TEST: WORKS OK.
I intercept all methods in all my custom classes in "dao" package. -->
<aop:pointcut id="test1" expression="execution(* myapp.dao.*.*(..))" />
<aop:before pointcut-ref="test1" method="doTest1" />
<!-- EXAMPLE 2: DOESN'T WORK.
Target everything in Hibernate's Impl package with executeUpdate() function -->
<aop:pointcut id="executeUpdate2" expression="execution(* org.hibernate.impl..*..executeUpdate(..))" />
<aop:before pointcut-ref="executeUpdate2" method="handleExecuteUpdate" />
<!-- EXAMPLE 3: DOESN'T WORK.
Target QueryImpl specifically -->
<aop:pointcut id="executeUpdate3" expression="execution(* org.hibernate.impl.QueryImpl.executeUpdate(..))" />
<aop:before pointcut-ref="executeUpdate3" method="handleExecuteUpdate" />
</aop:aspect>
</aop:config>
<bean id="aspectBean" class="myapp.util.AOPAspect">
</bean>
I know for a fact the Hibernate hierarchy is correct. Example #1 works great so I know the AOP/AspectJ is wired properly. Is there something about external library traversal that doesn't support AOP/AspectJ?
I found out it doesn't work because I'm dealing with an external JAR (in this case, Hibernate). Example 1 works because I'm within my own code.
No easy solutions for external JAR pointcuts, only Load-Time Weaving is possible (but I haven't tried it),
Aspectj: intercept method from external jar

Difference b/w primary and autowire-candidate attribute of bean tag in spring

I am new to spring. When i am going through auto wiring byType i came to know about these attributes primary and autowire-candidate.
I didn't get the exact difference b/w these two as setting these parameter to false will make the other bean a candidate for autowiring.
Can anybody help me in understanding these two.
Thanks
Let say there is interface
interface Translator { String translate(String word);}
Your application use the translator widely to translate from English to Polish. However, is some specific case you want to use dedicated translator, because vocabulary is specific. For example, string always means "sequence of characters" but never "underwear".
Sample configuration:
<bean class="EnglishToPolishTranslator" />
<bean class="ComputerScienceEnglishToPolishTranslator" autowire-candidate="false"/>
Everywhere EnglishToPolishTranslator will be autowired except some concrete place where ComputerScienceEnglishToPolishTranslator will be injected by reference.
Some day next customer arrive with requirement: use simpler words. The requirement is achieved by class SimpleEnglishToPolishTranslator. But computer science translator should remain unchanged: it is too costly to modify it.
Your company want keep product easy to maintain. Base application will not be modified, but for the customer the product will extended with extra library configured:
<bean class="SimpleEnglishToPolishTranslator" primary="true"/>
In result, everywhere SimpleEnglishToPolishTranslator will be used except computer science area.
Maybe it is overcomplicated, but shows a difference I found between autowire-candidate and primary
BTW, "autowire-candidate" doesn't have corresponding annotation. It looks to me that "autowire-candidate" is dead end in Spring evolution
if we configure bean for more than one time with different ids then IOC will throw an Exception. To overcome this duplicate beans problem, we can use autowire-candidate=”false” or primanry="true"
Example: i have two classes Mobile and Processor
Case -1: autowire-candidate=”false”
<bean id="mobile" class="com.Mobile" autowire="byType">
<property name="mobileName" value="Redmi"></property>
<property name="mobileModel" value="Note 5"></property>
</bean>
<bean id="process1" class="com.Processor"
autowire-candidate="false">
<property name="process" value="2GHz"></property>
<property name="ram" value="4GB"></property>
</bean>
<bean id="process2" class="com.Processor">
<property name="process" value="1GHz"></property>
<property name="ram" value="3GB"></property>
</bean>
As per above configuration, process1 bean will be ignored and process2 bean will be injected.
Case -2: primanry="true"
<bean id="mobile" class="com.Mobile" autowire="byType">
<property name="mobileName" value="Redmi"></property>
<property name="mobileModel" value="Note 5"></property>
</bean>
<bean id="process1" class="com.Processor" primary="true">
<property name="process" value="2GHz"></property>
<property name="ram" value="4GB"></property>
</bean>
<bean id="process2" class="com.Processor">
<property name="process" value="1GHz"></property>
<property name="ram" value="3GB"></property>
</bean>
As per above configuration, process2 bean will be ignored and process1 bean will be injected.

How to partition a large file using spring batch

I want to read a large text file using Spring Batch. I want to use Partition logic provided by Spring Batch. The partitioners that are already available does not solve my purpose. I want to read file through FlatFileReader using partitions.
Please help.
You can configure the ThreadPoolTaskExecutor and tweak the various properties according to your needs
<bean name="batchTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" >
<property name="maxPoolSize" value="6"/>
<property name="corePoolSize" value="4"/>
<property name="threadNamePrefix" value="batchitem"/>
<property name="threadGroupName" value="BATCH"/>
</bean>
Then when you configure your tasklet inside your step which will do the actual chunk processing add the attribute for the configured taskExecutor. For example
<batch:tasklet task-executor="batchTaskExecutor" transaction-manager="transactionManager" allow-start-if-complete="true">

Resources