Data persistence for repository and validators - java

In my current program, I must specify in a xml file the class that ensures the data persistence for every entity (repository) and the name of it's validator, and I have this example on how my xml file should look:
<beans>
<bean id="studentService" class="service.StudentService">
<property name="studentRepository" ref="studentRepository"/>
<property name="disciplineRepository" ref="disciplineRepository"/>
<property name="noteRepository" ref="noteRepository"/>
</bean>
<bean id="studentRepository" class="repository.StudentRepository">
<property name="validator" ref="studentValidator"/>
</bean>
<bean id="disciplineRepository" class="repository.DisciplineRepository">
<property name="validator" ref="disciplineValidator"/>
</bean>
<bean id="noteRepository" class="repository.NoteRepository">
<property name="validator" ref="noteValidator"/>
</bean>
<bean id="studentValidator" class="domain.StudentValidator"/>
<bean id="disciplineValidator" class="domain.DisciplineValidator"/>
<bean id="noteValidator" class="domain.NoteValidator"/>
</beans>
My question is, where I can find more information about exactly this kind of implementation, or how does the code to implement this xml file in my program should look?

Related

Spring batch to write multiple XML files using MultiResourceItemWriter

I am new to Spring batch and trying to write multiple XML files for each record that I am going to read from database table. Suppose if I read 10 records, I need to create 10 XML files. One for each record.
The name for each XML file should be unique. For that, I am planning to use "column_name1" value but I am not sure how to achieve that. If anyone can help me in this then that would be a great help.
Updated:
Added the #{formsPMVRowMapper.id} to resource property which can point to DefaultOutboundIFMRowMapper(Custom implementation of RowMapper) where I created a class level variable to set the row id. but still it's not working since it tries to call getter of ID even before getting into mapRow method which I think correct behviour but I am not sure how to get hold of that ID which I can use as resource name for my file in multiXmlFileItemWriter.
Could someone please let me know what could be the possibly correct way to do this?
Below is my Spring batch configuration file.
<util:properties id="batchProperties">
<prop key="batch.output.file">${outbound.pmv.filename}</prop>
</util:properties>
<bean id="itemReader" parent="pagingItemReader">
<property name="queryProvider" ref="outboundQueryProvider" />
<property name="rowMapper" ref="pmvRowMapper" />
</bean>
<bean id="pmvRowMapper"
class="tx.oag.cs.txcses.arch.batch.readers.DefaultOutboundIFMRowMapper">
<property name="idName" value="outbound_locate_record_staging_id" />
</bean>
<bean id="outboundQueryProvider" class="org.springframework.batch.item.database.support.SqlPagingQueryProviderFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="selectClause"
value="select column_name1" />
<property name="fromClause" value="from table_name" />
<property name="whereClause"
value="where column_name1='AAA' and column_name1='bbbb'" />
<property name="sortKey" value="column_name1" />
</bean>
<bean id="batchProcessor" parent="outboundStagingBatchProcessor">
<property name="entityClass"
value="Class_Name" />
</bean>
<bean id="itemWriter" parent="multiXmlFileItemWriter"/>
<bean id="multiXmlFileItemWriter"
class="org.springframework.batch.item.file.MultiResourceItemWriter">
<property name="resource" value="${outbound.ifm.outbound}/#{pmvRowMapper.id}">
</property>
<property name="delegate">
<bean class="org.springframework.batch.item.xml.StaxEventItemWriter">
<property name="marshaller">
<bean class="tx.oag.cs.txcses.arch.batch.utils.XMLStringMarshaller" />
</property>
</bean>
</property>
<property name="itemCountLimitPerResource" value="1" />
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location"
value="classpath:config/env/#{#env}/batch-outbound.properties" />
<property name="properties" ref="batchProperties" />
<property name="localOverride" value="true" />
</bean>
I understand that above "resource" property can only write files with same name but I am not sure how to use "resource" property well in co-ordination with "resourceSuffixCreator" property.

Setting Singleton Property as False for MethodInvokingFactoryBean in Spring

