Announcement Announcement Module
Collapse
No announcement yet.
Is this correct? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Is this correct?

    Hi all.
    I'm using from little mount of time the spring framework and its suppor tfor hibernate.
    There some times that i need to use the HibernateCallback class for doing some operation in the current open Hibernate session; i usually use this kind of code:

    Code:
    	public Item loadAllDetails(Item titem, LogInfo tinfo) {
    		final Item item = titem;
    		final LogInfo info = tinfo;
    		return (Item) getHibernateTemplate().execute(new HibernateCallback() {
    			public Object doInHibernate(org.hibernate.Session session) {
    				Transaction tx = session.beginTransaction();
    				try{
    					
    					info.setMsg("Inizio metodo doInHibernate nel loadAllDetails della classe ItemManagerImpl");
    					logger.debug(info);
    					session.load(item, item.getKey());
    					Item appItem = (Item) item;
    					appItem.getItemAttachs().iterator();
    					appItem.getItemValues();
    					info.setMsg("Fine metodo doInHibernate nel loadAllDetails della classe ItemManagerImpl");
    					logger.debug(info);
    					tx.commit();
    					return appItem;		
    				}catch (Exception e) {
    
    					info.setMsg("Errore durante il caricamento di tutti i dettagli dell'item; messaggio di errore: " + e.getMessage() + ". Effettuo il rollback dell'operazione");
    					tx.rollback();
    					logger.fatal(info, e);
    					if (logger.isDebugEnabled()) {
    
    						info.setMsg("Sollevo una IllegalTransactionStateException...");
    						logger.debug(info);
    					}
    					throw new IllegalTransactionStateException(info.getMsg());
    				} finally {
    
    					if (session != null) {
    
    						if (logger.isDebugEnabled()) {
    
    							info.setMsg("Sto per effettuare il flush e la chiusura della sessione");
    							logger.debug(info);
    						}
    						session.flush();
    						session.close();
    					}
    				}
    			}
    		});
    
    	}
    As you can see i handle transaction and session close. Is this correct? I have read from the Spring API that this method should not care about the session and transaction handling...so i was wondering if i'm not wrong in doing this.
    Any suggestion is really appreciated.
    Thanx to all.
    Angelo

  • #2
    Indeed, you are not supposed to handle transactions yourself like this. Either use Spring's declarative transaction management or (if you want programmatic control) use TransactionTemplate.

    See the reference for more details.

    Regards,
    Andreas

    Comment


    • #3
      Also - there is no need to close the session. Moreover, if you do it, it will break transactions spanning mutiple hibernatetemplate calls.

      Comment


      • #4
        This recent blog might prove useful as well.
        http://blog.interface21.com/main/200...r-jpatemplate/
        Last edited by karldmoore; Aug 27th, 2007, 03:45 PM.

        Comment


        • #5
          Hi all.
          Thanx for all your replies.

          But since i'm newbie in Spring and above all in its Hibernate support i'm losing something... In the code i must use the doInHibernate(org.hibernate.Session session) method (and the HibernateCallBack class); now i'm sure that hibernateTemplate is fully transactional (right?) ; but if i want to be fully transactional in doInHibernate too how can i do? By reading the documentation this can be done by using AOP or programmatic way. If i don't want to use AOP....how can i use the programmatic way? What kind of code must i write in doInHibernate(org.hibernate.Session session) for handling correctly the transaction?
          Or simply must i write the code in this way:

          Code:
          public Item loadAllDetails(Item titem, LogInfo tinfo) {
          		final Item item = titem;
          		final LogInfo info = tinfo;
          		return (Item) getHibernateTemplate().execute(new HibernateCallback() {
          			public Object doInHibernate(org.hibernate.Session session) {
          				try{
          					
          					info.setMsg("Inizio metodo doInHibernate nel loadAllDetails della classe ItemManagerImpl");
          					logger.debug(info);
          					session.load(item, item.getKey());
          					Item appItem = (Item) item;
          					appItem.getItemAttachs().iterator();
          					appItem.getItemValues();
          					info.setMsg("Fine metodo doInHibernate nel loadAllDetails della classe ItemManagerImpl");
          					logger.debug(info);
          					return appItem;		
          				}catch (Exception e) {
          
          					info.setMsg("Errore durante il caricamento di tutti i dettagli dell'item; messaggio di errore: " + e.getMessage() + ". Effettuo il rollback dell'operazione");
          					logger.fatal(info, e);
          					if (logger.isDebugEnabled()) {
          
          						info.setMsg("Sollevo una IllegalTransactionStateException...");
          						logger.debug(info);
          					}
          					throw new IllegalTransactionStateException(info.getMsg());
          				}
          			}
          		});
          ?

          I know it's only a select in my code...but it's only a sample code

          Thanx to all,
          Angelo.

          Comment


          • #6
            The transaction is supposed outside not inside the hibernate callback.

            When you do it programmatically, you have to create a TransactionTemplate and invoke its execute() method providing a TransactionCallback. Inside that callback you have the invocation of HibernateTemplate.execute() with your HibernateCallback.

            Regards,
            Andreas

            Comment


            • #7
              Did you manage to solve your problem and get up and running?
              Last edited by karldmoore; Aug 27th, 2007, 03:45 PM.

              Comment


              • #8
                Code:
                 	Did you manage to solve your problem and get up and running?
                Hi...well i have to try i have been busy on other project so i was not able in seeing it...but i think that by using the TransactionTemplate or the PlatformTransactionManager i can solve it.

                Comment


                • #9
                  Originally posted by karldmoore View Post
                  Did you manage to solve your problem and get up and running?
                  Hi i'm trying to solve the problem.
                  I think that this way can be good for me:

                  Code:
                  			//Gestione programmatica della transazione
                  			DefaultTransactionDefinition def = new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRED);
                  			TransactionStatus status = getTransactionManager().getTransaction(def);
                  			try{
                  			getHibernateTemplate().execute(new HibernateCallback() {
                  				public Object doInHibernate(org.hibernate.Session session) {
                  					
                  					try {
                  						// TODO need to refresh item attach;
                  						item.removeAllAttach();
                  						// aggiungo le risorse selezionate dall'utente
                  						if (lista != null) {
                  							for (Iterator iter = lista.iterator(); iter.hasNext();) {
                  								ItemAttach element = (ItemAttach) iter.next();
                  								item.addAttach(element);
                  							}
                  						}
                  						session.saveOrUpdate(item);
                  						
                  						return null;
                  					} catch (Exception e) {
                  
                  						info.setMsg("Errore durante l'aggiornamento dell'item; messaggio di errore: " + e.getMessage() + ". Effettuo il rollback dell'operazione");
                  						
                  						logger.fatal(info, e);
                  						if (logger.isDebugEnabled()) {
                  
                  							info.setMsg("Sollevo una IllegalTransactionStateException...");
                  							logger.debug(info);
                  						}
                  						throw new IllegalTransactionStateException(info.getMsg());
                  					} 
                  				}
                  
                  			});
                  			tinfo.setMsg("Aggiornamento dell'item avvenuto con successo. Committo la transazione");
                  			logger.info(tinfo);
                  			getTransactionManager().commit(status);
                  			}catch (Exception e) {
                  				
                  				tinfo.setMsg("Errore durante l'aggiornamento dell'item. Messaggio di errore: "+ e.getMessage()+". Effettuo il rollback della transazione");
                  				logger.fatal(tinfo, e);
                  				getTransactionManager().rollback(status);
                  				throw new SCFCMSRepositoryException(e.getMessage(), e); 
                  			}
                  I need to use the Hibernate session because in my hibernate configuration i have the "lazy" attribute setted to true so i can't obtain the full related objects after that hibernate session is closed.
                  According to you is this a good approach?
                  Sorry for this questions but i want just to be sure about the rigth way of using the Spring Hibernate Support.
                  Thanks,
                  Angelo.

                  Comment


                  • #10
                    Originally posted by craig1980 View Post
                    I need to use the Hibernate session because in my hibernate configuration i have the "lazy" attribute setted to true so i can't obtain the full related objects after that hibernate session is closed.
                    According to you is this a good approach?
                    Any chance you can explain more about what you don't understand with this stuff. I don't really follow what you struggling with. As for your example, I think that declarative transactions would be a better idea.
                    Last edited by karldmoore; Aug 27th, 2007, 03:44 PM.

                    Comment


                    • #11
                      Originally posted by karldmoore View Post
                      Any chance you can explain more about what you don't understand with this stuff. I don't really follow what you struggling with. As for your example, I think that declarative transactions would be a better idea.
                      Well....let's image i have this kind of hibernate configuration:

                      molti.hbm.xml
                      Code:
                      <?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="Apparecchiatura" table="APPARECCHIO">
                      	<id name="id" type="int" column="APPA_ID" unsaved-value="0">
                      		<generator class="native"/>
                      	</id>
                      	<many-to-one name="organo" column="ORGANO_ID" not-null="true" class="it.eng.Organo" cascade="delete"/>
                      	<property name="descrizione" column="DESCRIZIONE" type="string"/>
                      </class>
                      </hibernate-mapping>

                      Apparecchiatura.java

                      Code:
                      import java.io.Serializable;
                      
                      public class Apparecchiatura extends GenericEntity{
                      
                      	/**
                      	 * 
                      	 */
                      	private static final long serialVersionUID = -6700481256808933166L;
                      	
                      	private int id;
                      	private String descrizione;
                      	private Organo organo;
                      	public String getDescrizione() {
                      		return descrizione;
                      	}
                      	public void setDescrizione(String descrizione) {
                      		this.descrizione = descrizione;
                      	}
                      	public int getId() {
                      		return id;
                      	}
                      	public void setId(int id) {
                      		this.id = id;
                      	}
                      	public Organo getUnoAmolti() {
                      		return organo;
                      	}
                      	public void setUnoAmolti(Organo organo) {
                      		this.organo = organo;
                      	}
                      	public Serializable getKey() {
                      		
                      		return new Integer(getId());
                      	}
                      	public Organo getOrgano() {
                      		return organo;
                      	}
                      	public void setOrgano(Organo organo) {
                      		this.organo = organo;
                      	}
                      }

                      uno.hbm.xml

                      Code:
                      <?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="Organo" table="ORGANO">
                      	<id name="id" type="int" column="ID" unsaved-value="0">
                      		<generator class="native"/>
                      	</id>
                      	<property name="descrizione" column="DESCRIZIONE" type="string"/>
                          <set name="apps" cascade="all" lazy="true">
                              <key column="APPA_ID"/>
                              <one-to-many class="it.eng.Apparecchiatura"/>
                          </set> 
                      </class>
                      </hibernate-mapping>
                      Organo.java

                      Code:
                      import java.io.Serializable;
                      import java.util.HashSet;
                      import java.util.Set;
                      
                      public class Organo extends GenericEntity {
                      
                      	/**
                      	 * 
                      	 */
                      	private static final long serialVersionUID = -1692194167515470470L;
                      	
                      	private int id;
                      	private String descrizione;
                      	private Set apps = new HashSet();
                      	public String getDescrizione() {
                      		return descrizione;
                      	}
                      	public void setDescrizione(String descrizione) {
                      		this.descrizione = descrizione;
                      	}
                      	public int getId() {
                      		return id;
                      	}
                      	public void setId(int id) {
                      		this.id = id;
                      	}
                      	public Serializable getKey() {
                      			
                      			return new Integer(getId());
                      		}
                      	public Set getApps() {
                      		return apps;
                      	}
                      	public void setApps(Set apps) {
                      		this.apps = apps;
                      	}
                      	public void addApparecchiatura(Apparecchiatura ap){
                      		ap.setOrgano(this);
                      		apps.add(ap);
                      	}
                      }

                      Now if i try to search an Organo i can use getHibernateTemplate for doing it; if i need to have all the Apparecchiatura associated to the Organo i have to use the doInHibernate method so i can load Organo and all the Apparecchiatura associated; and untill here it's still all OK.
                      Now let's image i have to update some Apparecchiatura associated to Organo; i need to do this always in doinHibernate method...but let's image i have two or more transaction i have to do in the current open Hibernate session and let's image i need to be sure about the full commit transaction....how can i do?
                      Can i use the way i showed before or must i use any other way?

                      Comment


                      • #12
                        Originally posted by craig1980 View Post
                        Now if i try to search an Organo i can use getHibernateTemplate for doing it; if i need to have all the Apparecchiatura associated to the Organo i have to use the doInHibernate method so i can load Organo and all the Apparecchiatura associated; and untill here it's still all OK.
                        You can do this via a join.
                        http://www.hibernate.org/hib_docs/v3...queryhql-joins

                        Originally posted by craig1980 View Post
                        Now let's image i have to update some Apparecchiatura associated to Organo; i need to do this always in doinHibernate method...but let's image i have two or more transaction i have to do in the current open Hibernate session and let's image i need to be sure about the full commit transaction....how can i do? Can i use the way i showed before or must i use any other way?
                        I'm sorry I still don't understand what the problem is.
                        Last edited by karldmoore; Aug 27th, 2007, 03:44 PM.

                        Comment


                        • #13
                          Hi....so sorry for disturbing you...i try to be more clear.
                          Always in the scenario i described before let's imagine i have a third table.
                          Imagine i have to do some operation on the tables described before (i mean some update), then some other control and then, after these controls, i must do an insert in the third table; all this in one transaction and i must be sure that if all the DB operations end well i must commit the transaction otherwise i must rollback the full transaction....this is my scenario.
                          Now by having the mapping file with lazy=true i must recover all details of Organo (that is Organo with all the Apparecchaitura related) in the current open session...so i use the doInHibernate method....more i have to handle the full transaction. I hope i have been more clear
                          Try to pardon me
                          Thanx,
                          Angelo.

                          Comment


                          • #14
                            I'm still not clear on what you are trying to do. If you want all the operations to be contained within one transaction, then simply ensure you perform them within the scope of that one transaction.
                            http://www.springframework.org/docs/...ansaction.html
                            Last edited by karldmoore; Aug 27th, 2007, 03:44 PM.

                            Comment


                            • #15
                              Hi.

                              Thanx for your patience.
                              I have been able in studing more the Spring hibernate support.
                              I have understood this this:

                              the doInHibernate method is not transactional...i mean if there is a transaction it supports the transaction otherwise it doesn't. What is transactional is the doIntransaction method of the transactionTemplate.
                              Indeed i have done this test:
                              i have the three tables described in the previous reply: i have to do some quries and some check on the Organo and Apparecchiatura table, then, after all the controls, i have to add in a third table; i have done this operation:
                              • Load organo
                              • Load all the organo's apparecchiatura
                              • Do some update on apparecchiatura
                              • Do an insert in the third table

                              I caused an error in the insert in the third table (i wanted this error).What i expected was that since there is this error also the update on apparecchiatura was rollback.
                              I tried this in the doInHibernate method and as there was the error the update on apparecchiatura was not rollbacked.
                              I tried the same code in the doInTransaction method and, as i wanted, the update was rollbacked.

                              I'm sorry for distubing all you...and sorry for my bad english....
                              What i wanted to be sure was about the full transaction. Thanks again.
                              Angelo

                              Comment

                              Working...
                              X