-->
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: Interdependent properties
PostPosted: Tue Aug 22, 2006 9:02 am 
Newbie

Joined: Mon Aug 21, 2006 10:41 am
Posts: 2
I'm doing a site for a photographer friend and decided to use Hibernate (v3.1.2). I got the Hibernate in Action book, read through it and got cracking. I'd appreciate any pointers on a difficulty I've been having with two properties of an object that are not entirely independent. I'm not looking for a solution; I'd be delighted to just be told where I should be reading next.

The central notion is of a job that is comprised of many photos. Each photo has a category embedded in its metadata. An archive is uploaded from which I extract the photos. For each one, I parse out its category. I then create a set of photos, set it as a property on the job and save the job using Hibernate. This all works fine and the database tables for jobs and photos get populated as required. The relevant sections from Job.hbm.xml and Photo.hbm.xml are as follows (I've trimmed out simple string properties from both, for clarity):

Code:
    <class name="Job" table="jobs" schema="public">
        <id name="id" type="int">
            <column name="id" />
            <generator class="sequence">
                <param name="sequence">jobs_id_seq</param>
            </generator>
        </id>
        <set name="photos" inverse="true" cascade="all">
            <key column="job_id"/>
            <one-to-many class="Photo"/>   
        </set>
    </class>


Code:
    <class name="Photo" table="photos" schema="public">
        <id name="id" type="long">
            <column name="id" />
            <generator class="sequence">
                <param name="sequence">photos_id_seq</param>
            </generator>
        </id>
        <property name="category" type="string">
            <column name="category" length="10" not-null="true" />
        </property>
        <property name="content" type="binary">
            <column name="content" not-null="true" />
        </property>
        <many-to-one name="job" class="Job">
            <column name="job_id" not-null="true" />
        </many-to-one>
    </class>

So far so good. I also decided, as an optimisation, to retain the list of categories that appear in a job as a property of that job (seeing as I have to process each photo when they're being uploaded and I have access to that information at that point). So I put an extra string field in class Job that is a list of all the unique categories, using a special character to delimit them. The code inside the setPhotos() method also sets this list of categories.

At this point, there was a slight change to the requirements. In certain cases, categories will have a natural notion of order (whether this is a temporal order or whatever). So he would like to be able to edit this order, so that they are presented to users in a more natural way. I promptly renamed the property from "categories" to "categoryOrdering", and did up a second page that would allow categories to be re-ordered (modifying this string property), before the overall job was saved. I can't get this to work. I followed as many potential leads as I could from the forums but have drawn a blank. (E.g. I implemented equals() and hashCode() on both entities in terms of a business key, and so on.)

What's happening is that the setPhotos() method is being called a second time, which overwrites the re-ordered list of categories back to the original un-ordered list of categories. I can't see why it should be doing this. I understand that the Photo objects will obtain keys as part of the cascade, but there are no additions or deletions from the set of photos, so I'm not sure why the overall property is being re-set. (In line with the discussion on page 171 of HiA, where the modification of a Bid does not lead to the version of Item being incremented.) It occurred to me that it might have something to do with proxies but I tried it with the lazy attribute of the associate set to both true and false and the results were identical. Finally, I put print statements in all the setters of the Job class to see how many Job objects were involved. The following is typical output:

[After the initial upload page, called by the web framework]
Code:
setTitle called on model.Job@17cd7
setYear called on model.Job@a097132d
setFolderName called on model.Job@a097132d
setPhotos called on model.Job@a097132d


[After the category re-ordering page, when I save the Job in Hibernate]
Code:
setId called on model.Job@a097132d
setTitle called on model.Job@a097132d
setYear called on model.Job@a097132d
setFolderName called on model.Job@a097132d
setCategoryOrdering called on model.Job@a097132d
setPhotos called on model.Job@a097132d


In other words, all calls are on the same object, except for the very first one. That object doesn't seem to be involved again (but the title that was set is captured somewhere in the system). The problem is in the last two lines. setCategoryOrdering() sets the string that holds the ordered list of categories correctly and then setPhotos() overwrites it back to what it was. This would be the correct behaviour if we were dealing with a new set of photos, but the set of photos is unmodified (modulo the acquisition of IDs).

One possible approach is to introduce a separate Category entity, but the above is "idiomatic" Java to me and I would like to first-of-all attempt to get it working before adapting my code to the persistence framework. More to the point, I'd like to get to the bottom of why it's happening to deepen my understanding of Hibernate.

Thanks in advance,

John.


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.