I have a prototype bean 'client' for which I want to call a method 'addHandler' every time it is instantiated. I am using 'MethodInvokingFactoryBean' for this. I the docs, I can see that by default MethodInvokingFactoryBean operates in a singleton fashion and caches the result of 'getObject' to return in subsequent calls.
To circumvent this, I want to call 'setSingleton' with 'false'. I am not sure about how to do this.
<bean id="provider" class="com.example.credProvider">
<constructor-arg value="key1"/>
</bean>
<bean id="handler" class="com.example.Handler"/>
<bean id="client" class="com.example.DBClient" scope="prototype">
<constructor-arg><ref local="provider"/></constructor-arg>
<property name="endpoint" value="http://xyz:8080/" />
</bean>
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject"><ref local="client"/></property>
<property name="targetMethod"><value>addHandler</value></property>
<property name="arguments">
<ref local="handler" />
</property>
</bean>
Will adding a scope="prototype" like this help? -
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" scope="prototype">
...
</bean>

Calling method in Bean property attribute

I have a simple bean tag in the bean xml file as shown below. This is just a dummy values
<bean id="myBeanId" class="myBeanClass">
<property name="myProperty" value=${myPassword} />
</bean>
<bean id ="myOtherBeanId" class="myOtherBeanClass">
<property name="myOtherProperty" ref="myBeanId">
</bean>
myPassword is a variable names stored in a separate properties file. Now, I instead of storing the direct value of myPassword from the properties file, I will have encrypted string in the property file and I want to call my custom written Decrypt method on myPassword property instead. something like this.
<bean id="myBeanId" class="myBeanClass">
<property name="myProperty" value=com.xxx.Security.Decrypt(${myPassword}) />
</bean>
How can I do this?
Use the MethodInvokingFactoryBean if you want to invoke another bean's method and use the returned object as a bean.
<bean id="securityBean" class="com.xxx.Security">
</bean>
<bean id="myBeanId" class="myBeanClass">
<property name="myProperty">
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject"><ref local="securityBean"/></property>
<property name="targetMethod"><value>Decrypt</value></property>
<property name="arguments">
<list>
<value>${myPassword}</value>
</list>
</property>
</bean>
</property>
</bean>
How about Using with jaspyt,
Properties file entry
password=ENC(G6N718UuyPE5bHyWKyuLQSm02auQPUtm)
Bean Entry
<bean id="myBeanId" class="myBeanClass">
<property name="myProperty" value=${password} />
</bean>
Source : http://www.jasypt.org/spring31.html

Usage of P6Spy with datasource in Spring applicationContext.xml

I am using Hibernate 4, Spring 3, JSF 2.0 and Weblogic 10.3.6 as server.
I have created datasource on Weblogic server and in applicationContext.xml I have defined datasource as
<!-- Data Source Declaration -->
<bean id="DataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/​myDS"/>
</bean>
If I would want to use the P6Spy for logging SQL parameters, how can and where I should add the following in applicationcontext.xml?
<property name="hibernate.connection.driver_class">com.p6spy.engine.spy.
P6SpyDriver</property>
Any help is highly appreciable.
Thanks
The easiest way to integrate p6spy using spring is to use the P6DataSource class. The P6DataSource class is just a proxy for the real data source. This lets you obtain the real data source using any of the spring data source factory implementations.
<bean id="dataSource" class="com.p6spy.engine.spy.P6DataSource">
<constructor-arg>
<bean id="DataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/​myDS"/>
</bean>
</constructor-arg>
</bean>
If you are using an XADatasource, just change the classname to P6ConnectionPoolDataSource as shown below. Note: P6ConnectionPoolDataSource implements the ConnectionPoolDataSource and XADataSource interfaces.
<bean id="dataSource" class="com.p6spy.engine.spy.P6ConnectionPoolDataSource">
<constructor-arg>
<bean id="DataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/​myDS"/>
</bean>
</constructor-arg>
</bean>
You need to create bean of session factory in applicationContext.xml file as follows:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.p6spy.engine.spy.
P6SpyDriver" />
<property name="url" value="jdbc\:mysql\://localhost\:3306/testdb" />
<property name="username" value="my_username" />
<property name="password" value="my_password" />
</bean>
Please refer to: http://www.mkyong.com/hibernate/how-to-display-hibernate-sql-parameter-values-solution/ for more about P6Spy library.
We can omit "dataSource" bean and directly write properties. Ref: how to configure hibernate config file for sql server

