MyEclipse: hibernate spring tutorial on latest myeclipse no data

alderion - Jan 09, 2008 - 06:21 PM
Post subject: hibernate spring tutorial on latest myeclipse no data
i'm not sure what exactly is up but the tutorial doesn't actually save any data in the db. if i comment out the delete line of the business logic and then check the database, there aren't any rows.

if i set the 'connection.autocommit' property to true in the hibernate.cfg.xml file, it does save data.

autocommit isn't ideal. how do you get it to save data without autocommit? how do you get your hands on a transaction so you can commit "manually"?

thanks,

-peter
support-rkalla - Jan 10, 2008 - 05:19 PM
Post subject: RE: hibernate spring tutorial on latest myeclipse no data
Peter,
The tutorial wasn't written with transactions originally to help keep it simple, so your information is cached in the session until Hibernate decides to flush it. Using autocommit just makes sure Hibernate flushes it every time anyway.

You can check the hibernate docs on using the transactions in hib to perform the commit yourself, I dug through some code on my end and didn't have the version of that example *with* transactions in it to provide to you... sorry about that.

I pinged another developer on the team to see if he had it laying around, I knew we messed with it a while ago to provide as an example but I just don't have access to it off the top of my head. Sorry about that.
alderion - Jan 10, 2008 - 05:40 PM
Post subject: RE: hibernate spring tutorial on latest myeclipse no data
thanks for the reply. i don't think what you are saying, '...so your information is cached in the session until Hibernate decides to flush it..', is true. the example is a simple main() class. why wouldn't hibernate flush its session when the program ended. what i am saying is that if you try to use the example 'as is' it will not save data to the db. the only reason the example appears to work is because you delete the object as the last step. if you comment out the delete statement, no data ever gets saved to the db. i think that is a poor example.

i would really appreciate it if you could track down the transactional code, it would be very helpful.

thanks,

-peter
support-rkalla - Jan 10, 2008 - 06:58 PM
Post subject: RE: hibernate spring tutorial on latest myeclipse no data
Peter,
I'll try and dig up the transactions code for you by tommorow.

As for the example, if instead of the delete, you put another bit of code right before it to query the DB to get the same entity back, does it return something? My guess is yes because it's still all cached in the session. Hibernate likes caching stuff unless you tell it not to. You can try flushing the session before the exit.
alderion - Jan 10, 2008 - 07:13 PM
Post subject: RE: hibernate spring tutorial on latest myeclipse no data
i look forward to your reply tomorrow. thanks!

yes, all the operations in the example succeed because you are using the cache; however, as soon as you try to extend the example by creating a new main class and trying to read the data from there, you won't get any data.

it seems to me any complete example should actually store things in the db. when i used previous version of myeclipse, i seem to recall that there was a hibernate utility generated from which you could request a transaction object, begin a transaction, do work and then commit the transaction. i don't see anything similar in the current generated code.

at the very least, i think you should explicitly state that nothing will get to the db using this example unless you set the connection.autocommit property to true in hibernate.cfg.xml. at least that was my experience with mysql.

again, thanks for the help. i look forward to hearing from you on the transactional example.

-peter
support-nipun - Jan 11, 2008 - 02:58 PM
Post subject: RE: hibernate spring tutorial on latest myeclipse no data
In the UserDAO.java, replace the save, delete and merge methods with the following piece of code. It should get things working:-

Code:

  public void save(User transientInstance) {
        log.debug("saving User instance");
        try {
           Session session = HibernateSessionFactory.getSession();
           Transaction tx = session.beginTransaction();
           tx.begin();
           session.save(transientInstance);
           
           tx.commit();
           
            log.debug("save successful");
        } catch (RuntimeException re) {
            log.error("save failed", re);
            throw re;
        }
    }
   
   public void delete(User persistentInstance) {
        log.debug("deleting User instance");
        try {
           Session session = HibernateSessionFactory.getSession();
           Transaction tx = session.beginTransaction();
           tx.begin();
       
            session.delete(persistentInstance);
           
            tx.commit();
            log.debug("delete successful");
        } catch (RuntimeException re) {
            log.error("delete failed", re);
            throw re;
        }
    }

    public User merge(User detachedInstance) {
        log.debug("merging User instance");
        try {
           Session session = HibernateSessionFactory.getSession();
           Transaction tx = session.beginTransaction();
           tx.begin();
       
            User result = (User) session
                    .merge(detachedInstance);
           
            tx.commit();
            log.debug("merge successful");
            return result;
        } catch (RuntimeException re) {
            log.error("merge failed", re);
            throw re;
        }
    }

