-->
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.  [ 1 post ] 
Author Message
 Post subject: optimizing add
PostPosted: Sun Apr 17, 2005 12:12 pm 
Newbie

Joined: Mon Dec 27, 2004 10:23 am
Posts: 7
Hibernate versoin: 2.1.8
Others: using Spring and AndroMDA for code generation

Hi,

I guess this is a very common question: about adding and removing objects from a collection without initializing it:

my code looks like this (using Spring):

Code:
    Rolodex rolodex = user.getRolodex ();
    if (contact.getId()==null) getHibernateTemplate ().save (contact);
    if (rolodex.getContacts()==null) rolodex.setContacts (new HashSet());
    rolodex.getContacts ().add (contact);
    update (rolodex);


Simply put, I have users, which have rolodexes which contain contacts wich are Person entities. those Person entities can belong to several users' rolodexes at the same time. Hence I've modeled a many-to-many relationship between rolodex and contacts

The previous code is a disaster. It generates the following:

Code:
Hibernate: select contacts0_.ROLODEXS_FK as ROLODEXS1___, contacts0_.CONTACTS_FK as CONTACTS2___ from ROLODEX_CONTACTS contacts0_ where contacts0_.ROLODEXS_FK=? order by contacts0_.CONTACTS_FK
Hibernate: select personimpl0_.ID as ID1_, personimpl0_.FIRSTNAME as FIRSTNAME42_1_, personimpl0_.LASTNAME as LASTNAME42_1_, personimpl0_.BIRTHDATE as BIRTHDATE42_1_, personimpl0_.MIDDLE_NAME as MIDDLE_N5_42_1_, personimpl0_.EMAIL as EMAIL42_1_, personimpl0_.PHONE as PHONE42_1_, personimpl0_.MOBILE as MOBILE42_1_, personimpl0_.WORK_PHONE as WORK_PHONE42_1_, personimpl0_.PERSONAL_EMAIL as PERSONA10_42_1_, personimpl0_.ICQ_NUMBER as ICQ_NUMBER42_1_, personimpl0_.MSN_ID as MSN_ID42_1_, personimpl0_.SKYPE_ID as SKYPE_ID42_1_, personimpl0_.SKYPE_NUMBER as SKYPE_N14_42_1_, personimpl0_.FAX as FAX42_1_, personimpl0__2_.TIMESTAMP as TIMESTAMP26_1_, personimpl0__2_.CORE_M_D_FK as CORE_M_D3_26_1_, userimpl1_.ID as ID0_, userimpl1_.USERNAME as USERNAME0_, userimpl1_.PASSWORD as PASSWORD0_, userimpl1_.TIMESTAMP as TIMESTAMP0_, userimpl1_.PERSON_FK as PERSON_FK0_, userimpl1_.THUMBNAIL_FK as THUMBNAI6_0_, userimpl1_.ROLODEX_FK as ROLODEX_FK0_, userimpl1_.CALENDAR_FK as CALENDAR8_0_ from PERSON personimpl0_ inner join ABSTRACT_OBJECT personimpl0__1_ on personimpl0_.ID=personimpl0__1_.ID inner join RESOURCE personimpl0__2_ on personimpl0_.ID=personimpl0__2_.ID left outer join USER userimpl1_ on personimpl0_.ID=userimpl1_.PERSON_FK where personimpl0_.ID=?
Hibernate: select userimpl0_.ID as ID0_, userimpl0_.USERNAME as USERNAME0_, userimpl0_.PASSWORD as PASSWORD0_, userimpl0_.TIMESTAMP as TIMESTAMP0_, userimpl0_.PERSON_FK as PERSON_FK0_, userimpl0_.THUMBNAIL_FK as THUMBNAI6_0_, userimpl0_.ROLODEX_FK as ROLODEX_FK0_, userimpl0_.CALENDAR_FK as CALENDAR8_0_ from USER userimpl0_ where userimpl0_.PERSON_FK=?
Hibernate: select personimpl0_.ID as ID1_, personimpl0_.FIRSTNAME as FIRSTNAME42_1_, personimpl0_.LASTNAME as LASTNAME42_1_, personimpl0_.BIRTHDATE as BIRTHDATE42_1_, personimpl0_.MIDDLE_NAME as MIDDLE_N5_42_1_, personimpl0_.EMAIL as EMAIL42_1_, personimpl0_.PHONE as PHONE42_1_, personimpl0_.MOBILE as MOBILE42_1_, personimpl0_.WORK_PHONE as WORK_PHONE42_1_, personimpl0_.PERSONAL_EMAIL as PERSONA10_42_1_, personimpl0_.ICQ_NUMBER as ICQ_NUMBER42_1_, personimpl0_.MSN_ID as MSN_ID42_1_, personimpl0_.SKYPE_ID as SKYPE_ID42_1_, personimpl0_.SKYPE_NUMBER as SKYPE_N14_42_1_, personimpl0_.FAX as FAX42_1_, personimpl0__2_.TIMESTAMP as TIMESTAMP26_1_, personimpl0__2_.CORE_M_D_FK as CORE_M_D3_26_1_, userimpl1_.ID as ID0_, userimpl1_.USERNAME as USERNAME0_, userimpl1_.PASSWORD as PASSWORD0_, userimpl1_.TIMESTAMP as TIMESTAMP0_, userimpl1_.PERSON_FK as PERSON_FK0_, userimpl1_.THUMBNAIL_FK as THUMBNAI6_0_, userimpl1_.ROLODEX_FK as ROLODEX_FK0_, userimpl1_.CALENDAR_FK as CALENDAR8_0_ from PERSON personimpl0_ inner join ABSTRACT_OBJECT personimpl0__1_ on personimpl0_.ID=personimpl0__1_.ID inner join RESOURCE personimpl0__2_ on personimpl0_.ID=personimpl0__2_.ID left outer join USER userimpl1_ on personimpl0_.ID=userimpl1_.PERSON_FK where personimpl0_.ID=?
Hibernate: select userimpl0_.ID as ID0_, userimpl0_.USERNAME as USERNAME0_, userimpl0_.PASSWORD as PASSWORD0_, userimpl0_.TIMESTAMP as TIMESTAMP0_, userimpl0_.PERSON_FK as PERSON_FK0_, userimpl0_.THUMBNAIL_FK as THUMBNAI6_0_, userimpl0_.ROLODEX_FK as ROLODEX_FK0_, userimpl0_.CALENDAR_FK as CALENDAR8_0_ from USER userimpl0_ where userimpl0_.PERSON_FK=?
Hibernate: select personimpl0_.ID as ID1_, personimpl0_.FIRSTNAME as FIRSTNAME42_1_, personimpl0_.LASTNAME as LASTNAME42_1_, personimpl0_.BIRTHDATE as BIRTHDATE42_1_, personimpl0_.MIDDLE_NAME as MIDDLE_N5_42_1_, personimpl0_.EMAIL as EMAIL42_1_, personimpl0_.PHONE as PHONE42_1_, personimpl0_.MOBILE as MOBILE42_1_, personimpl0_.WORK_PHONE as WORK_PHONE42_1_, personimpl0_.PERSONAL_EMAIL as PERSONA10_42_1_, personimpl0_.ICQ_NUMBER as ICQ_NUMBER42_1_, personimpl0_.MSN_ID as MSN_ID42_1_, personimpl0_.SKYPE_ID as SKYPE_ID42_1_, personimpl0_.SKYPE_NUMBER as SKYPE_N14_42_1_, personimpl0_.FAX as FAX42_1_, personimpl0__2_.TIMESTAMP as TIMESTAMP26_1_, personimpl0__2_.CORE_M_D_FK as CORE_M_D3_26_1_, userimpl1_.ID as ID0_, userimpl1_.USERNAME as USERNAME0_, userimpl1_.PASSWORD as PASSWORD0_, userimpl1_.TIMESTAMP as TIMESTAMP0_, userimpl1_.PERSON_FK as PERSON_FK0_, userimpl1_.THUMBNAIL_FK as THUMBNAI6_0_, userimpl1_.ROLODEX_FK as ROLODEX_FK0_, userimpl1_.CALENDAR_FK as CALENDAR8_0_ from PERSON personimpl0_ inner join ABSTRACT_OBJECT personimpl0__1_ on personimpl0_.ID=personimpl0__1_.ID inner join RESOURCE personimpl0__2_ on personimpl0_.ID=personimpl0__2_.ID left outer join USER userimpl1_ on personimpl0_.ID=userimpl1_.PERSON_FK where personimpl0_.ID=?
..... (and on and on and on and on)...


