-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: Assigning ID programatically and associations problem
PostPosted: Mon Oct 17, 2005 6:27 pm 
Newbie

Joined: Tue Jun 07, 2005 1:08 pm
Posts: 10
I'm running into a problem that I hope someone has some insight into. Our application is currently setting the id programatically in our base domain object's constructor. The mapping for the domain object, which every other object extends, defines the ID as assigned in the mapping file. We then set the ID in the constructor.

So my problem occurs when I have a new object graph that I'm trying to persist all at once. So in this case, I've got a Person object that has a list of contacts (phone, address, etc). When I save Person, the logs show that it's performing an insert into the Person table (which is correct), but when it gets to Phone, it's performing an update instead of an insert. Is this because the ID is set, so hibernate thinks that the object isn't transient?

I'm using hibernate version 3.0.5.

Here's my mapping:

Code:
    <class name="com.tickets.common.domain.DomainObject" table="DOMAIN_OBJECT" dynamic-insert="false"
           dynamic-update="false" abstract="true">
        <id name="id" type="java.lang.String" unsaved-value="null">
            <column name="ID" sql-type="CHARACTER VARYING(22)" />
            <generator class="assigned">
            </generator>
        </id>
        <property name="owningId" type="java.lang.String">
            <column name="OWNING_ID" not-null="false" unique="false" sql-type="CHARACTER VARYING(22)" />
        </property>
    </class>

    <union-subclass name="com.tickets.patron.domain.Party" extends="com.tickets.common.domain.TraitableDomainObject"
                    table="PARTY" dynamic-insert="false" dynamic-update="false" abstract="true">
        <property name="phonetics" type="java.lang.String">
            <column name="PHONETICS" not-null="false" unique="false" sql-type="CHARACTER VARYING(1024)" />
        </property>
        <property name="formattedName" type="java.lang.String">
            <column name="FORMATTED_NAME" not-null="false" unique="false" sql-type="CHARACTER VARYING(1024)" />
        </property>
        <property name="formatOverride" type="boolean">
            <column name="FORMAT_OVERRIDE" not-null="false" unique="false" sql-type="BOOLEAN" />
        </property>
        <property name="active" type="boolean">
            <column name="ACTIVE" not-null="true" unique="false" sql-type="BOOLEAN" />
        </property>
        <property name="name" type="java.lang.String">
            <column name="NAME" not-null="true" unique="false" sql-type="CHARACTER VARYING(1024)" />
        </property>

        <set name="creditCards" order-by="PARTY_ID" lazy="true" fetch="select" inverse="true"
             cascade="save-update,delete">
            <key foreign-key="CREDIT_CARD_PARTY_IDC">
                <column name="PARTY_ID" sql-type="CHARACTER VARYING(22)" />
            </key>
            <one-to-many class="com.tickets.common.domain.CreditCard" />
        </set>

        <bag name="contacts" order-by="PARTY_ID" lazy="true" fetch="select" inverse="true" cascade="save-update,delete">
            <key foreign-key="CONTACT_PARTY_IDC">
                <column name="PARTY_ID" sql-type="CHARACTER VARYING(22)" />
            </key>
            <one-to-many class="com.tickets.common.domain.Contact" />
        </bag>

        <set name="notes" table="PARTY_CORRESPONDENCE" order-by="PARTY_ID" lazy="true" fetch="select" inverse="false"
             cascade="save-update,delete">
            <key foreign-key="CORRESPONDENCE_PARTY_IDC">
                <column name="PARTY_ID" sql-type="CHARACTER VARYING(22)" />
            </key>
            <many-to-many class="com.tickets.common.domain.Correspondence" column="NOTES_ID" unique="true" />
        </set>
        <many-to-one name="primaryPhone" class="com.tickets.common.domain.Phone" cascade="save-update,delete"
                     foreign-key="PARTY_PRIMARY_PHONE_IDC" lazy="false" fetch="select">
            <column name="PRIMARY_PHONE_ID" not-null="false" sql-type="CHARACTER VARYING(22)" />
        </many-to-one>
        <many-to-one name="primaryAddress" class="com.tickets.common.domain.Address" cascade="save-update,delete"
                     foreign-key="PARTY_PRIMARY_ADDRESS_IDC" lazy="false" fetch="select">
            <column name="PRIMARY_ADDRESS_ID" not-null="false" sql-type="CHARACTER VARYING(22)" />
        </many-to-one>
        <many-to-one name="primaryEmail" class="com.tickets.common.domain.Email" cascade="save-update,delete"
                     foreign-key="PARTY_PRIMARY_EMAIL_IDC" lazy="false" fetch="select">
            <column name="PRIMARY_EMAIL_ID" not-null="false" sql-type="CHARACTER VARYING(22)" />
        </many-to-one>
        <many-to-one name="primaryCreditCard" class="com.tickets.common.domain.CreditCard"
                     foreign-key="PARTY_PRIMARY_CREDIT_CARD_IDC" lazy="false" fetch="select">
            <column name="PRIMARY_CREDIT_CARD_ID" not-null="false" sql-type="CHARACTER VARYING(22)" />
        </many-to-one>

        <set name="linkedPatrons" table="PARTY_PATRONLINK" order-by="PARTY_ID" lazy="true" fetch="select"
             inverse="false">
            <key foreign-key="PATRON_LINK_PARTY_IDC">
                <column name="PARTY_ID" sql-type="CHARACTER VARYING(22)" />
            </key>
            <many-to-many class="com.tickets.patron.domain.PatronLink" column="LINKED_PATRONS_ID" unique="true" />
        </set>
        <many-to-one name="subordinate" class="com.tickets.patron.domain.Party" foreign-key="PARTY_SUBORDINATE_IDC"
                     lazy="proxy" fetch="select">
            <column name="SUBORDINATE_ID" not-null="false" sql-type="CHARACTER VARYING(22)" />
        </many-to-one>
        <set name="accounts" table="ACCOUNT_PARTY" order-by="ACCOUNTS_ID" lazy="true" fetch="select" inverse="true">
            <key foreign-key="ACCOUNT_OWNERS_IDC">
                <column name="OWNERS_ID" sql-type="CHARACTER VARYING(22)" />
            </key>
            <many-to-many class="com.tickets.account.domain.Account" foreign-key="PARTY_ACCOUNTS_IDC">
                <column name="ACCOUNTS_ID" sql-type="CHARACTER VARYING(22)" />
            </many-to-many>
        </set>
    </union-subclass>

    <union-subclass name="com.tickets.patron.domain.Person" extends="com.tickets.patron.domain.Party" table="PERSON"
                    dynamic-insert="false" dynamic-update="false" abstract="false">
        <property name="firstName" type="java.lang.String">
            <column name="FIRST_NAME" not-null="true" unique="false" sql-type="CHARACTER VARYING(50)" />
        </property>
        <property name="middleName" type="java.lang.String">
            <column name="MIDDLE_NAME" not-null="false" unique="false" sql-type="CHARACTER VARYING(1024)" />
        </property>
        <property name="lastName" type="java.lang.String">
            <column name="LAST_NAME" not-null="true" unique="false" sql-type="CHARACTER VARYING(1024)" />
        </property>
        <property name="formalSalutation" type="java.lang.String">
            <column name="FORMAL_SALUTATION" not-null="false" unique="false" sql-type="CHARACTER VARYING(1024)" />
        </property>
        <property name="salutationOverride" type="boolean">
            <column name="SALUTATION_OVERRIDE" not-null="false" unique="false" sql-type="BOOLEAN" />
        </property>
        <property name="namePrefix" type="java.lang.String">
            <column name="NAME_PREFIX" not-null="false" unique="false" sql-type="CHARACTER VARYING(1024)" />
        </property>
        <property name="nameSuffix" type="java.lang.String">
            <column name="NAME_SUFFIX" not-null="false" unique="false" sql-type="CHARACTER VARYING(1024)" />
        </property>
    </union-subclass>


    <union-subclass name="com.tickets.common.domain.Phone" extends="com.tickets.common.domain.Contact" table="PHONE"
                    dynamic-insert="false" dynamic-update="false" abstract="false">
        <property name="countryCode" type="java.lang.String">
            <column name="COUNTRY_CODE" not-null="false" unique="false" sql-type="CHARACTER VARYING(1024)" />
        </property>
        <property name="areaCode" type="java.lang.String">
            <column name="AREA_CODE" not-null="true" unique="false" sql-type="CHARACTER VARYING(1024)" />
        </property>
        <property name="localNumber" type="java.lang.String">
            <column name="LOCAL_NUMBER" not-null="true" unique="false" sql-type="CHARACTER VARYING(1024)" />
        </property>
        <property name="extension" type="java.lang.String">
            <column name="EXTENSION" not-null="false" unique="false" sql-type="CHARACTER VARYING(1024)" />
        </property>
        <property name="phoneDisplay" type="java.lang.String">
            <column name="PHONE_DISPLAY" not-null="false" unique="false" sql-type="CHARACTER VARYING(1024)" />
        </property>
        <property name="telemarket" type="boolean">
            <column name="TELEMARKET" not-null="false" unique="false" sql-type="BOOLEAN" />
        </property>
    </union-subclass>



