Announcement Announcement Module
Collapse
No announcement yet.
Problem with Spring and Hibernate Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problem with Spring and Hibernate

    Hi

    iīm using Hibernate with Spring and i have the following problem: I have a very simple database with one table. The corresponding domain-object mapped to the database with annotations looks like this

    Code:
    @Entity
    @Table(name="S_Benutzer",
       uniqueConstraints = {@UniqueConstraint(columnNames={"b_nr"})})
    @org.hibernate.annotations.Table(appliesTo="S_Benutzer", indexes={@Index(name="b_nr", columnNames={"b_nr"})})
    @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
    @AccessType("property")
    public class BenutzerDOM implements Serializable, IBenutzerDOM {
       private static final long serialVersionUID = 1L;
       private Long id;
       private String name;
       private String vorname;
       private int art;
       private String kennung;
       private String passwort;
       private int sperre;
       private int standard;
          
       public BenutzerDOM() {}
    
       @Id 
            @GenericGenerator(name="pk_creator", strategy = "increment")
       @GeneratedValue(generator="pk_creator")
       @Column(name="b_nr", nullable=false, unique=true, length=4)
       public Long getId() {
          return id;
       }
    
       @Basic
       @Column(name="b_name", length=200)
       public String getName() {
          return name;
       }
    
       @Basic
       @Column(name="b_vname", length=200)
       public String getVorname() {
          return vorname;
       }
    
       @Basic
       @Column(name="b_kenn", length=200)
       public String getKennung() {
          return kennung;
       }
    
       @Basic
       @Column(name="b_passwort", length=200)
       public String getPasswort() {
          return passwort;
       }
    
       @Basic
       @Column(name="b_art", length=2)
       public int getArt() {
          return art;
       }
    
       @Basic
       @Column(name="b_sperre", length=200)
       public int getSperre() {
          return sperre;
       }
    
       @Basic
       @Column(name="b_standard", length=2)
       public int getStandard() {
          return standard;
       }
    
       public void setId(Long id) {
          this.id=id;
       }
       
       public void setName(String name) {
          this.name=name;
       }
    
       public void setVorname(String name) {
          this.vorname=name;
       }
    
       public void setKennung(String kennung) {
          this.kennung=kennung;
       }
    
       public void setPasswort(String passwort) {
          this.passwort=passwort;
       }
    
       public void setArt(int art) {
          this.art=art;
       }
       
       public void setSperre (int sperre) {
          this.sperre=sperre;
       }
    
       public void setStandard(int pass_change) {
          this.standard=pass_change;
       }
    
       public int compareTo(Object o) {
          return this.getId().compareTo(((BenutzerDOM)o).getId());
       }
    
       @Override
       public boolean equals(Object obj) {
          if (obj==this) return true;
          if((obj == null) || (obj.getClass() != this.getClass())) return false;
          
          BenutzerDOM benutzer=(BenutzerDOM)obj;
          boolean rueck=true;
          
          rueck=rueck && (name==null ? benutzer.name==null : name.equals(benutzer.name));
          rueck=rueck && (vorname==null ? benutzer.vorname==null : vorname.equals(benutzer.vorname));
          rueck=rueck && (art==benutzer.art);
          rueck=rueck && (kennung==null ? benutzer.kennung==null : kennung.equals(benutzer.kennung));
          rueck=rueck && (passwort==null ? benutzer.passwort==null : passwort.equals(benutzer.passwort));
          rueck=rueck && (sperre==benutzer.sperre);
          rueck=rueck && (standard==benutzer.standard);
          
          // Rückgabewert
          return rueck;
       }
    
       @Override
       public int hashCode() {
          int hash=7;
          
          hash=31*hash+(name!=null ? name.hashCode() : 0);
          hash=31*hash+(vorname!=null ? vorname.hashCode() : 0);
          hash=31*hash+art;
          hash=31*hash+(kennung!=null ? kennung.hashCode() : 0);
          hash=31*hash+(passwort!=null ? passwort.hashCode() : 0);
          hash=31*hash+sperre;
          hash=31*hash+standard;
          
          return hash;      
       }
    }
    In the table are 6 records with the id ranging from 1 to 6. Before i changed to Spring i was using pure Hibernate and everything worked fine. Now i try to load these records using the HibernateTemplate from Spring. Here i create a DetachedCriteria and pass it to the method findByCriteria(). That looks like this:

    Code:
    DetachedCriteria criteria=DetachedCriteria.forClass(BenutzerDOM.class);
    criteria.addOrder(Order.asc("id"));
    
    List result=hibernateTemplate.findByCriteria(criteria);
    The problem is, that my result has 7 records instead of 6 and the last record (which is not in the database) has the id 10 (every other field is null). There is no record with id 10 in the database.

    The same problem occurs when i use a hql-query and because it worked before i changed to Spring and i have not changed anything with the mapping i assume that it has something to do with HibernateTemplate from Spring.

    Whats wrong here? Can anybody help me?

    Thanks in advance for any help.

    Christoph
    Hibernate 3.2
    Spring 2.0
    MS SQL-Server 7.0

  • #2
    I cannot imagine this being a Spring issue, The findByCriteria method just passes everything thru to Hibernate, it doesn't modify anything. Try this with a HibernateCallback (this gives you access to the Hibernate Session) and use the plain Hibernate api.

    Code:
    List result = hibernateTemplate.executeFind(new HibernateCallback() {
        public Object doInHibernate(Session session) throws HibernateException, SQLException{
            Criteria criteria = session.createCriteria(BenutzerDOM.class);
            criteria.addOrder(Order.asc("id"));
            return criteria.list();
        }
    });
    Can it be that there is some uncommitted insert/update hanging around which you also retrieve? Did you first do some updates/inserts without commit/rollback?

    Comment


    • #3
      thanks for your reply. unfortunately even a callback doesnīt work.

      itīs really a mystery. what iīm doing here is executing a testcase. I changed my testssuite, so that itīs the ONLY testcase that i execute. So there is nothing else that i do before i execute the above query, no updates, no inserts ... i even restarted my computer to make sure that every cache is empty ;-) To be completely sure I deleted the line from the domain-object about the second-level-cache. So the only cache that i use is the first-level-cache ... i still get more records than there are in the database.

      I even get one more ... right now i get 8 records instead of 6 ... the records that are not in the database have the idīs 8 and 9. They are definitely not in the database. I tried to flush the session ... no changes. As far as i understand this they canīt be transient objects, because they have an Id!

      I have tried it with hql as well as with the criteria-API ... same result. I have no second-level-cache, no open transactions ... actually i have no idea :-(
      The only thing that i donīt know is, what Spring does with the session in its HibernateTemplate-Object. Is the session open all the time and with that the firstlevel-Cache? But on the other hand, when my query is the first, that i execute, where come the other records from?

      As a last try i post my Spring-configuration here. Maybe someone has an idea whats wrong here:

      Code:
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
      	"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
      
      <beans> 
      	<!-- Mapping-Ressource-Classes -->
      	<bean id="mappingClasses" class="org.springframework.beans.factory.config.ListFactoryBean">
      		<property name="sourceList">
      	      	<list>
      	      	   	<value>de.gebitms.geplan.datastructures.data.BenutzerDOM</value>
      	      	</list>
      		</property>
      	</bean>
      	<!-- Mapping-Ressource-Packages -->
      	<bean id="mappingPackages" class="org.springframework.beans.factory.config.ListFactoryBean">
      		<property name="sourceList">
      	      	<list>
      	      	   	<value>de.gebitms.geplan.datastructures.data</value>
      	      	</list>
      		</property>
      	</bean>
      
      	<!-- Hibernate-Propertys SQL-Server -->
      	<bean id="hibernatePropertiesSQL" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
      		<property name="properties">
      	  		<props>
      				<prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
      				<prop key="hibernate.connection.isolation">1</prop>
      				<prop key="hibernate.jdbc.batch_size">0</prop>
      				<prop key="hibernate.order_updates">true</prop>
      				<prop key="hibernate.show_sql">true</prop>
      				<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</prop>
      				<!-- Connection-Pooling -->
      				<prop key="hibernate.c3p0.initial_pool_size">10</prop>
      				<prop key="hibernate.c3p0.min_size">10</prop>
      				<prop key="hibernate.c3p0.max_size">150</prop>
      				<prop key="hibernate.c3p0.timeout">30</prop>
      				<prop key="hibernate.c3p0.max_statements">300</prop>
      				<prop key="hibernate.c3po.idle_test_period">3000</prop>
      				<prop key="hibernate.c3po.max_idle_time">30</prop>
      				<prop key="hibernate.c3po.acquire_increment">3</prop>
      				<prop key="hibernate.c3po.auto_commit_on_close">false</prop>
      				<prop key="hibernate.c3po.num_helper_threads">10</prop>
      				<prop key="hibernate.connection.use_compression">true</prop>
      				<prop key="hibernate.connection.cache_result_set_metadata">true</prop>
      				<prop key="hibernate.connection.dont_track_open_resources">true</prop>
      				<prop key="hibernate.connection.dynamic_calendars">true</prop>
      				<prop key="hibernate.connection.zero_date_time_behavior">convertToNull</prop>
      				<prop key="hibernate.connection.rollback_on_pooled_close">true</prop>
      				<!-- Second-Level-Caching -->
      				<prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</prop>
      				<!-- For the Migration from Hibernate 2 to Hibernate 3 -->
      				<prop key="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</prop>
      		  	</props>
      	 	</property>
      	</bean>
      	<!-- Hibernate-Propertys for Oracle -->
      	<bean id="hibernatePropertiesOracle" parent="hibernatePropertiesSQL">
      		<property name="properties">
      			<props merge="true">
      				<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
      			</props>
      		</property>
      	</bean>
      
      	<!-- JDBC-Datasources -->
      	<!-- Abstract beans -->
      	<bean id="abstractDataSourceSQL" abstract="true" class="org.apache.commons.dbcp.BasicDataSource">
      		<property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver"/>
      		<property name="url" value="jdbc:jtds:sqlserver://localhost:1433/geplan4;user=geplan4;password=gebit;TDS=7.0;"/>
      		<property name="username" value="geplan4"/>
      		<property name="password" value="gebit"/>
      	</bean>
      	<bean id="abstractDataSourceOracle" abstract="true" class="org.apache.commons.dbcp.BasicDataSource">
      		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
      		<property name="url" value="jdbc:oracle:thin:@pc-oracle:1521:gebit"/>
      		<property name="username" value="geplan4"/>
      		<property name="password" value="gebit"/>
      	</bean>
      	<!-- Beans -->
      	<bean id="dataSourceSQL" parent="abstractDataSourceSQL"/>
      	<bean id="dataSourceSQLTest" parent="abstractDataSourceSQL">
      		<property name="url" value="jdbc:jtds:sqlserver://localhost:1433/geplan4_test;user=geplan4_test;password=gebit;TDS=7.0;"/>
      		<property name="username" value="geplan4_test"/>
      	</bean>
      	<bean id="dataSourceOracle" parent="abstractDataSourceOracle"/>
      	<bean id="dataSourceOracleTest" parent="abstractDataSourceOracle">
      		<property name="username" value="geplan4_test"/>
      	</bean>
      
      	<!-- Hibernate-Session-Factories -->
      	<!-- Abstract Classes -->
      	<bean id="abstractSessionFactorySQL" abstract="true" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
      		<property name="dataSource" ref="dataSourceSQL"/>
      		<property name="hibernateProperties" ref="hibernatePropertiesSQL"/>
       	    <property name="annotatedPackages" ref="mappingPackages"/>
       	    <property name="annotatedClasses" ref="mappingClasses"/>
      		<property name="exposeTransactionAwareSessionFactory"><value>false</value></property>
      	</bean>
      	<bean id="abstractSessionFactoryOracle" abstract="true" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
      		<property name="dataSource" ref="dataSourceOracle"/>
      		<property name="hibernateProperties" ref="hibernatePropertiesOracle"/>
       	    <property name="annotatedPackages" ref="mappingPackages"/>
       	    <property name="annotatedClasses" ref="mappingClasses"/>
      		<property name="exposeTransactionAwareSessionFactory"><value>false</value></property>
      	</bean>
      	<!-- Beans -->
      	<bean id="sessionFactorySQL" parent="abstractSessionFactorySQL"/>
      	<bean id="sessionFactorySQLTest" parent="abstractSessionFactorySQL">
      		<property name="dataSource" ref="dataSourceSQLTest"/>
      	</bean>
      	<bean id="sessionFactoryOracle" parent="abstractSessionFactoryOracle"/>
      	<bean id="sessionFactoryOracleTest" parent="abstractSessionFactoryOracle">
      		<property name="dataSource" ref="dataSourceOracleTest"/>
      	</bean>
      
      	<!-- HibernateTemplates -->
      	<bean id="hibernateTemplateSQL" class="org.springframework.orm.hibernate3.HibernateTemplate">
      		<property name="sessionFactory" ref="sessionFactorySQL"/>
      	</bean>
      	<bean id="hibernateTemplateSQLTest" class="org.springframework.orm.hibernate3.HibernateTemplate">
      		<property name="sessionFactory" ref="sessionFactorySQLTest"/>
      	</bean>
      	<bean id="hibernateTemplateOracle" class="org.springframework.orm.hibernate3.HibernateTemplate">
      		<property name="sessionFactory" ref="sessionFactoryOracle"/>
      	</bean>
      	<bean id="hibernateTemplateOracleTest" class="org.springframework.orm.hibernate3.HibernateTemplate">
      		<property name="sessionFactory" ref="sessionFactoryOracleTest"/>
      	</bean>
      
      	<!-- Bean for MultipleHibernateTemplate-Factory -->
      	<bean id="multipleHibernateTemplate" class="de.gebitms.geplan.springwrapper.MultipleHibernateTemplate"
      		scope="prototype">
      		<constructor-arg>
      			<map>
      				<entry key="sql" value-ref="hibernateTemplateSQL"/>
      				<entry key="sqlTest" value-ref="hibernateTemplateSQLTest"/>
      				<entry key="oracle" value-ref="hibernateTemplateOracle"/>
      				<entry key="oracleTest" value-ref="hibernateTemplateOracleTest"/>
      			</map>
      		</constructor-arg>
      	</bean>
      
      	<!-- My beans -->
      	<bean id="benutzerDAO" class="de.gebitms.geplan.datastructures.dao.BenutzerDAO" scope="prototype">
      		<constructor-arg ref="multipleHibernateTemplate"/>
      	</bean>
      	<bean id="benutzerCompositeDAO" class="de.gebitms.geplan.datastructures.dao.BenutzerCompositeDAO" scope="prototype">
      		<constructor-arg ref="multipleHibernateTemplate"/>
      	</bean>
      	<bean id="systemDAO" class="de.gebitms.geplan.datastructures.dao.SystemDAO" scope="prototype">
      		<constructor-arg ref="multipleHibernateTemplate"/>
      	</bean>
      
      	<bean id="benutzer" class="de.gebitms.geplan.business.objects.Benutzer" scope="prototype">
      		<constructor-arg ref="benutzerDAO"/>
      	</bean>
      	<bean id="benutzerComposite" class="de.gebitms.geplan.business.objects.BenutzerComposite" scope="prototype">
      		<constructor-arg ref="benutzerCompositeDAO"/>
      	</bean>
      
      	<bean id="benutzerFactory" class="de.gebitms.geplan.business.factories.BenutzerFactory" scope="prototype"/>
      	<bean id="benutzerCompositeFactory" class="de.gebitms.geplan.business.factories.BenutzerCompositeFactory" scope="prototype"/>
      
      </beans>
      Thanks for any help
      Christoph

      Comment


      • #4
        HibernateTemplate will simply open the session if there is no session bound to the transaction, so I don't think that's the problem.

        I guess you are using "dataSourceSQLTest" for tests. I'd suggest to delete all the hibernate properties from the datasource definition except dialect.

        Comment


        • #5
          thanks for the reply, but sorry, that doesnīt solve the problem.

          but i think we can close this thread, i found the problem. It was my fault. It has nothing to do with spring or hibernate. Sorry for bothering you with this.

          Comment

          Working...
          X