Pagination in MyBatis using PageHelper gives no improvement in time - java

I'm trying to use PageHelper plugin provided on this repo following the installation instructions provided here, but my problem is that I am unable to achieve better timings as compared to what I was getting without the plugin. I downloaded jars for pagehelper and jsqparser, added them to the build path of my project as well as added pagehelper in dependencies list in build.gradle of my project as:
dependencies {
compile fileTree(dir: 'lib', include: ['*.jar'])
compile 'com.github.pagehelper:pagehelper:3.2.1'
compile files("lib/jsqlparser-3.0.jar")
}
and added them to my build path as well. Then for the second step, I edited config org.mybatis.spring.SqlSessionFactoryBean as following:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="wrapperDataSource" />
<property name="configLocation" value="/WEB-INF/MapConfig.xml"/>
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<!-- config params as the following -->
<value>
helperDialect=mysql
reasonable=true
supportMethodsArguments=true
params=count=countSql
autoRuntimeDialect=true
</value>
</property>
</bean>
</array>
</property>
</bean>
where the first two properties were already present in this xml file. Now after making these changes, I build my project and run it using jetty by calling selectList in the following manner:
RowBounds rowBounds = new RowBounds(0, 100);
List<E> pendingRequests = getSqlSession().<E>selectList("fetchAllPendingRequests",inputData,rowBounds);
where E is the datatype of my results.
The problem is that the time I get for this function to fetch all the results using the PageHelper plugin is almost the same as that I get without using the plugin. Although when I go into the debugging mode, I see that in both the cases, the query from database is happening in different ways through different methods. While without using the plugin, the final query call is made using executor object in SimpleExecutor class, using the plugin the call is made from PageInterceptor class of the PageHelper repo. So the only conclusion I draw is it is unable to perform physical pagination despite making use of the plugin, but I could not understand the reasons for it.
Any help would be very much appreciated :)

Related

Hibernate Tools reverse engineering with Gradle