I've read the faq entry about this, but it is a bit unclear to me:

Quote:
Unfortunately the collections API defines method return values that may only be computed by hitting the database. There are three exceptions to this: Hibernate can add to a <bag>, <idbag> or <list> declared with inverse="true" without initializing the collection; the return value must always be true.


Now, actually I am a bit limited by what AndroMDA can offer, but I can maybe talk about this issue to the developers.

However, could somebody tell me if the following:

Code:
        <set name="contacts" table="ROLODEX_CONTACTS" order-by="CONTACTS_FK" outer-join="auto" lazy="true" inverse="false">
            <key foreign-key="ROLODEX_CONTACTS_FKC">
                <column name="ROLODEXS_FK"/>
            </key>
            <many-to-many class="fractals.psychos.core.ontology.entity.PersonImpl" column="CONTACTS_FK" foreign-key="ROLODEX_CONTACTS_FKC"/>
        </set>


could be generated using bag, idbag or list without changing the semantics. I do not understand what "the return value must always be true" actually means in this context.

Quote:
If you want to avoid extra database traffic (ie. in performance critical code), refactor your model to use only many-to-one associations. This is almost always possible. Then use queries in place of collection access.


OK: in my case (rolodex/contacts) it is really impossible to model the relationship as many-to-one (or is it?). Anyway I don't think a query could help me in the case of adding an entity to a collection.

At this time, I'm really stuck here: the performance is really unacceptable, and I can see no other solution than to bypass hibernate and access the database myself (which would really make me feel bad)

bernard


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

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.