Archive for hibernate

Spring Hibernate hbm2ddl.auto & Annotations

Spent Yesterday and today drawing up a schema for www.justcars.ie Ireland’s newest and hottest place to source your car.

To create this schema I wanted to get hibernate generate it via the POJOs I create. I am using annotations. So here is what i did:

Step One:

Create the POJO:

@Entity
public class Manufacteur {

@Id
private Integer manufacteurlId;

…..

}

Make sure you import javax.persistence.*; & not the more intuitive sounding hibernate one .

Step Two:

I am using a hibernate.cfg.xml for neatness:

<hibernate-configuration>
<session-factory name=”justCarsSessionFactory”>
<property name=”hibernate.connection.driver_class”>org.gjt.mm.mysql.Driver</property>
<property name=”hibernate.connection.password”>yourPassword</property>
<property name=”hibernate.connection.url”>jdbc:mysql://localhost:3306/YourScehma</property>
<property name=”hibernate.connection.username”>YourUsername</property>
<property name=”hibernate.default_schema”>jYourScehma</property>
<property name=”hibernate.dialect”>org.hibernate.dialect.MySQL5Dialect</property>
<property name=”show_sql”>true</property>
<property name=”hibernate.format_sql”>true</property>
<property name=”hibernate.hbm2ddl.auto”>create-drop</property>
<mapping package=”com.zeninvent.justcars.business”/>
<mapping class=”com.zeninvent.justcars.business.Manufacteur”/>
</session-factory>
</hibernate-configuration>

Change the pieces in bold as appropriate.

Step Three servlet:

Ensure your session factory bean if you are using annotations is using the AnnotationSession otherwise you will get an “Annotation Instance required ” exception.

Point the session factory to your hibernate.cfg.xml

<bean id=”sessionFactory” class=”org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean”>

<property name=”configLocation”><value>/WEB-INF/hibernate.cfg.xml</value></property>
<property name=”schemaUpdate”><value>true</value></property>
</bean>

Step Four:

Depoly & hey Presto hibernate is creating your schema! :)

Leave a Comment

The Development Envioroment

Just finished setting up the complete development on my laptop we’re back in business

Leave a Comment

Resloution

Ok the problem below has now be resloved.
First there was no cascadeType set on the orginal oneToOne mapping as per the hibernate book.
However, since I removed the @Proxy(lazy = false) a cascade option must be set for each nested object, otherwise the save of values in the nested object will fail(ie as it will never happen), which is what is explained in the transitive persistence section in Java Persitence in hibernate.
Using the javax.persitence annonations which do not have a save-update attibute I instead used PERSIST which then required the updating of the DAO code to utlise persist instead of update.
If this throughs up anymore bugs ill create a persist method seprate to the update so they can both be utlised in the project.
That is issue 48 in the issue tracker resloved & one of the probems from test 08 resloved.

Leave a Comment

CM02 Customer Documents & Sessions

CM02 customer document management is complete and ready for UAT.

The biggest problems faced during development of this requirements were management of sessions & the lazy loading of customer documents in the Client POJO.

Uploading on the flex side is developed from the file upload & php article from coding cowboys:

http://weblog.cahlan.com/2006/09/uploading-files-with-flex-and-php.html

I then got the apache commons file upload libraries to lend a hand on the backend.

The actionscript from the above link handles the getting of the file from the file system and posts it off to our usual service, tagged with add document.

The request is then parsed using the apache commons library into a FileItem where we can extract the content & file name etc.

The request comes with the client key, we fetch the appropriate client and its file set adding the new document and saving the client.

One of the biggest problems we had with this as i mentioned earlier was a  session problem. When logged in there is a session id associated with the authenticated user. However, the file upload implementation in flex begins a new session. There are numerous links and posts about these flex session id tomcat problems on the web. Our solution was to setup another request handler which can pass back the valid jsession id to flex itself. We then append this session id to the upload url which ensures the upload request is authenticated. The same issue occurs for file download.

The other issue i noted earlier was lazy loading and while my post on the hibernate forum was a start it wasn’t the sliver bullet to all my problems.

In the end I wrote a session interceptor in Spring which i mentioned as on wish list in a previous post – this however became essential to make the document lazy loading work.