alderion - Jan 11, 2008 - 03:06 PM
Post subject: RE: hibernate spring tutorial on latest myeclipse no data
thanks very much. seeing it now, it is very easy. i was trying to use the hibernate template, getting rid of it altogether was a bit of a mental block.
support-nipun - Jan 11, 2008 - 05:45 PM
Post subject: RE: hibernate spring tutorial on latest myeclipse no data
Your Welcome.
parasjain01 - Jan 17, 2008 - 06:47 PM
Post subject: Update the tutorial
Hi,
Thanks for the updated code. Can someone please update the tutorial for the same. So that next time if anyone tries the tutorial he should not be wondering why the data is not saved in the DB.

Paras
support-rkalla - Jan 17, 2008 - 07:23 PM
Post subject: RE: Update the tutorial
Paras,
It's actually on our TODO list to refresh the tutorial project and put it into the Examples On-Demand repository directly for others.
parasjain01 - Jan 18, 2008 - 04:24 PM
Post subject: RE: Update the tutorial
Thanks Riyad
parasjain01 - Jan 18, 2008 - 04:48 PM
Post subject: Spring's transaction management in Hibernate
By the time MyEclipse tutorial is updated if someone wants to do the transaction management using spring. This is what you have to do.

1)
a) Go to project properties- Java Build Path -> Libraries Tab -> Select Add Library button.
b) Select MyEclipse Library and press next.
c) Select Spring 1.2 AOP libraries
d) Press finish

2) UserDAO should implement some interface. Define a new Interface

Code:


package com.myeclipse.hibernatespring;

public interface IUser {

}


3) Change class signature of UserDAO to
Code:

public class UserDAO extends HibernateDaoSupport implements IUser{


4)applicationContext.xml has to be updated with new beans etc. Below is the entire applicationContext.xml code


Code:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
   <bean id="sessionFactory"
      class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
      <property name="configLocation"
         value="file:src/hibernate.cfg.xml">
      </property>
   </bean>
   <bean id="userDAOTarget" class="com.myeclipse.hibernatespring.UserDAO">
      <property name="sessionFactory">
         <ref bean="sessionFactory" />
      </property>
   </bean>
      <bean id="userDAOService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">   
      <property name="transactionManager" ref="transactionManager"/>
      <property name="transactionAttributes">
         <props>
            <prop key="add*">PROPAGATION_REQUIRED</prop>
            <prop key="update*">PROPAGATION_REQUIRED</prop>
            <prop key="delete*">PROPAGATION_REQUIRED</prop>
         </props>
      </property>
      <property name="target"><ref local="persistenceLayer"/></property>
   </bean>
   
   <bean id="persistenceLayer"
      class="com.myeclipse.hibernatespring.PersistenceLayer"
      abstract="false" singleton="true" lazy-init="default"
      autowire="default" dependency-check="default">
      <property name="userDAO">
         <ref bean="userDAOTarget" />
      </property>
   </bean>
   <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
      <property name="sessionFactory"><ref bean="sessionFactory"/></property>
   </bean>
</beans>


5) Go to BusinessLogic.java. Instead of writing
Code:

PersistenceLayer persistenceLayer = (PersistenceLayer) beanFactory
                .getBean("persistenceLayer");

you should write

Code:

PersistenceLayer persistenceLayer = (PersistenceLayer) beanFactory
                .getBean("userDAOService");


6) After making this changes the code should run fine and it should automatically persist the persistent objects.

Try removing the following line of code in BusinessLogic class and run the program.
Code:

persistenceLayer.deleteUser(user);

You can see entries in the databases now.

Cheers,
Paras
support-rkalla - Jan 18, 2008 - 05:45 PM
Post subject: RE: Spring
Paras,
That was very nice of you to post that followup for folks. Thanks for doing that.
dshopkins - Jan 23, 2008 - 08:33 PM
Post subject:
Thanx for the info guys on doing with Spring and directly via Hibernate.

I would like to just ask if it would be possible to get another example that say shows adding 2 new users without actually committing until the 2nd user was added. I can see how I could do this with hibernate, but I have no clue how could accomplish this using Spring's Session logic/config.
cnboy - Mar 21, 2008 - 06:39 AM
Post subject:
Paras,
thanks for doing that.
TonyHH - Apr 24, 2008 - 02:53 AM
Post subject:
Thanks for that! All worked fine but would like to see the tutorial updated as I had the same problem you guys had. But overall I think MyEclipse has pretty good support!
TonyHH - Apr 24, 2008 - 03:03 AM
Post subject:
Just a question why does the DAO have to implement an interface when the interface can do absolutely nothing?!!?
mcintosh_i - Apr 28, 2008 - 03:56 AM
Post subject:
Yep I can confirm that the interface is not needed, it still works without it.