JPA Multiple Persistence Unit bug

I'm trying to add one more database/schema/persistenceUnit in my project and I'm receiving the error:
No unique bean of type [javax.persistence.EntityManagerFactory] is defined: expected single bean but found 2
I google/api allot and could not found why spring is complaining about my configuration.
Here is part of my applicationContext.xml
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="transactionManager" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="${show.hibernate.sql}" />
<property name="generateDdl" value="false" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect" />
</bean>
</property>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${database.driver}" />
<property name="url" ...
<property name="testOnBorrow" value="true" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="entityManagerFactoryREST" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSourceREST" />
<property name="persistenceUnitName" value="REST" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="${show.hibernate.sql}" />
<property name="generateDdl" value="false" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect" />
</bean>
</property>
</bean>
<bean id="dataSourceREST" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${database.driver}" />
...
<property name="testOnBorrow" value="true" />
</bean>
<bean id="transactionManagerREST" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryREST" />
</bean>
<tx:annotation-driven transaction-manager="REST"/>
<tx:annotation-driven transaction-manager="transactionManager"/>
Some questions:
Do I need to have two tx:annotation-driven ?
Do I need to specify persistenceUnitName in the factory ?
I'm putting some notes of my digg in spring forum (LINK)
Well thats it... any help will be glad!
With Spring, you need to have only one EntityManagerFactory.
What you are looking for is describe in the Spring documentation at the chapiter 13.5.1.4 : "Deals with multiple persitence units"
I copy/paste the text :
"13.5.1.4 Dealing with multiple persistence units
For applications that rely on multiple persistence units locations, stored in various JARS in the classpath, for example, Spring offers the PersistenceUnitManager to act as a central repository and to avoid the persistence units discovery process, which can be expensive. The default implementation allows multiple locations to be specified that are parsed and later retrieved through the persistence unit name. (By default, the classpath is searched for META-INF/persistence.xml files.)
<bean id="pum" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<property name="persistenceXmlLocations">
<list>
<value>org/springframework/orm/jpa/domain/persistence-multi.xml</value>
<value>classpath:/my/package/**/custom-persistence.xml</value>
<value>classpath*:META-INF/persistence.xml</value>
</list>
</property>
<property name="dataSources">
<map>
<entry key="localDataSource" value-ref="local-db"/>
<entry key="remoteDataSource" value-ref="remote-db"/>
</map>
</property>
<!-- if no datasource is specified, use this one -->
<property name="defaultDataSource" ref="remoteDataSource"/>
</bean>
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitManager" ref="pum"/>
<property name="persistenceUnitName" value="myCustomUnit"/>
</bean>
The default implementation allows customization of the PersistenceUnitInfo instances, before they are fed to the JPA provider, declaratively through its properties, which affect all hosted units, or programmatically, through the PersistenceUnitPostProcessor, which allows persistence unit selection. If no PersistenceUnitManager is specified, one is created and used internally by LocalContainerEntityManagerFactoryBean."
This exceptions means that you are trying to autowire EntityManagerFactory by type. Do you have any #Autowired annotation in your code?
Aslo, when using #PersistenceContext, set the unit attribute correctly. And (I'm not sure if this is a proper thing to do) - try setting the name attribute to your respective factory name.
Also, check if you haven't copy-pasted incorrectly the REST transaction manager - now there is no such bean REST
Ensure all of your #PersistenceContext specify unitName. I haven't figured out how to tell Spring that a particular EMF or PersistenceUnit is the default. I thought specifying primary="true" on the default EMF would work but doesn't appear to
Do I need to specify persistenceUnitName in the factory ?
If you've got multiple persistence units, you do need to specify which ones the factories will use.
More to the heart of the matter, see SPR-3955. To summarize, versions prior to Spring 3.0M4 do not support multiple transaction managers with #Transactional. Nor do I believe it honors the "unitName" attribute for #PersistenceContext, so you can't specify that either.
For an example of how I worked around this by explicitly injecting EntityManagerFactorys and using AOP to re-enable #Transactional, see my sample app

Categories