I also had to the spilt the file POJO into two separate POJOs one for the file details and one for the file content itself. This is because as per the hibernate post all hibernate properties default to eager fetching and changing this through writing an ant task to change the byte code is not a very “done” thing. So as per the hibernate post i have setup an @lazyToOne relation between the File & FileContent POJOs. This now means when we do a fetch on a customer for populating the various customer tabs we are not fetching there documents as well, just a proxy list containing their file details. Before this was implemented even with small files there was a visible drop in performance of fetching customer details. This has now thankfully been resolved.

Also becuase of the spilt the adding of a file is a transaction and as such has been wrapped by a spring transaction interceptor (see my previous post on transactions for details).

Further I have implemenated a many to many relationship on the data model side to open the scope for one document to be linked to more than one customer. This however, will be beyond scope for this project iteration.

Now my task is to go back over all of the developed CMS components and do some ironing and polishing.

David is already writing JUnits for some of his code so I had better not let the side down. For GUI testing we are going to rely on manual use cases and checks as opposed to some of the automated GUI testing software out there – due simply to the ever tightening time constraints placed on the project.

Leave a Comment

Lazy loading issues Customers & Documents

Have a problem at the moment with loading a user (Climas POJO) as hibernate defaults to eager fetching of assocations and a user POJO has a Set of File POJOs associated with them. This File POJO contains the byte content of the file itself.
This leads to the issue of everytime the Climas POJO is accessed all the files assocated with this client are pulled from the database and loaded into the POJO. This is not good.
According to the hibernate book I can annote the blob with the @Lob annotation which should default to lazy. However, there appears to be much ambiguity over this as some interent forums disagree. I too disagree as I can still see the files being fetched in the log.
Now I could intercept and inject the byte[] through an ANT task to setup lazy loading through interception as opposed to hibernate default proxy pattern but it appears rather difficult and there must be a better solution.
So I posted on the hibernate forum for help & help has arrived.
Option two from my limited hibernate skillset looks like the most ideal solution and so tomorrow I will give it a go.
Link:

Leave a Comment

Searching, Contact Log, Annontations, Deprecation, HD16 etc

Since my last update where I discussed an implementation of free form search, I now have this requirement fufilled with a few caveats.

The current implementation is a free from search which is implemented for all but two of Dermot’s requirements (see previous post).

That is for example you can type a policy number or a client name etc into the one search box and without specifying further options on type it will pull back the pertinent client results.

It is a free from search for Dermot’s search specification only.

I have implemented this in the following fashion:

The retreiveClientsRequestHandler bean which handles requests for client search has a list of query fields

    <bean id=“retrieveAllCustomersRequestHandler” class=“com.zeninvent.dmib.web.handler.retrieveAllCustomersRequestHandler”>

            <property name=“climasListProxyDAO”><ref bean=“climasListProxyDAO”/></property>

            <property name=“queryFields”>

              <list>

                     <!– Any  value here must be specifed its table implmentation list in the climasListProxyDAO –>

                     <value>taxStatus</value>

                     <value>surname</value>

                     <value>phone1</value>

                     <value>address1</value>

                     <value>address2</value>

                     <value>occupationS</value>

                     <value>employerS</value>

                     <value>policyNum</value>

                     <value>maritalStatus</value>

              </list>

            </property>

    </bean>

Any field\column which is signed up for search must first be entered here.

Then the clientMasterListProxy bean has a list of columns for each table to be queried.

    <bean id=“climasListProxyDAO” class=“com.zeninvent.dmib.db.hibernate.HibernateClimasListProxyDAO”>

        <property name=“sessionFactory”><ref bean=“sessionFactory”/></property>

        <property name=“ftrenqFields”>

              <list>

                     <value>occupationS</value>

                     <value>employerS</value>

              </list>

        </property>

        <property name=“policyFields”>

              <list>

                     <value>policyNum</value>

              </list>

        </property>

        <property name=“climasFields”>

              <list>

                           <value>taxStatus</value>

                     <value>surname</value>

                     <value>phone1</value>

                     <value>address1</value>

                     <value>address2</value>

                     <value>maritalStatus</value>

              </list>

        </property>

While this list currently corresponds only to match the values in the original list in the handler it may be nice in time to have some redundancy here where the search list in the requestHandler may not utilise all of the options in the lists for performance reasons etc.

Then in the ClientMasterListProxyDAO it is simply a case of iterating through the lists and adding the appropriate  criteria to the right Criteria objects.

             

Example:     