When I was using Eclipse as my IDE, I used to use Hibernate Tools to reverse engineer a database to obtain my entities, complete with annotations.
I recently moved to IntelliJ IDEA, which I consider to be an overral better IDE, but unfortunately there isn't a port of Hibernate Tools for it, so I cannot generate my entities the way I used to. I know that IntelliJ IDEA has its own reverse engineer tool (the one accessible via Persistence->Generate Persistence Mapping->By Database Schema), but I found it to be somewhat buggy, sometimes generating entities which are plain wrong.
I know that Hibernate Tools can be also used from Ant. Is there a way to use it from Gradle, too?
I managed to use Hibernate Tools from Gradle, largely thanks to this question.
It turns out (I didn't know it) that Gradle is indeed capable of calling Ant tasks, so it is possible to use the preexisting Hibernate Tools Ant task to reverse engineer a database.
To do so, it is necessary to have a hibernate.cfg.xml file, which contains the configuration needed to tell the Ant ask how to access our database. This is an example:
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="hibernate.connection.url">
jdbc:mysql://localhost:3306/mydb
</property>
<property name="hibernate.connection.username">
username
</property>
<property name="hibernate.connection.password">
password
</property>
</session-factory>
</hibernate-configuration>
(IntelliJ may complain about this file, telling that it cannot find the driver, but this is ok, as they will be provided by Gradle during the execution)
This config file will be used by the Ant task called from Gradle. I put it in a new db folder, created in the project root.
The following needs to be added to the build.gradle file:
configurations {
reverseMap
}
dependencies {
//...your other dependencies...
reverseMap 'org.hibernate:hibernate-core:4.0.1.Final'
reverseMap 'org.hibernate:hibernate-tools:4.0.1.Final'
reverseMap 'org.slf4j:slf4j-simple:1.7.5'
reverseMap 'mysql:mysql-connector-java:5.1.48'
}
project.ext {
hibernateDestDir = file("$projectDir/src/main/java")
}
task reverseMap {
outputs.dir hibernateDestDir
doLast {
hibernateDestDir.exists() || hibernateDestDir.mkdirs()
ant {
taskdef(
name: 'hibernatetool',
classname: 'org.hibernate.tool.ant.HibernateToolTask',
classpath: configurations.reverseMap.asPath
)
hibernatetool(destdir: hibernateDestDir) {
jdbcconfiguration(
configurationfile: "$projectDir/db/hibernate.cfg.xml",
packagename: "com.me.models"
)
hbm2java(
jdk5: true,
ejb3: true
)
}
}
}
}
This code creates a new configuration called reverseMap, which can be used to declare the dependencies needed for the reverseMap task (hibernate-core,hibernate-tools and log4j are needed, while the driver should be the one needed for your DBMS).
The reverseMap code calls the Ant task, basically following the official guide. The part of interest is hbm2java, which is the actual exporter. The rest of the code is basically glue code for the Ant task and configuration.
The Gradle task can be called either from the command line (./gradlew reverseMap) or from IntelliJ.

GWT + IntelliJ Idea - adding a server side library

I am trying to implement a GWT project in IntelliJ Idea 15. I have no problems (at least obvious) with GWT and its superdev mode - I can run an application and play with it. I can do RPC calls.
However, now I am trying to add JPA/Hibernate support to use a database. And here I have troubles. In the project I have a GWT facet (2.6.1), a JPA facet (with hibernate implementation), and a web facet (for web dd). Using Open Module Settings -> Libraries -> New Project Library I have added gwt-servlet.jar, and using maven (its not a maven project, just using the feature of Idea) libraries: c3p0:c3p0:0.9.1.2, org.hibernate:hibernate-entitymanager:5.0.3.Final, org.postgresql:postgresql:9.3-1101-jdbc41 ; that is the configuration.
Using this persistence unit properties (excerpt):
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
<property name="hibernate.c3p0.min_size" value="5" />
<property name="hibernate.c3p0.max_size" value="20" />
<property name="hibernate.c3p0.timeout" value="300" />
<property name="hibernate.c3p0.max_statements" value="50" />
<property name="hibernate.c3p0.idle_test_period" value="3000" />
In GWT RPC servlet I try to create EntityManager instance:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("ThreatPersistenceUnit");
EntityManager em = emf.createEntityManager();
Query query = em.createQuery("SELECT a FROM Asset a");
...
But when I try to run it in the IDEA using default GWT run configuration (Jetty), I get following exception:
javax.persistence.PersistenceException: Unable to build entity manager factory
caused by
Caused by: java.lang.ClassNotFoundException: Could not load requested class : org.postgresql.Driver
Also, before the exception I get following warning:
WARN: HHH000022: c3p0 properties were encountered, but the c3p0 provider class was not found on the classpath; these properties are going to be ignored.
So it seems the server cannot see both c3p0 and postgre jdbc driver.
I tried to google, the closest problem/solution I found is this SO answer. I have put the libraries both to the project and to the artifact. However, I am not sure what the replier meant by the Jetty lib. Where would I find Jetty installation, if I am using just the GWT's default server?
Plus, what seems quite weird to me is that before I had a similar problem (I dont remember if it was exactly the ClassNotFoundException) with GWT RPC that I was able to resolve by adding a gwt-servlet.jar to the libraries - why then adding these other libraries does not help? At least it seems that it does not have any problems with hibernate, since it provides the warnings and so on.
OK, even though it is a stupid mistake, maybe someday in the future someone else will make it, so for future reference this was the issue:
I had set the SDK and sources version of the project as 1.6; the hibernate and other libraries seem to been compiled in the same or lower version. However, the postgre driver was compiled using a newer version - when I have set the source version to 1.7 and set as an SDK the Java 8 SDK, the program crashed at some different exception (but that was due to my programming error - unrelated). I found this out only after I tried (in total desperation) to create a new object of the driver manually in the code (not to delegate the creation to persistence provider) - then I got the major minor version exception and I knew what is the problem.

How to get hibernate mapping files from another project using xml based config?

I'm working with spring and hibernate. Currently I have the context config file like this
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<!-- other properties -->
<property name="mappingDirectoryLocations" value="classpath:mappings/" />
</bean>
the *.hbm.xml mappings are in the same project.
Now I plan to pull some entities together with the mappings out, so they can be shared with other projects. The question is, how should I configure the sessionFactory bean to get *.hbm.xml files from the newly created project?
I tried mappingJarLocations but got error saying that the class path is not valid.
Instead of classpath: use classpath*:.
Check What is the difference between "classpath:" and "classpath:/" in Spring XML? for a extended answer on the differences between the 2.
AFASIK, Hibernate looks for mentioned hbm files in all the jars in classpath. You need to mention only the files.

How to externalize configuration in spring?

I am attempting to externalize the configurations using spring, but cannot get it to work properly..
Here is what I did so far:
create a property file inside the war file (src/test/resources/) for each environment.
For example: nonprod-key.properties & prod-key.properties with content like so:
key.name=NameOfPrivateKey.pfx
key.password=JustAPasswordForPrivateKey
Then in my jboss-cxf.xml, I would like to read the above value as follows:
<import resource="#{systemProperties['environment']}-key.properties" />
<http:conduit name="*.http-conduit">
<http:tlsClientParameters
secureSocketProtocol="SSL">
<sec:keyManagers keyPassword="${key.password}">
<sec:keyStore type="PKCS12" password="${key.password}" resource="${key.name}" />
</sec:keyManagers>
... ... ...
</http:tlsClientParameters>
</http:conduit>
And then in eclipse, run configurations --> Arguments --> VM Arguments
-Denvironment=nonprod
Unfortunately, the above does not work. :(
I am getting this error message:
class path resource [#{systemProperties['environment']}-key.properties] cannot be opened because it does not exist
I was attempting to use the suggestion from here :
http://forum.springsource.org/showthread.php?98988-Access-external-properties-file-from-SPRING-context-file&p=332278#post332278
But cannot seem to get it to work. What am I doing wrong?
Could someone please give an example/sample of how best to do accomplish this.
Thank you.
-SGB
I believe one needs to be on Spring 3.1.x to use profiles. We are not ... yet.
Anyways, the final solution that seems to work for us is to use :
<context:property-placeholder location="classpath:${environment}-key.properties"/>
instead of
<import resource="#{systemProperties['environment']}-key.properties" />
Everything else is same as listed in my original post (question).
Hope someone finds this useful.
SGB
You can use Property Place Holder. If you want a flexible configuration, eg. a default configuration stored in your war which can be overrided by an external configuration, you can use directly the PropertyPlaceholderConfigurer bean like :
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:ignoreResourceNotFound="true">
<property name="locations">
<array>
<bean class="org.springframework.core.io.ClassPathResource" c:path="${environment}-key.properties"/>
<bean class="org.springframework.core.io.FileSystemResource" c:path="relative/path"/>
</array>
</property>
</bean>
path attributes can used SPEL for example to reference property or system env variable.
Have a look to this article and this how to read System environment variable in Spring applicationContext

How to substitute a variable with real value in a xml file , which is in another dependency jar file by Maven

We have a project called web-app1 and has a dependency on another jar file called core-app.jar which is provided by another team as a shared library , yet there is a hibernate.cfg.xml in this core-app.jar (inside of the jar), with content as below.
<hibernate-configuration>
<session-factory>
<property name="dialect">${hibernate.dialect}</property>
<property name="query.substitutions"><![CDATA[false 'N', true 'Y']]></property>
<property name="show_sql">false</property>
<property name="format_sql">false</property>
<property name="use_sql_comments">false</property>
<property name="generate_statistics">true</property>
<property name="hibernate.connection.release_mode">after_transaction</property>
<!-- Search Configurations -->
<property name="hibernate.search.default.directory_provider">org.hibernate.search.store.FSDirectoryProvider</property>
<property name="hibernate.search.default.indexBase">${lucene.index.home}</property>
<property name="hibernate.search.default.batch.merge_factor">10</property>
<property name="hibernate.search.default.batch.max_buffered_docs">10</property>
</session-factory>
</hibernate-configuration>
As we see in the Search Configurations section, there is a variable ${lucene.index.home} that should be replaced by other projects on different OS platform,
so the question, does maven provide a way to filter a dependency jar file and filter the content? any plugins ? war:war , unzip ? dependencies ? I couldn't figure a fast way to do that. it looks to me , no matter what plugin would be adopted, the plugin needs to do 4 things basically.
1 unpack the jar in
process-resources phase.
2 substitute the ${var} with
value defined in profile.
3 pack it again back into a jar.
4 need to copy it back from the
packing/unpacking workspace back to
the maven process path ??
did anyone run into this similar requirement before.
thanks
I would assume that those values are meant to be set at runtime, likely as VM arguments. It doesn't make sense to provide a jar file that has to be modified to be able to be used.
If you really really REALLY have to do filtering at build time for configuration purposes, those configuration files should be filtered, NOT your dependencies. Then, you should either bundle said file into multiple artifacts (assuming of course you are targeting multiple environments), or be provided outside the built artifact as an externalized resource.

Categories

Resources