Regarding my source code, my pojo's are really straight forward. I'll ommit those for the sake of keeping this post short. But when I go to persist the object, I call session.save().

Here's the log output:
Code:
[org.hibernate.engine.ActionQueue]changes must be flushed to space: PERSON
[org.hibernate.event.def.DefaultAutoFlushEventListener]Need to execute flush
[org.hibernate.event.def.AbstractFlushingEventListener]executing flush
[org.hibernate.persister.entity.BasicEntityPersister]Inserting entity: [com.tickets.patron.domain.Person#pFtJDsKBdKLv6AhDMHUNa]
[org.hibernate.jdbc.AbstractBatcher]about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
[org.hibernate.SQL]insert into PERSON (OWNING_ID, PHONETICS, FORMATTED_NAME, FORMAT_OVERRIDE, ACTIVE, NAME, PRIMARY_PHONE_ID, PRIMARY_ADDRESS_ID, PRIMARY_EMAIL_ID, PRIMARY_CREDIT_CARD_ID, SUBORDINATE_ID, FIRST_NAME, MIDDLE_NAME, LAST_NAME, FORMAL_SALUTATION, SALUTATION_OVERRIDE, NAME_PREFIX, NAME_SUFFIX, ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
[org.hibernate.jdbc.AbstractBatcher]preparing statement
[org.hibernate.persister.entity.BasicEntityPersister]Dehydrating entity: [com.tickets.patron.domain.Person#pFtJDsKBdKLv6AhDMHUNa]
[org.hibernate.type.StringType]binding null to parameter: 1
[org.hibernate.type.StringType]binding 'JNT' to parameter: 2
[org.hibernate.type.StringType]binding 'Mr. John  Doe' to parameter: 3
[org.hibernate.type.BooleanType]binding 'false' to parameter: 4
[org.hibernate.type.BooleanType]binding 'false' to parameter: 5
[org.hibernate.type.StringType]binding 'Doe, John' to parameter: 6
[org.hibernate.type.StringType]binding null to parameter: 7
[org.hibernate.type.StringType]binding null to parameter: 8
[org.hibernate.type.StringType]binding null to parameter: 9
[org.hibernate.type.StringType]binding null to parameter: 10
[org.hibernate.type.StringType]binding null to parameter: 11
[org.hibernate.type.StringType]binding 'John' to parameter: 12
[org.hibernate.type.StringType]binding null to parameter: 13
[org.hibernate.type.StringType]binding 'Doe' to parameter: 14
[org.hibernate.type.StringType]binding null to parameter: 15
[org.hibernate.type.BooleanType]binding 'false' to parameter: 16
[org.hibernate.type.StringType]binding 'Mr.' to parameter: 17
[org.hibernate.type.StringType]binding null to parameter: 18
[org.hibernate.type.StringType]binding 'pFtJDsKBdKLv6AhDMHUNa' to parameter: 19
[org.hibernate.jdbc.AbstractBatcher]Adding to batch
[org.hibernate.persister.entity.BasicEntityPersister]Inserting entity: [com.tickets.patron.domain.Organization#pYmxmKBhDu0MHgrBWgL48]
[org.hibernate.jdbc.AbstractBatcher]Executing batch size: 1
[org.hibernate.jdbc.AbstractBatcher]about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
[org.hibernate.jdbc.AbstractBatcher]closing statement
[org.hibernate.jdbc.AbstractBatcher]about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
[org.hibernate.SQL]insert into ORGANIZATION (OWNING_ID, PHONETICS, FORMATTED_NAME, FORMAT_OVERRIDE, ACTIVE, NAME, PRIMARY_PHONE_ID, PRIMARY_ADDRESS_ID, PRIMARY_EMAIL_ID, PRIMARY_CREDIT_CARD_ID, SUBORDINATE_ID, PARENT_ID, ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
[org.hibernate.jdbc.AbstractBatcher]preparing statement
[org.hibernate.persister.entity.BasicEntityPersister]Dehydrating entity: [com.tickets.patron.domain.Organization#pYmxmKBhDu0MHgrBWgL48]
[org.hibernate.type.StringType]binding null to parameter: 1
[org.hibernate.type.StringType]binding 'TSKN' to parameter: 2
[org.hibernate.type.StringType]binding 'Doe's Consulting Firm' to parameter: 3
[org.hibernate.type.BooleanType]binding 'false' to parameter: 4
[org.hibernate.type.BooleanType]binding 'false' to parameter: 5
[org.hibernate.type.StringType]binding 'Doe's Consulting Firm' to parameter: 6
[org.hibernate.type.StringType]binding null to parameter: 7
[org.hibernate.type.StringType]binding null to parameter: 8
[org.hibernate.type.StringType]binding null to parameter: 9
[org.hibernate.type.StringType]binding null to parameter: 10
[org.hibernate.type.StringType]binding null to parameter: 11
[org.hibernate.type.StringType]binding null to parameter: 12
[org.hibernate.type.StringType]binding 'pYmxmKBhDu0MHgrBWgL48' to parameter: 13
[org.hibernate.jdbc.AbstractBatcher]Adding to batch
[org.hibernate.jdbc.AbstractBatcher]Executing batch size: 1
[org.hibernate.jdbc.AbstractBatcher]about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
[org.hibernate.jdbc.AbstractBatcher]closing statement
[org.hibernate.persister.entity.BasicEntityPersister]Updating entity: [com.tickets.common.domain.Phone#pFtJFXMdvTqFVicoUC7gc]
[org.hibernate.jdbc.AbstractBatcher]about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
[org.hibernate.SQL]update PHONE set OWNING_ID=?, USAGE_TYPE_ID=?, PARTY_ID=?, COUNTRY_CODE=?, AREA_CODE=?, LOCAL_NUMBER=?, EXTENSION=?, PHONE_DISPLAY=?, TELEMARKET=?, ADDRESS_ID=? where ID=?
[org.hibernate.jdbc.AbstractBatcher]preparing statement
[org.hibernate.persister.entity.BasicEntityPersister]Dehydrating entity: [com.tickets.common.domain.Phone#pFtJFXMdvTqFVicoUC7gc]
[org.hibernate.type.StringType]binding null to parameter: 1
[org.hibernate.type.StringType]binding 'pFtJDsKBdKLv6AhDMHUNa' to parameter: 3
[org.hibernate.type.StringType]binding null to parameter: 4
[org.hibernate.type.StringType]binding '714' to parameter: 5
[org.hibernate.type.StringType]binding '327-5400' to parameter: 6
[org.hibernate.type.StringType]binding null to parameter: 7
[org.hibernate.type.StringType]binding null to parameter: 8
[org.hibernate.type.BooleanType]binding 'false' to parameter: 9
[org.hibernate.type.StringType]binding 'pGaXpnG5cUudY1piN6jUU' to parameter: 10
[org.hibernate.type.StringType]binding 'pFtJFXMdvTqFVicoUC7gc' to parameter: 11
[org.hibernate.jdbc.AbstractBatcher]Adding to batch
[org.hibernate.persister.entity.BasicEntityPersister]Updating entity: [com.tickets.common.domain.Address#pGaXpnG5cUudY1piN6jUU]
[org.hibernate.jdbc.AbstractBatcher]Executing batch size: 1
[org.hibernate.jdbc.AbstractBatcher]Exception executing batch:
org.hibernate.StaleStateException: Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1
   at org.hibernate.jdbc.BatchingBatcher.checkRowCount(BatchingBatcher.java:92)
   at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:78)
   at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:57)
   at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:174)
   at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:74)



Notice the call to update phone instead of actually inserting it. Now I could create the phone object before persisting the person, but that's not the behavior I'm striving for. I want to be able to persist the whole graph all at once.

Can anyone shed some light if this is a problem? Or if this is a common problem, what are some possible solutions?

Thanks in advance.

John


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 17, 2005 6:35 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
read the documentation regarding id mappings. Especially the bit about unsaved-value...

http://www.hibernate.org/hib_docs/v3/reference/en/html/mapping.html#mapping-declaration-id


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.