Wednesday, September 30, 2015

Exception in thread "main" org.springframework.orm.hibernate3.HibernateSystemException:

Getting following exception while testing an Hibernate Application.

I have GeoLocationDataDao while testing a method getGeoLocationFromZipCode(zipcode) which returns the coordinates for a provided zip code.

I get following exception while running the test class.
Exception in thread "main" org.springframework.orm.hibernate3.HibernateSystemException: Unknown entity: com.testapp.service.geolocation.GeoLocationData; nested exception is org.hibernate.MappingException: Unknown entity: com.testapp.service.geolocation.GeoLocationData at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:690) at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412) at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:411) at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374) at org.springframework.orm.hibernate3.HibernateTemplate.get(HibernateTemplate.java:512) at org.springframework.orm.hibernate3.HibernateTemplate.get(HibernateTemplate.java:506) at com.testapp.service.geolocation.GeoLocationDataDao.getGeoLocationFromZipCode(GeoLocationDataDao.java:35) at org.mg.service.SpringHibernateTest.main(SpringHibernateTest.java:46) Caused by: org.hibernate.MappingException: Unknown entity: com.mg.service.geolocation.GeoLocationData at org.hibernate.impl.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:693) at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:92) at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:1090) at org.hibernate.impl.SessionImpl.get(SessionImpl.java:1005) at org.hibernate.impl.SessionImpl.get(SessionImpl.java:998) at org.springframework.orm.hibernate3.HibernateTemplate$1.doInHibernate(HibernateTemplate.java:519) at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406) ... 5 more


Fix :

Error was coming as the Entity object required by Dao could not be instantiated as it could not find its mapping.We have to list our classes in the session factory configuration. We can either have our entities auto-discovered using AnnotationSessionFactoryBean or we can use LocalSessionFactoryBean if have entity xml files.

Following is an example, if we are using EntityManager and annotations.

 <bean id="sessionFactory"
    class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="annotatedClasses">
        <list>
            <value>com.testapp.service.geolocation.GeoLocationData</value>
        </list>
    </property>
    ....
 </bean>


If we are not using annotation and want to specify the entities in a child xml we can use LocalSessionFactoryBean where we can specify a list of entity beans xmls as shown below.

<bean id="mySessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="mgDataSource"/>
    <property name="mappingResources">
        <list>
            <value>geolocationdata.hbm.xml</value>      
            <value>profile.hbm.xml</value>
        </list>
    </property>
    <property name="hibernateProperties">
        <value>hibernate.dialect=org.hibernate.dialect.HSQLDialect</value>
    </property>
</bean>

Here is a sample entity xml geolocationdata.hbm.xml configured above.

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.testapp.service.geolocation.GeoLocationData" table="GeoLocationData">
    <id name="zip_code" column="zip_code">
        <generator class="assigned"/>
    </id>
  <property name="lat"><column name="lat"/></property>
  <property name="lon"><column name="lon"/></property>
  <property name="city"><column name="city"/></property>
  <property name="state_prefix"><column name="state_prefix"/></property>
  <property name="county"><column name="county"/></property>
</class>
</hibernate-mapping>

Friday, September 25, 2015

Google Analytics Reporting

This document shows that how to create a custom google analytics report to analyze a web application and its users behavior.
Create a Sample Web Application using Eclipse
In the example below we have created a sample Dynamic Web Application “DynoWeb” using Eclipse with few test jsp pages.
Map localhost 8080 to a domain using fiddler:
Google Analytics requires us to provide a valid domain to generate a analytics report, hence we can’t configure localhost:8080.
As a workaround we can use Fiddler to map the localhost:8080 to point a logical domain name
1.       Download and Install Fiddler
2.       Navigate to Fiddler menu:- Tools > HOSTS.. (Click to select)
3.       Add a line like this in the dialog that appears :
localhost:8080 www.sanjay-local-dev.com



  1. Save the file & then check out your application url using following domain name instead of localhost:8080.
i.e. http://www.sanjay-local-dev.com/DynoWeb/index.jsp

Create a google analytics account for your web application
Now create a google analytics account with the domain: http://www.sanjay-local-dev.com
It requires you to provide some basic information like Property name, default URL, Industry category etc. Once successfully created it will provide you a Tracker ID (i.e. UA-68126XXX-1) which you will need to provide in your page within google analytics script.
Add the google analytics script to your page.
Now as we have created a google analytics account, we are ready to enable our jsps to start reporting data to google.
Add the following in your jsp page before the end of <head> tag.
<script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics_debug.js','ga');

  ga('create', '<<UA-XXXXXXXX-X>>', {
         'cookieDomain': 'none'
       });

  ga('send', 'pageview');

</script>

Note :
·         Replace the highlighted tracker id <<UA-XXXXXXXX-X>> with the one generated for you.
·         We have added 'cookieDomain': 'none' to enable the testing from localhost.

Test your google analytics report.
You can test your google analytics report to verify if your pages are sending the data to google correctly.
To see your report:
1.      Sign in to your Google Analytics account.
2.      Navigate to your view.
3.      Select the Reporting tab.
4.      Select Audience Overview from Left menu.
5.      You should be able to see your first google analytics report. If you see some activities in your report, it means its configured correctly.



Testing Real Time data:
You can also monitor activity as it happens on your site or app. Real-Time allows you to monitor activity as it happens on your site or app. The reports are updated continuously and each hit is reported seconds after it occurs. For example, you can see how many people are on your site right now, which pages or events they're interacting with, and which goal conversions have occurred.
To see Real-Time:
6.      Sign in to your Google Analytics account.
7.      Navigate to your view.
8.      Select the Reporting tab.
9.      Select Real-Time.




Creating Custom Dimensions and Metrics


Dimensions and metrics go hand in hand.  We can create a custom dimension and Metrics to generate the report for any application specific entity which is not covered by google, for example a healthcare blog can create a dimension for analyzing how many users of certain age group read about a specific disease. You can define dimension as an agegroup and then create different metrices around it (i.e. Parkinson, Lukemia, Arthiritis etc).

Report would look like this :

----------------------------------------------------------------------------------------------------------------
AgeGroup                             |     Parkinson                 | Lukemia               |  Arthiritis
----------------------------------------------------------------------------------------------------------------
30-40                                    |     1980                         | 789                        |  1200
----------------------------------------------------------------------------------------------------------------
40-50                                    |     3420                         | 900                        |  1200
----------------------------------------------------------------------------------------------------------------
50-60                                    |     1000                         | 2502                        |  5020
----------------------------------------------------------------------------------------------------------------
60-70                                    |     400                           | 990                        |  1723
----------------------------------------------------------------------------------------------------------------








 Creates a Custom Report

We can create a Custom report and add the custom Dimensions and metrics to this custom report.