// builds a list for the ftrenqFiels set in the servlet context these must match fields in the ftrenq table

                     if(ftrenqFields.contains(queryCriteria.get(i).getPropertyName())){

                           log.debug(“Non climas value being added to query:”+queryCriteria.get(i).getPropertyName());

                           critFtrenq.add((Criterion) queryCriteria.get(i).getQueryCriterion());

                           isAdded = true;

                     }

Once the criteria list is then built we return the results to the calling requestHandler which places the results back into the model.

While one can argue that there are could be performance issues against checking for example a telephone number against all the search list options in our live database with two and a half thousand customers there are no such issues.

If performance issues were to arise in the future or the days were suddenly to get longer I would consider implementing some regular expression pattern matching on the query field to narrow the list of possible search fields.

That took me until late Saturday afternoon to implement after which I spent the rest of the evening knocking off requirements :

CM09(Mapping) & CM11(For quotation – re-using David’s already developed quotation & front end purchase component).

Today I focused on CM06 the customer contact log.

While reading more about relationship mapping in hibernate there is an improved implementation for mapping, which up to now we have not been using, through annotations. Today that changed.

The beauty about using hibernate annotations is that they provide a further abstraction away from the database and also remove the need for the rather awakard mapping.hbm.xml file.

The other added advantage is if we do need to recfactor the table itself, for example adding a column, under the old regieme it would require updating the mapping.hbm.xml and then updating the POJO. However, now we just add the field to the POJO and hey presto!


The hibernate annotations are placed in the POJO

Example:

@Entity

@Table(name = “climas”)

@Proxy(lazy=false)

public class Climas implements java.io.Serializable{

       @Id

       @GeneratedValue(strategy = GenerationType.AUTO)

       @Column(name=“clientKey”)

       private int clientKey;

       @OneToOne

       @PrimaryKeyJoinColumn

       private Ftrenq ftrenq;

       @OneToMany(fetch=FetchType.EAGER)

       @JoinColumn(name=“clientKey”)

       private Set<ContactLog> contactLog ;

}

Most of the above annotations are self explanatory.

@Proxy is the fix for the hibernate org.hibernate.LazyInitializationException which translates to:

“Indicates access to unfetched data outside of a session context. For example, when an uninitialized proxy or collection is accessed after the session was closed” 

A way to fix this is to write a sessionIntercoter which has a similar theme to our transaction interceptor from a previous post.

I’ll do this if I get time near the end of the project.

However, we need to hydrate  the Climas pojo with a contactLog Set eagerly which is hibernates default to avoid another dreaded null pointer!

The @OneToMany @OneToOne do as they say on the tin.

Now because our mappings are being phased out I have had to re-factor the ftrenq table column names to a nicer format as before the xml mapping swept the column names under the carpet.

The ftrenq’s tables has 156 columns which required manual renaming. I could have used the @Column annotation to override the defaults in the Ftrenq POJO but I felt the column renaming was quicker.

This change in moving away from hibernate mappings to annotations also requires a change in our servlet sessionFactory where we now have an annotated classes list as well. The nice thing about it is we can use mappings and annotations side by side so there doesn’t have to be a complete re-factoring of every POJO and table but more a gentle migration as we code new tables and POJO’s with annotations and re-factoring old POJOs as required like the case today.

I also made the bold decision to truncate all DATETIME types in the migrated data to DATE to remove the absurdity of know the exact second of when a client signed for a policy. Don’t worry all the times were 00:00:00 anyway! J

The Client POJO has also now been officially deprecated and we hope to remove it completely in time.

David has the purchase of mortgage protection nicely tied up. And has been liaising with Dermot over a couple of options regarding the quotation service and purchase options.

anon…

HD16 Tomorrow agenda here:

 

http://gaffneykev.no-ip.info/ca400blog/Docs/Meeting%20HD16%20Agenda.doc

 

Screenshot of the contact log UI:

 

http://gaffneykev.no-ip.info/ca400blog/Docs/contactlOG.JPG

Leave a Comment

Search

Currently working on being able to switch between client partners on the application.
Example: I look at Mr Bloggs on the system and there is a link from Mr Bloggs to Mrs Bloggs.
This is a useul idea as it cuts down on having to re-enter client informatio such as address etc…
And I have utlised an existing link in the old data model which links a clientKey with another clientKey.. However, yet again the data looks to be inaccuratley entered as some clientKeys link to clients who are not partners.. some cleaning up will need to be done on the data by Ruth Dermot’s admin to make this a valueable link in the system for existing client partnerships

Leave a Comment