Thanks Paras, great example, very helpful.

One question: the userDAOService bean is basically just a transaction wrapper, so is there any way that we can make this more generic, i.e. by not having to hard-wire the target to that particular "persistenceLayer" bean? (that bean is basically a userPersistenceLayer really). If we didn't have to hard-wire the reference to persistenceLayer in the transaction bean, we could use the transaction bean for ANY objects we wanted.

In other words, instead of having the line:
<property name="target"><ref local="persistenceLayer"/></property>
...
can we pass this reference in our client code? Otherwise we'll need one transaction bean for every object we might potentially want to save.

cheers,
Ian
mcintosh_i - Apr 28, 2008 - 04:37 AM
Post subject:
To answer my own question, the API doc for TransactionProxyFactoryBean gave me the answer. (I'm new to spring so didn't realise you could declare abstraction in the xml bean def file). Here's their example:

<bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
abstract="true">
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>

<bean id="myProxy" parent="baseTransactionProxy">
<property name="target" ref="myTarget"/>
</bean>

<bean id="yourProxy" parent="baseTransactionProxy">
<property name="target" ref="yourTarget"/>
</bean>
simpigill - May 02, 2008 - 11:26 PM
Post subject:
I used the information from this thread and build my application. Now DBA is complaining that I am eating up number of sessions (or processes) allowed.

Ques: Do I need to make changes to all my beans as suggested for UserDAO? ie. create XXXDAOservice for each one of them?
TonyHH - May 06, 2008 - 07:54 AM
Post subject:
I have the same problem as simpigill. Using this example I've created a tracker application to track web user etc. However, it seems I'm starting to get com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException too many connections. Anyone know how we should be handling connections?
TonyHH - May 07, 2008 - 01:25 AM
Post subject:
Funnily enough I looked around on google and found that simpigill had posted the question onto a few other sites and it looked like he figured out the solution himself. Given we're using the same design I thought I'd try his solution out with using C3P0 for JDBC connection management.

At first I couldn't get it working. But after awhile of searching on google I found that you must set minpoolsize to zero. I set my max connections on MySQL to 10 for testing purposes. So I'm using the settings below. But the most important thing is setting min_size to zero.

<code>
<property name="c3p0.max_size">6</property>
<property name="c3p0.min_size">0</property>
<property name="c3p0.timeout">30</property>
<property name="c3p0.max_statements">5</property>
<property name="c3p0.acquire_increment">1</property>
<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
</code>

simpigill also seem to stumbled on this solution as I can see his postings on another forum. The place I found the solution said that setting it to zero isn't a good thing and he didn't explain why. Anyone know of an explanation as to why this works and why it's not a good idea to set the min pool size to zero?
TonyHH - May 07, 2008 - 01:47 AM
Post subject:
Okay I figured out why minpoolsize makes this work.

Minpoolsize (or min_size) is the setting to tell c3p0 that's the minimum amount of connections c3p0 needs to manage in the pool. However, if this is set to zero then c3p0 doesn't maintain any connections in the pool thus the connections timeout and get released (so we don't run out of database connections). However, this is a bad way of implementing things as each time a new transaction is started we need to connect to the database which can be expensive especially in larger apps.

This makes me think that the sessions are not being handled properly? As in they aren't being closed off or that when new sessions and open connections are being opened but not reused. Anyone with opinions on this matter?
TonyHH - May 09, 2008 - 01:02 AM
Post subject:
Alright since nobody knows what's going wrong here I found the answer to my problem and probably simpigill's problem too. For me it was a stupid silly problem but probably very easily made. I was instantiating the Spring BeanFactory inside my doPost and doGet methods of my servlets which should be really be done in the init() method. Now of course everytime these methods are use we will get a new BeanFactory created thus a new connection (pool) to the database. The actual creation of the beans by the bean factory and the accessing of these beans causes Hibernate to create a connection. If you have a third party connection pooling manager like c3p0, it will create a connection pool accordingly to the parameters you've set for c3p0. So when you instantiate the BeanFactory and create a set of beans (and access them) you also create a connection pool. Having multiple BeanFactories gives you multiple connection pools so it's important that you don't instantiate multiple BeanFactories unless that's what you really want to do.

So if you are working on a webapp and exceeding max db connections best to check out your servlet code and no don't set min_size in c3p0 to zero because this defeats the purpose of connection pooling.

Hope that helps someone out.
All times are GMT - 6 Hours
Powered by PNphpBB2 © 2003-2004 The PNphpBB Group
Credits