Page 1 of 2 12 LastLast
Results 1 to 10 of 17

Thread: null values in records which need to be deleted

  1. #1

    Default null values in records which need to be deleted

    Hi all,

    When I do the below what is does is that it creates a new row in the PHONE_NUMBER table with the new values of the new phone number object which is right but instead of deleting the old values of phone number (because I have used instance.getPhoneNumbers().clear()) it nulllifies the values of the old record.

    This is leading to creation of large number of null rows in the Phone_Number table which should have ideally been deleted. Can anyone explain me why this is happening

    Hibernate version: Hibernate 3.0.5

    Mapping documents:
    <class name="MyClass"
    table="MY_CLASS">
    <id name="id" column="ID" type="long" unsaved-value="0">
    <generator class="native"/>
    </id>
    <property name="requestDate" type="timestamp" column="REQUEST_DATE"/>
    <property name="requester" column="REQUESTER" type="java.lang.String"/>
    <set name="phoneNumbers" cascade="all" access="field" lazy="false">
    <key column="MYCLASS_ID" not-null="false"/>
    <one-to-many class="PhoneNumber"/>
    </set>
    </class>

    <class name="PhoneNumber">
    table="PHONE_NUMBER">
    <id name="id" column="ID" type="long" unsaved-value="0">
    <generator class="native">
    </generator>
    </id>
    <property name="areaCode" type="java.lang.String" column="AREA_CODE"/>
    <property name="number" type="java.lang.String" column="NUMBER"/>
    <property name="extension" type="java.lang.String" column="EXTENSION"/>
    <property name="type" type="int" column="PHONE_TYPE_ID"/>
    </class>


    Code between sessionFactory.openSession() and session.close():

    PhoneNumber phoneNumber = new PhoneNumber("610", "964 5235", "");

    MyClass instance = (MyClass) s.get(MyClass.class, id);
    instance.getPhoneNumbers().clear();//since phone number array is a Set
    instance.setPhoneNumbers(new HashSet(phoneNumber));
    HibernateUtil.currentSession().saveOrUpdate(instan ce);




    Name and version of the database you are using:SQL Server 2000

    In case anything is not clear please let me know.

    Thanks for help,
    Ashish Abrol
    Last edited by ashish261080; Sep 26th, 2006 at 01:25 AM.

  2. #2
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,624

    Default

    Code:
    MyClass instance = (MyClass) s.get(MyClass.class, id);
    instance.getPhoneNumbers().clear();//since phone number array is a Set
    instance.setPhoneNumbers(new HashSet(phoneNumber));
    HibernateUtil.currentSession().saveOrUpdate(instan ce);
    First your clear your set and next you replace the set with a new HashSet!. Which results in the old cleared set (still being managed by Hiberante) hanging around in your system without any reference to MyClass, hence the cascade="all" cannot be done. When you replace the set and do a saveorupdate the changes in this set are also flushed to the database. The new set is then saved for the current instance of MyClass. The easiest way of fixing this is to add the new phonenumber to the set.

    Code:
    MyClass instance = (MyClass) s.get(MyClass.class, id);
    instance.getPhoneNumbers().clear();//since phone number array is a Set
    instance.getPhoneNumbers().add(phoneNumber));
    HibernateUtil.currentSession().saveOrUpdate(instan ce);
    If this is good code/behavior is debatable but it works .
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  3. #3

    Default

    Thanks for the prompt reply. But even after making the belwo changes the same is happening.

    MyClass instance = (MyClass) s.get(MyClass.class, id);
    instance.getPhoneNumbers().clear();//since phone number array is a Set
    instance.getPhoneNumbers().add(phoneNumber));
    HibernateUtil.currentSession().saveOrUpdate(instan ce);


    I have spent hours figuring out the problem but in vain.

  4. #4
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,624

    Default

    Something I noticed in your mapping file

    Code:
    <set name="phoneNumbers" cascade="all" access="field" lazy="false">
        <key column="MYCLASS_ID" not-null="false"/>
        <one-to-many class="com.magnus.ecloser.model.contact.PhoneNumber"/>
     </set>
    Your key is not-null="false" I figure it should be true, it is a key so it should be filled. Also your cascade has all I would try switching it to all-delete-orphan.

    So your mapping will look like

    Code:
    <set name="phoneNumbers" cascade="all-delete-orphan" access="field" lazy="false">
        <key column="MYCLASS_ID" not-null="true"/>
        <one-to-many class="com.magnus.ecloser.model.contact.PhoneNumber"/>
     </set>
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  5. #5

    Default

    Thanks, but key is set to not-null="false" because like MyClass other classes also have set of phone numbers (like class Person whose mapping is shown below) and each class has its own foriegn key attribute in PHONE_NUMBER table. So the value of MyClass instance's phone number can be null in case a Person object is being saved.

    <class name="Person"
    table="PERSON">
    <id name="id" column="ID" type="long" unsaved-value="0">
    <generator class="native"/>
    </id>
    <set name="phoneNumbers" cascade="all" access="field" lazy="false">
    <key column="PERSON_ID" not-null="false"/>
    <one-to-many class="PhoneNumber"/>
    </set>
    </class>


    As far as cascade "all-delete-orphan" is concerned it too doesn't help. I think the problem lies somewhere else but I am not able to figure out where. Also though the code runs absolutely fine and gives no problem yet the issue is there with almost half of the tables that are there in our project.
    Last edited by ashish261080; Sep 26th, 2006 at 01:26 AM.

  6. #6
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,624

    Default

    If you have a PHONE_NUMBER record with a null foreign_key to which PERSON does it belong to?! I still believe the foreign key shouldn't be null. If you configured everything right, first the person (without PHONE_NUMBERS) is saved and afterwards the phonenumbers. But that is just IMHO ofcourse .

    I guess that the fact of having the not-null="false" is also part of your problem. If you remove a phonenumber from this person, it is perfectly legal to have a null foreign key and hence the record is updated with a null value instead of being removed.

    But maybe some of the hibernate/spring guru's (Colin maybe?) can give a more clear answer.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  7. #7
    Join Date
    Oct 2006
    Posts
    6

    Default null values in records which need to be deleted

    Hi,

    Did you find a solution even i am facing the same issue where records are updated to null values instead of getting deleted.

    Please mail me the solution mvjmanju@yahoo.com

    Regards,
    Manjunath

  8. #8
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    Is it possible to see the code that causes the problem, the HBM files and also the SQL logging that comes out? If you wrap this all in [code] [ /code] tags, it's most appreciated.

  9. #9
    Join Date
    Oct 2006
    Posts
    6

    Default

    Mapping file
    Code:
    <!DOCTYPE hibernate-mapping
    PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    
    <hibernate-mapping>
        <class name="com.motive.criteriatemplate.domain.CriteriaTemplate" table="CriteriaTemplate">
    
            <!-- HdmPersistentObject id property -->
            <id name="id" type="int" column="id">
              <generator class="native">
                <param name="sequence">HdmCriteriaService_Seq</param>
              </generator>
            </id>
    
            <!-- HdmPersistentObject version property used for
                 Hibernate managed versioning for optimistic locking -->
    		<version name="version" column="version" />
    
            <!-- HdmPersistentObject additional properties -->
            <property name="guid" column="guid" type="string" update="false"
                      length="32"/>
            <property name="inserted" column="inserted" type="date"
                      update="false" insert="false"/>
    	    <property name="updated" column="updated" type="date"
    	    		  update="false" insert="false"  not-null="false"/>
    
            <!-- CriteriaTemplate properties -->
    		<property name="name" type="string" not-null="true">
            	<column name="name" length="255" not-null="true" unique-key="CRITERIA_UNIQUE_KEY"/> 
    		</property>
    		<property name="description" column="description" type="string" not-null="false" length="255" />
            <property name="criteriaExpression" column="criteriaExpression" type="string" not-null="true" length="2048" />
            <property name="dynamicOptions" column="dynamicOptions" type="boolean" not-null="true" />
            <property name="evaluatorBeanName" column="evaluatorBeanName" type="string" not-null="true" length="255" />
    		<property name="inUse" column="inUse" type="boolean" not-null="true" />
    		<property name="deleted" column="deleted" type="boolean" not-null="true" />
            <property name="nullIndicator">
            	<column name="nullIndicator" length="64" unique-key="CRITERIA_UNIQUE_KEY"/>        
            </property>
    
            <component name="templateParameterMetaData" class="com.motive.criteriatemplate.domain.FunctionMetaData">
                <property name="nameKey" column="funcNameKey"/>
     			<array name="parameterSet" cascade="all">
                    <key column="GROUP_ID"/>
                    <index column="indexVal"/>
                    <one-to-many class="com.motive.criteriatemplate.domain.ParameterGroupMetaData"/>                
                </array>
             </component>
         
        </class>
        
        <class name="com.motive.criteriatemplate.domain.ParameterGroupMetaData" table="CRITTEMPLATE_GROUPS">
            <id name="id" column="id" type="int"> 
                <generator class="native">
    				<param name="sequence">HdmCritTmpltGrp_seq</param>
                 </generator>
            </id>        
            <property name="nameKey" column="nameKey"/>
            <property name="optional" column="optional"/>
            <array name="parameterMeta" cascade="all">
                <key column="PARAM_ID"/>
                <index column="indexVal"/>
                <one-to-many class="com.motive.criteriatemplate.domain.ParameterMetaData"/>                
             </array>
        </class>
    
        <class name="com.motive.criteriatemplate.domain.ParameterMetaData" table="CRITTEMPLATE_PARAMS"
            discriminator-value="ParameterMetaData">
            <id name="id" column="id" type="int"> 
                <generator class="native">
    				<param name="sequence">hdm_srchtmpltgrp_seq</param>
                 </generator>
            </id>
            <discriminator
                column="subclass"
                type="string"
                length="64"
            />        
            <property name="name" column="name"/>
            <property name="nameKey" column="nameKey"/>
            <property name="preString" column="preString"/>
            <property name="postString" column="postString"/>
            <property name="required" column="required"/>
            <property name="defaultValue" column="defaultValue"/>
            <property name="hint" column="hint"/>
            <property name="type" column="type"/>
            <property name="list" column="list"/>
            <subclass
                name="com.motive.criteriatemplate.domain.ParameterMetaDataChoiceList"
                discriminator-value="ParameterMetaDataChoiceList">
    	        <array name="options" table="CRITTEMPLATE_OPTIONS" cascade="all">
    	            <key column="OPTIONS_ID"/>
    	            <index column="indexVal"/>	
    	            <element column="VALUE" type="string"/>
    	        </array>
    	        <property name="dynOptionsExpression" column="dynOptionsExpression"/>
            </subclass>
        </class>
    Java Code
    Code:
    //Inserting the criteria template
    hibernateTemplate.save(criteriaTemplate)
    
    //updating template here i am creating new criteria template object  
    // and setting the id of the template object of the existing one
    
    hibernateTemplate.saveOrUpdate(updatedCriteriaTemplate);
    log

    Code:
    2007-06-06 17:04:41,743 [main] DEBUG AbstractCollectionPersister - Deleting collection: [com.motive.criteriatemplate.domain.CriteriaTemplate.templateParameterMetaData.parameterSet#86]
    2007-06-06 17:04:41,743 [main] DEBUG AbstractBatcher - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
    2007-06-06 17:04:41,743 [main] DEBUG SQL - update CRITTEMPLATE_GROUPS set GROUP_ID=null, indexVal=null where GROUP_ID=?2007-06-06 17:04:41,743 [main] TRACE AbstractBatcher - preparing statement
    2007-06-06 17:04:41,743 [main] TRACE IntegerType - binding '86' to parameter: 1
    2007-06-06 17:04:41,743 [main] DEBUG AbstractCollectionPersister - done deleting collection
    2007-06-06 17:04:41,743 [main] DEBUG AbstractBatcher - Executing batch size: 1
    2007-06-06 17:04:41,759 [main] DEBUG AbstractBatcher - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
    2007-06-06 17:04:41,759 [main] TRACE AbstractBatcher - closing statement
    2007-06-06 17:04:41,759 [main] DEBUG AbstractCollectionPersister - Inserting collection: [com.motive.criteriatemplate.domain.ParameterGroupMetaData.parameterMeta#96]
    2007-06-06 17:04:41,759 [main] DEBUG AbstractBatcher - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
    2007-06-06 17:04:41,759 [main] DEBUG SQL - update CRITTEMPLATE_PARAMS set PARAM_ID=?, indexVal=? where id=?
    2007-06-06 17:04:41,759 [main] TRACE AbstractBatcher - preparing statement
    2007-06-06 17:04:41,759 [main] TRACE IntegerType - binding '96' to parameter: 1
    2007-06-06 17:04:41,759 [main] TRACE IntegerType - binding '0' to parameter: 2
    2007-06-06 17:04:41,759 [main] TRACE IntegerType - binding '123' to parameter: 3
    2007-06-06 17:04:41,759 [main] DEBUG AbstractBatcher - reusing prepared statement
    2007-06-06 17:04:41,759 [main] DEBUG SQL - update CRITTEMPLATE_PARAMS set PARAM_ID=?, indexVal=? where id=?
    2007-06-06 17:04:41,759 [main] TRACE IntegerType - binding '96' to parameter: 1
    2007-06-06 17:04:41,759 [main] TRACE IntegerType - binding '1' to parameter: 2
    2007-06-06 17:04:41,759 [main] TRACE IntegerType - binding '124' to parameter: 3
    2007-06-06 17:04:41,759 [main] DEBUG AbstractCollectionPersister - done inserting collection: 2 rows inserted
    2007-06-06 17:04:41,759 [main] DEBUG AbstractCollectionPersister - Inserting collection: [com.motive.criteriatemplate.domain.CriteriaTemplate.templateParameterMetaData.parameterSet#86]
    2007-06-06 17:04:41,759 [main] DEBUG AbstractBatcher - Executing batch size: 2
    2007-06-06 17:04:41,790 [main] DEBUG Expectations - success of batch update unknown: 0
    2007-06-06 17:04:41,790 [main] DEBUG Expectations - success of batch update unknown: 1
    2007-06-06 17:04:41,790 [main] DEBUG AbstractBatcher - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
    2007-06-06 17:04:41,790 [main] TRACE AbstractBatcher - closing statement
    2007-06-06 17:04:41,790 [main] DEBUG AbstractBatcher - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
    2007-06-06 17:04:41,790 [main] DEBUG SQL - update CRITTEMPLATE_GROUPS set GROUP_ID=?, indexVal=? where id=?
    2007-06-06 17:04:41,790 [main] TRACE AbstractBatcher - preparing statement
    2007-06-06 17:04:41,790 [main] TRACE IntegerType - binding '86' to parameter: 1
    2007-06-06 17:04:41,790 [main] TRACE IntegerType - binding '0' to parameter: 2
    2007-06-06 17:04:41,790 [main] TRACE IntegerType - binding '96' to parameter: 3
    2007-06-06 17:04:41,790 [main] DEBUG AbstractCollectionPersister - done inserting collection: 1 rows inserted
    2007-06-06 17:04:41,790 [main] DEBUG AbstractBatcher - Executing batch size: 1
    2007-06-06 17:04:41,806 [main] DEBUG Expectations - success of batch update unknown: 0
    2007-06-06 17:04:41,806 [main] DEBUG AbstractBatcher - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
    2007-06-06 17:04:41,806 [main] TRACE AbstractBatcher - closing statement
    2007-06-06 17:04:41,806 [main] TRACE ConnectionManager - registering flush end
    2007-06-06 17:04:41,806 [main] TRACE AbstractFlushingEventListener - post flush
    2007-06-06 17:04:41,806 [main] DEBUG SessionFactoryUtils - Closing Hibernate Session
    Regards,
    Manjunath

  10. #10
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    Ok, but what do you actually do to the entity before you persist it? What changes do you make to actually get it in this state?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •