Need to implement paginating for an spring batch application. The Query has multiple join, Guide for an effective Pagining query, with existing table model can this join be effectively written to pagination where "ED_EMP_LOGIN_STATE" is the filter where other tables are select. running this query is still slow and look likes paginzation with rownnum condition does not show any impact on execution plan.
How this query can be modified to pass in spring batch paginzation reader
<bean id="empItemReader" class="org.springframework.batch.item.database.JdbcPagingItemReader" scope="step">
<property name="dataSource" ref="empDataSource" />
<property name="rowMapper">
<bean class="org.sample.model.EmployeeMapper" />
</property>
<property name="queryProvider">
<bean class="org.springframework.batch.item.database.support.SqlPagingQueryProviderFactoryBean">
<property name="dataSource" ref="empDataSource" />
<property name="sortKeys">
<map>
<entry key="ID" value="ASCENDING"/>
</map>
</property>
<!-- Intentionally put sort key second in the query list as a test -->
<property name="selectClause" >
<value>
<![CDATA[
emp_task_sub_details.DEP_NAME AS DEP_NAME
,emp_task_sub_details.EmpName AS EmpName
,emp_task_sub_details.EmpFirstName AS EmpFirstName
,emp_task_sub_details.EmpIDCard AS EmpIDCard
,emp_task_sub_details.EmpBuilding AS EmpBuilding
,emp_task_sub_details.EmpLocation EmpLocation ENV_CAT
,emp_task_sub_details.NAME AS NAME
,ed_parent_join.task_name AS TASK_NAME
,ed_parent_join.start_time AS TASK_NAME_START_TIME
,ed_parent_join.finish_time AS TASK_NAME_END_TIME
,emp_task_sub_details.STATUS AS STATUS
,emp_task_sub_details.STATE_ID AS ID
]]>
</value>
</property>
<property name="fromClause">
<value>
<![CDATA[
ED_EMP_LOGIN_STATE ed_parent_join
JOIN (
select
ed_dep.name as DEP_NAME
,empName_code_prop.string as EmpName
,empfirst_code_prop.string as EmpFirstName
,id_code_prop.string as EmpIDCard
,build_code_prop.string as EmpBuilding
,loc_code_prop.string as EmpLocation
,ed_emp.name as NAME
,ed_emp_lg_st.id as STATE_ID
,ed_emp_tas_wk.STATUS AS STATUS
from
ED_DEPARTMENT ed_dep
,ED_EMPLOYEE ed_emp
,ed_emp_tas_wkK ed_emp_tsk
,ED_EMP_LOGIN ed_emp_lg
,ED_EMP_LOGIN_STATE ed_emp_lg_st
,ED_EMP_LOGIN_WORK ed_emp_tas_wk
,ED_TASK_PROPS empName_code_prop
,ED_TASK_PROPS empfirst_code_prop
,ED_TASK_PROPS id_code_prop
,ED_TASK_PROPS build_code_prop
,ED_TASK_PROPS loc_code_prop
,ED_ACTIVITY ed_act
,ED_LOCATION ed_loc
where
ed_emp.id = ed_dep.id
and ed_emp.tsk_id = ed_emp_tsk.id
and ed_emp_lg.tsk_id = ed_emp_tsk.id
and ed_emp_lg_st.parent_emp_id = ed_emp_lg.id
and ed_emp_tas_wk.state_id = ed_emp_lg_st.id
and ed_emp_lg.prop_id = empName_code_prop.parent_prop_id
and empName_code_prop.name = 'EmpName'
and ed_emp_lg.prop_id = empfirst_code_prop.parent_prop_id
and empfirst_code_prop.name = 'EmpFirstName'
and ed_emp_lg.prop_id = id_code_prop.parent_prop_id
and id_code_prop.name = 'EmpIDCard'
and ed_emp_lg.prop_id = build_code_prop.parent_prop_id
and build_code_prop.name = 'EmpBuilding'
and ed_emp_tas_wk.JOB_ID = ed_act.id
and ed_act.environment_name = ed_loc.name
and ed_loc.prop_id = loc_code_prop.parent_prop_id
and loc_code_prop.name = 'EmpLocation') emp_task_sub_details
ON emp_task_sub_details.STATE_ID = ed_parent_join.id
]]>
</value>
</property>
<property name="whereClause">
<value>
<![CDATA[
ed_parent_join.start_time >= :startTime
and ed_parent_join.finish_time < :finishTime
]]>
</value>
</property>
</bean>
</property>
<property name="pageSize" value="${loadPageCommitSize}" />
<property name="parameterValues">
<map>
<entry key="startTime" value="#{jobParameters[StartTime]}" />
<entry key="finishTime" value="#{jobParameters[FinishTime]}" />
</map>
</property>
</bean>
Related
Here is my HashMap in spring context which uses value-ref :
<util:map id="generalDAOMap" map-class="java.util.HashMap">
<entry key="1" value-ref="userDAO" />
<entry key="2" value-ref="accountsDAO" />
<entry key="3" value-ref="settingsDAO" />
</util:map>
<bean id="userDAO"
class="com.test.myproj.dao.impl.UserDAOImpl" />
<bean id="accountsDAO"
class="com.test.myproj.dao.impl.AccountsDAOImpl" />
<bean id="settingsDAO"
class="com.test.myproj.dao.impl.SettingsDAOImpl" />
In my Java class i have autowired the "generalDAOMap" as below:
#AutoWired
private Map<String,GeneralDAO> generalDAOMap;
//getters and setters follows
When i print the map value its as follows :
{userDAO = com.test.myproj.dao.impl.UserDAOImpl#164d6ae,accountsDAO = com.test.myproj.dao.impl.AccountsDAOImpl#ed9382 , settingsDAO = com.test.myproj.dao.impl.SettingsDAOImpl#ed9586}
but the Key values should be "1","2" and "3" , why its getting replaced as "userDAO ","settingsDAO " and "accountsDAO ", due to which when i use getGeneralDAOMap.get("1") it returns null. Kindly help.
Can you try using #Resource instead of using #Autowired ?
Spring docs says this,
As a specific consequence of this semantic difference, beans that are themselves defined as a collection or map type cannot be injected through #Autowired, because type matching is not properly applicable to them. Use #Resource for such beans, referring to the specific collection or map bean by unique name.
you can try ...
<util:map id="generalDAOMap" map-class="java.util.HashMap">
<entry key="1">
<bean class="com.test.myproj.dao.impl.UserDAOImpl" />
</entry>
<entry key="2">
<bean class="com.test.myproj.dao.impl.AccountsDAOImpl" />
</entry>
<entry key="3">
<bean class="com.test.myproj.dao.impl.SettingsDAOImpl" />
</entry>
</util:map>
How is it possible to add entry to dictionary, defined in parent object, from the child object?
*UPDATED
I edit my config as follows:
<object id="ParentType" singleton="false" type="SomeType">
<property name="FieldNameMap">
<dictionary key-type="string" value-type="string" >
<entry key="Title" value="TitleName"/>
</dictionary>
</property>
</object>
<object id="ChildType" singleton="false" type="SomeType" parent="ParentType">
<property name="FieldNameMap">
<dictionary merge="true">
<!-- this entry should be added to, not replace the whole Dictionary -->
<entry key="Position" value="PositionName"/>
</dictionary>
</property>
</object>
but, unfortunately, it now throws cast exception:
Cannot convert property value of type
[System.Collections.Specialized.HybridDictionary] to required type
[System.Collections.Generic.IDictionary`2[[System.String,
],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089]]
I haven't tried this myself, but according to the docs, spring.net will use the Add method of the collection to add items, if the collection itself is exposed as a readonly property.
So it might be possible to use object definition inheritance to achieve the behavior you describe. Config will be something like:
<object id="ParentType" singleton="false" type="SomeType"
abstract="true">
<property name="FieldNameMap">
<dictionary>
<entry key="Title" value="TitleName"/>
</dictionary>
</property>
</object>
<object id="ChildType" singleton="false" type="SomeType"
parent="ParentType">
<property name="FieldNameMap">
<dictionary>
<!-- this entry should be added to, not replace the whole Dictionary -->
<entry key="Position" value="PositionName"/>
</dictionary>
</property>
</object>
This will only work if FieldNameMap is a readonly property.
I have a problem with only one controller that has a lazy loaded entity(there is a transaction initiated and commited, see stack trace)
17:56:46,084 DEBUG HibernateTransactionManager:438 - Found thread-bound Session [org.hibernate.impl.SessionImpl#6b204e88] for Hibernate transaction
17:56:46,085 DEBUG HibernateTransactionManager:471 - Participating in existing transaction
17:56:46,085 DEBUG HibernateTransactionManager:438 - Found thread-bound Session [org.hibernate.impl.SessionImpl#6b204e88] for Hibernate transaction
17:56:46,085 DEBUG HibernateTransactionManager:471 - Participating in existing transaction
Hibernate: select preference0_.id as id66_, preference0_.name as name66_, preference0_.value as value66_, preference0_.default_value as default4_66_, preference0_.updated_at as updated5_66_ from preferences preference0_ where preference0_.name='scheduleInterval'
17:56:46,086 DEBUG GooGooStatementCache:457 - cxnStmtMgr.statementSet( com.mysql.jdbc.JDBC4Connection#5ec60ee2 ).size(): 21
17:56:46,086 DEBUG GooGooStatementCache:196 - checkoutStatement: com.mchange.v2.c3p0.stmt.GlobalMaxOnlyStatementCache stats -- total size: 111; checked out: 1; num connections: 10; num keys: 111
17:56:46,087 DEBUG GooGooStatementCache:271 - checkinStatement(): com.mchange.v2.c3p0.stmt.GlobalMaxOnlyStatementCache stats -- total size: 111; checked out: 0; num connections: 10; num keys: 111
17:56:46,089 FATAL app:79 - service
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:167)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:215)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)
at com.model.User_$$_javassist_76.getName(User_$$_javassist_76.java)
at com.model.json.ScheduleItemWrapper.wrap(ScheduleItemWrapper.java:55)
at com.web.controllers.ajax.Model.wrap(Model.java:127)
at com.web.controllers.ajax.Model.toJSON(Model.java:165)
at com.web.controllers.ajax.Model.getContent(Model.java:51)
at com.web.controllers.ajax.BasicAction.execute(BasicAction.java:27)
at com.web.HibernateServlet.doService(HibernateServlet.java:113)
at com.web.HibernateServlet.service(HibernateServlet.java:66)
at sun.reflect.GeneratedMethodAccessor200.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:695)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
at com.levitech.web.controllers.schedule.ScheduleList$$EnhancerByCGLIB$$4a7ae33e.service(<generated>)
at com.levitech.web.RequestDispatcher.service(RequestDispatcher.java:63)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:662)
17:56:46,090 DEBUG HibernateTransactionManager:753 - Initiating transaction commit
17:56:46,090 DEBUG HibernateTransactionManager:653 - Committing Hibernate transaction on Session [org.hibernate.impl.SessionImpl#6b204e88]
17:56:46,091 DEBUG HibernateTransactionManager:735 - Closing Hibernate Session [org.hibernate.impl.SessionImpl#6b204e88] after transaction
17:56:46,091 DEBUG SessionFactoryUtils:800 - Closing Hibernate Session
The model (ScheduleItem and User) and their hibernate mappings
public class ScheduleItem {
private Integer id;
....
private User user;
}
public class User {
private Integer id;
...
private String name;
}
<class
name="ScheduleItem"
table="schedule_item"
>
<cache usage="read-write"/>
<id
name="id"
type="integer"
column="id"
>
<generator class="identity" />
</id>
<many-to-one name="user" column="user_id" lazy="proxy"></many-to-one>
</class>
<class
name="ScheduleItem"
table="schedule_item"
>
<cache usage="read-write"/>
<id
name="id"
type="integer"
column="id"
>
<generator class="identity" />
</id>
<property name="name" column="name" type="string" />
</class>
I found the culprit. OpenSessionViewFilter is using a different session or sessionfactory.
Here is my Spring config and web.xml (What am I doing wrong?):
Part of web.xml:
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>sessionFactory</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>/app/s/*</url-pattern>
</filter-mapping>
Part of Spring Config:
<bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${db.driver}"/>
<property name="jdbcUrl" value="${db.url}"/>
<property name="user" value="${db.user}"/>
<property name="password" value="${db.pass}"/>
<!-- Pool properties -->
<property name="minPoolSize" value="5" />
<property name="maxPoolSize" value="100" />
<property name="acquireIncrement" value="5" />
<property name="maxStatements" value="200" />
<property name="idleConnectionTestPeriod" value="120" />
<property name="maxIdleTime" value="1800" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource"></property>
<property name="mappingLocations" value="classpath*:com/model/hbm/**/*.hbm.xml" />
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.show_sql=true
hibernate.cache.region.factory_class=net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory
hibernate.cache.use_query_cache=true
hibernate.cache.use_second_level_cache=true
</value>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
From the log it looks like the session is still open when you get this exception. The other scenario in which you would get such an exception is if the row doesn't exist in the database.
User user = session.load(User.class, 1000); // Create a proxy
user.getName(); // This would throw lazy initialization exception if row doesn't exist
One more scenario that can lead to this is working with detached objects. If you fetched and stored the ScheduleItem as a HTTPSession variable. Retrieve it in another request and then try to access the proxy - it will result in the same exception. The session that was used to load the object has been closed. If that is the case you need to first reattach the object to the new session (merge, update or lock) before using it.
There are multiple solutions for your problem:
The easiest one is using Spring's OpenSessionInViewFilter. Just add this filter to your web.xml and configure it to filter your request.
This filter opens and closes Hibernate session in a filter, so during page rendering session will be open.
Some people believe that OpenSessionInViewFilter is against good design, and it mixes business logic into presentation tier. If you think so, fetch the referenced object in your query (for example by using join fetch in your HQLs).
You could try to:
Eagerly load the collection.
initialize the collection before leaving the collection by calling the respective getter method Hibernate.initialize(rtn.getUserRoles());
Thats basically two times the same approach depending on what works best in your setup. You are making sure to load the complete entity before leaving the session that way the entity can be detached from the old and then reatached to a new session without problems. What you are doing is initializing the proxy before leaving the session so that the collection is available for sure when you are out of a session context.
my property like this:
<property name="ReadingDateTime"
expression="//ReadingDateTime/text()"
scope="default"
type="STRING"
/>
Result is :1361855692325
which is in epoch format how can i convert in to noraml timezone to send db
my try is like this but its not converting it
<property name="ReadingDateTime"
expression=" current-dateTime()-xs:dateTime('1361855692325'))"
scope="default"
type="STRING"
/>
any body help me pls
<property name="epoch"
expression="get-property(SYSTEM_TIME")
scope="default"
type="STRING"/>
Result:-1361855692325 its superbly giving epoch value but i want change epoch value to timestamp
You can do this easily with the script mediator which let you use Javascript. Config looks like,
<property name="epoch" value="1361968436252"/>
<script language="js"><![CDATA[
var t = mc.getProperty("epoch");
var date = new Date(parseInt(t)).toString();
mc.setProperty("newdate", date);
]]></script>
<log level="custom">
<property name="TIMESTAMP" expression="get-property('newdate')"/>
</log>
I am trying to use BIRT 2.5.0 to generate a pdf file. BIRT is called from pHp (this is done thanks to JavaBridge and a Tomcat server).
And I am simply trying to create a checkbox, checked under certain conditions.
I looked a bit on the internet and found 2 different ways to do it.
The first way is to play with the Visibility if the field "idclassebillet" (on which I am making the test) has a value of 1. I did it this way :
<image id="9010">
<list-property name="visibility">
<structure>
<property name="format">all</property>
<expression name="valueExpr" type="javascript">row["classEq1"]</expression>
</structure>
</list-property>
<list-property name="boundDataColumns">
<structure>
<property name="name">classEq1</property>
<text-property name="displayName">classEq1</text-property>
<expression name="expression" type="javascript">dataSetRow["idclassebillet"] == 1</expression>
<property name="dataType">boolean</property>
</structure>
</list-property>
<property name="source">embed</property>
<property name="imageName">checkbox_unchecked.png</property>
</image>
But this doesn't work.
So the second solution that I found was to play with a simple URL. This solution is much more convenient, but doesn't work neither. This would looks like that.
<image id="9018">
<property name="source">url</property>
<list-property name="boundDataColumns">
<structure>
<property name="name">classEq1</property>
<text-property name="displayName">classEq1</text-property>
<expression name="expression" type="javascript">dataSetRow["idclassebillet"]</expression>
<property name="dataType">integer</property>
</structure>
</list-property>
<expression name="uri" type="javascript">
if(row["classEq1"] == 1)
"http://my.server.com/checkbox_checked.png"+row["classEq1"];
else
"http://my.server.com/checkbox_unchecked.png"+row["classEq1"];
</expression>
</image>
In both cases, I declare the field "dataSetRow["idfield"]" like that :
<data-sets>
<oda-data-set extensionID="org.eclipse.birt.report.data.oda.jdbc.JdbcSelectDataSet" name="infoBordereau" id="178">
<structure name="cachedMetaData">
<list-property name="resultSet">
...
<structure>
<property name="position">9</property>
<property name="name">idclassebillet</property>
<property name="dataType">integer</property>
</structure>
...
</structure>
<property name="dataSource">GestionBillet</property>
<list-property name="resultSet">
...
<structure>
<property name="position">8</property>
<property name="name">idclassebillet</property>
<property name="nativeName">idclassebillet</property>
<property name="dataType">integer</property>
</structure>
...
</list-property>
....
</oda-data-set>
</data-sets>
I checked that I can access to the content of "idclassebillet". If I simply print it this way, it works fine :
<data id="90060001">
<property name="whiteSpace">nowrap</property>
<property name="dataSet">infoBordereau</property>
<list-property name="boundDataColumns">
<structure>
<property name="name">classEq1</property>
<text-property name="displayName">classEq1</text-property>
<expression name="expression" type="javascript">dataSetRow["idclassebillet"]</expression>
<property name="dataType">integer</property>
</structure>
</list-property>
<property name="resultSetColumn">classEq1</property>
</data>
And whatever the solution I choose to get my "dynamic" images, I always get the same image, whatever the value of "dataSetRow["idclassebillet"]" is.
I have no problem accessing and printing the image. The problem is more to "test" the value of the "idclassebillet" field (ie. how can I access this field ?).
I hope that you understand what I am trying to do. If you have a better solution (and if possible an example of working code), don't hesitate to share ^^ :)
Many thanks,
Raphaƫl POITTEVIN
NB : At first, I wanted my images to be embedded in the document (this what I use in the first solution), but as this didn't worked, I used an images hosted on http://my.server.com ...
If your objective is to display an unchecked/checked checkbox, have you considered using the Wingdings font with characters 0xA8 and 0xFD or 0xFE?