-->
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.  [ 9 posts ] 
Author Message
 Post subject: persisted object sometimes not being stored in DB
PostPosted: Wed Aug 03, 2005 9:04 pm 
Newbie

Joined: Wed Aug 03, 2005 9:00 pm
Posts: 6
I have a problem that occurs sometimes. I have not been able to identify any differences in the situation that causes the problem and the situation where everything works.

I am creating a new object. When I review the SQL log for postgresql in the working situation I can see:

Code:
2005-08-03 17:00:53 LOG:  statement: select x.linker_id as linker_id, x.subclass as subclass, x.organization_name as organiza5_, x.created as created, x.modified as modified from linkers x where x.subclass in ('COMPANY', 'CLIENT_COMPANY') and ((x.organization_name='Company X' ))
2005-08-03 17:00:53 LOG:  duration: 3.942 ms
2005-08-03 17:00:53 LOG:  statement: select nextval ('hibernate_sequence')
2005-08-03 17:00:53 LOG:  duration: 1.878 ms

2005-08-03 17:00:57 LOG:  statement: insert into linkers (organization_name, created, modified, subclass, linker_id) values ('Company X', '2005-08-03 17:00:53.652000-07', '2005-08-03 17:00:53.652000-07', 'COMPANY', 12746)

2005-08-03 17:00:57 LOG:  duration: 17.492 ms
2005-08-03 17:00:57 LOG:  statement: update linkers set organization_name='Company X', created='2005-08-03 17:00:53.652000-07', modified='2005-08-03 17:00:56.706000-07' where linker_id=12746

2005-08-03 17:00:58 LOG:  statement: insert into links (resume_id, cover_letter_id, stars, distance, created, modified, source_id, target_id, current_status, subclass, link_id) values (null, 12744, null, null, '2005-08-03 17:00:49.507000-07', '2005-08-03 17:00:49.507000-07', 12741, 1431, 'sent', 'APPLICATION', 12745)


(I do not understand why there is the second, seemingly repetitive update statement.) When the problem occurs however the SQL looks different, like this:

Code:
2005-08-03 17:42:52 LOG:  statement: select x.linker_id as linker_id, x.subclass as subclass, x.organization_name as organiza5_, x.created as created, x.modified as modified from linkers x where x.subclass in ('COMPANY', 'CLIENT_COMPANY') and ((x.organization_name='Company X' ))
2005-08-03 17:42:52 LOG:  duration: 1.748 ms
2005-08-03 17:42:52 LOG:  statement: select nextval ('hibernate_sequence')
2005-08-03 17:42:52 LOG:  duration: 0.759 ms

2005-08-03 17:42:53 LOG:  statement: insert into links (position_title, position_description, start_date, end_date, current, created, modified, source_id, target_id, current_status, subclass, link_id) values ('CEO', null, null, null, '0', '2005-08-03 17:42:52.427000-07', '2005-08-03 17:42:52.427000-07', 1, 6, null, 'MANAGEMENT', 7)
2005-08-03 17:42:53 LOG:  statement: SELECT 1 FROM ONLY "public"."linkers" x WHERE "linker_id" = $1 FOR UPDATE OF x
2005-08-03 17:42:53 LOG:  statement: SELECT 1 FROM ONLY "public"."linkers" x WHERE "linker_id" = $1 FOR UPDATE OF x
2005-08-03 17:42:53 ERROR:  insert or update on table "links" violates foreign key constraint "fk6234fb9cf634a89"
DETAIL:  Key (target_id)=(6) is not present in table "linkers".



In the second situation (where the operation fails) hibernate seems to SKIP the insert statement. It is selecting next value from the database and moves forward with the second insert as though the first item was properly saved, but the sql INSERT statement is never issued to the database.

Like I said, sometimes this problem doesnt happen, sometimes it does.

Thanks


Hibernate version: 2.1

Name and version of the database you are using: PostgreSQL 7.1 OS X


Top
 Profile  
 
 Post subject: to clarify
PostPosted: Thu Aug 04, 2005 1:20 am 
Newbie

Joined: Wed Aug 03, 2005 9:00 pm
Posts: 6
I have since discovered that the problem occurs whenever I have the following sequence of events:

load EXISTING instance of Linker (no update)
persist NEW instance of Link (associated with Linker)


The problem does NOT occur for the following:
persist NEW instance of Linker
persist NEW instance of Link (associated with Linker)



Also, my mapping for the two items in quesion are as follows:

Code:
<class
        name="linker.Linker"
        table="linkers"
        dynamic-update="false"
        dynamic-insert="false"
        select-before-update="false"
        optimistic-lock="version"
        mutable="true"
        discriminator-value="LINKER">

        <id
            name="id"
            column="linker_id"
            type="java.lang.Long"
            unsaved-value="null">

            <generator class="native">
            </generator>
        </id>

        <discriminator column="subclass"/>

<bag
            name="inLinks"
            lazy="true"
            inverse="true"
            cascade="none"
        >

              <key
                  column="target_id"
              >
              </key>

              <one-to-many
                  class="link.Link"
              />

        </bag>

        <bag
            name="outLinks"
            lazy="true"
            inverse="true"
            cascade="none"
        >

              <key
                  column="source_id"
              >
              </key>

              <one-to-many
                  class="link.Link"
              />

        </bag>

<subclass
            name="linker.ClientCompany"
            dynamic-update="false"
            dynamic-insert="false"
            discriminator-value="CLIENT_COMPANY"
        >


      <component
            name="name"
            class="linker.name.OrganizationName"
        >
        <property
            name="organizationName"
            type="java.lang.String"
            update="true"
            insert="true"
            access="property"
            column="organization_name"
            not-null="false"
            unique="true"
        />

        </component>

</subclass>
</class>


<class
        name="com.headlesshunter.om.link.Link"
        table="links"
        dynamic-update="false"
        dynamic-insert="false"
        select-before-update="false"
        optimistic-lock="version"
        mutable="true"
    >

        <id
            name="id"
            column="link_id"
            type="java.lang.Long"
            unsaved-value="null"
        >
            <generator class="native">
              <!-- 
                  To add non XDoclet generator parameters, create a file named
                  hibernate-generator-params-Link.xml
                  containing the additional parameters and place it in your merge dir.
              -->
            </generator>
        </id>

        <discriminator
            column="subclass"
        />

   <many-to-one
            name="source"
            class="com.headlesshunter.om.linker.Linker"
            cascade="none"
            outer-join="auto"
            update="true"
            insert="true"
            access="property"
            column="source_id"
            unique="false"
        />

        <many-to-one
            name="target"
            class="com.headlesshunter.om.linker.Linker"
            cascade="none"
            outer-join="auto"
            update="true"
            insert="true"
            access="property"
            column="target_id"
            unique="false"
        />
</class>




Top
 Profile  
 
 Post subject: to clarify
PostPosted: Thu Aug 04, 2005 1:22 am 
Newbie

Joined: Wed Aug 03, 2005 9:00 pm
Posts: 6
I have since discovered that the problem occurs whenever I have the following sequence of events:

load EXISTING instance of Linker (no update)
persist NEW instance of Link (associated with Linker)


The problem does NOT occur for the following:
persist NEW instance of Linker
persist NEW instance of Link (associated with Linker)



Also, my mapping for the two items in quesion are as follows:

Code:
<class
        name="linker.Linker"
        table="linkers"
        dynamic-update="false"
        dynamic-insert="false"
        select-before-update="false"
        optimistic-lock="version"
        mutable="true"
        discriminator-value="LINKER">

        <id
            name="id"
            column="linker_id"
            type="java.lang.Long"
            unsaved-value="null">

            <generator class="native">
            </generator>
        </id>

        <discriminator column="subclass"/>

<bag
            name="inLinks"
            lazy="true"
            inverse="true"
            cascade="none"
        >

              <key
                  column="target_id"
              >
              </key>

              <one-to-many
                  class="link.Link"
              />

        </bag>

        <bag
            name="outLinks"
            lazy="true"
            inverse="true"
            cascade="none"
        >

              <key
                  column="source_id"
              >
              </key>

              <one-to-many
                  class="link.Link"
              />

        </bag>

<subclass
            name="linker.ClientCompany"
            dynamic-update="false"
            dynamic-insert="false"
            discriminator-value="CLIENT_COMPANY"
        >


      <component
            name="name"
            class="linker.name.OrganizationName"
        >
        <property
            name="organizationName"
            type="java.lang.String"
            update="true"
            insert="true"
            access="property"
            column="organization_name"
            not-null="false"
            unique="true"
        />

        </component>

</subclass>
</class>


<class
        name="com.headlesshunter.om.link.Link"
        table="links"
        dynamic-update="false"
        dynamic-insert="false"
        select-before-update="false"
        optimistic-lock="version"
        mutable="true"
    >

        <id
            name="id"
            column="link_id"
            type="java.lang.Long"
            unsaved-value="null"
        >
            <generator class="native">
              <!-- 
                  To add non XDoclet generator parameters, create a file named
                  hibernate-generator-params-Link.xml
                  containing the additional parameters and place it in your merge dir.
              -->
            </generator>
        </id>

        <discriminator
            column="subclass"
        />

   <many-to-one
            name="source"
            class="com.headlesshunter.om.linker.Linker"
            cascade="none"
            outer-join="auto"
            update="true"
            insert="true"
            access="property"
            column="source_id"
            unique="false"
        />

        <many-to-one
            name="target"
            class="com.headlesshunter.om.linker.Linker"
            cascade="none"
            outer-join="auto"
            update="true"
            insert="true"
            access="property"
            column="target_id"
            unique="false"
        />
</class>




Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 04, 2005 3:04 am 
Beginner
Beginner

Joined: Fri Feb 11, 2005 12:03 pm
Posts: 48
Location: Kiel, Germany
Can you please send your Java code for the working and the failing example?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 04, 2005 11:20 am 
Newbie

Joined: Wed Aug 03, 2005 9:00 pm
Posts: 6
Sure, the code for the operation is below.

Both Person and Company extend Linker.

The operation works when an existing person cannot be found and must be created. When an existing person is found, the operation fails.



Quote:

person = ... // provided by user submitted form
company = ... // provided by user submitted form

Person existingPerson = null;
try {
Object[] p = {"some@email"};
Class[] t = {String.class};

String query = "FROM x IN " + Person.class +
" WHERE x.primaryEmail = ?";

existingPerson = (Person) session.findOne(query, p, t);

LOG.info("Found existing account.");

} catch (ObjectNotFoundException e) {
LOG.info("Creating new person");
existingPerson = person;
session.save(existingPerson);
index(existingPerson) // lucene indexer
}


Company existingCompany = null;
try {
Object[] p = {"some company name"};
Class[] t = {String.class};

String query = "FROM x IN " + Company.class +
" WHERE x.name.organizationName = ?";


existingCompany = (Company) session.findOne(query, p, t);

} catch (ItemNotFoundException e) {
LOG.info("creating new company");
existingCompany = company;
session.save(existingCompany);
index(existingCompany) // lucene indexer
}


Link newLink = new Link();
newLink.setSource(existingPerson);
newLink.setTarget(existingCompany);
session.save(newLink);




Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 04, 2005 11:35 am 
Newbie

Joined: Wed Aug 03, 2005 9:00 pm
Posts: 6
One last thing I noticed...

If I remove the foreign key constraint that is causing this operation to fail, everything works!

Returning to the SQL, what is clearly happening is the Link insert is happening BEFORE the Linker (Company in this case) insert.

Is there some ordering requirement in Hibernate I must follow? Its strange becuase my code is session.save()ing the Linker FIRST anyways...

So to recap, hibernate is attempting the following sql:

Code:
2005-08-04 08:29:10 LOG:  statement: insert into links (position_title, position_description, start_date, end_date, current, created, modified, source_id, target_id, current_status, subclass, link_id) values ('asdf', null, '2005-04-04 00:00:00.000000-07', '2008-04-02 00:00:00.000000-08', '0', '2005-08-04 08:29:07.431000-07', '2005-08-04 08:29:07.431000-07', 1, 22, null, 'LINK', 23)
2005-08-04 08:29:10 LOG:  statement: SELECT 1 FROM ONLY "public"."linkers" x WHERE "linker_id" = $1 FOR UPDATE OF x
2005-08-04 08:29:10 LOG:  duration: 9.522 ms
2005-08-04 08:29:10 LOG:  statement: insert into linkers (organization_name, created, modified, subclass, linker_id) values ('asdf', '2005-08-04 08:29:07.373000-07', '2005-08-04 08:29:07.373000-07', 'COMPANY', 22)
2005-08-04 08:29:10 LOG:  duration: 37.169 ms


But because there is a foreign key constraint:
Code:
FOREIGN KEY (target_id) REFERENCES linkers(linker_id)


...and the Linker insert is happening AFTER the Link insert, the operation fails. Agains, since my code is saving the Linker first, I dont understand whats going on.


Thank You


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 05, 2005 3:08 am 
Beginner
Beginner

Joined: Fri Feb 11, 2005 12:03 pm
Posts: 48
Location: Kiel, Germany
I am a bit confused about this. The example shows the case where the Linker and the Link is inserted. But you said the problem would occur when you try to add a Link to an existing Linker. Is the example below one without the foreign key constraint (it seemed to have worked)? In that case the order of the inserts might be different than the order in the code because hibernate persists all changes in the Session when flush() is called, at the latest when the transaction is committed, and in doing so it might change the order (it does not know about the foreign key constraint).

stevedave wrote:
One last thing I noticed...
Code:
2005-08-04 08:29:10 LOG:  statement: insert into links (position_title, position_description, start_date, end_date, current, created, modified, source_id, target_id, current_status, subclass, link_id) values ('asdf', null, '2005-04-04 00:00:00.000000-07', '2008-04-02 00:00:00.000000-08', '0', '2005-08-04 08:29:07.431000-07', '2005-08-04 08:29:07.431000-07', 1, 22, null, 'LINK', 23)
2005-08-04 08:29:10 LOG:  statement: SELECT 1 FROM ONLY "public"."linkers" x WHERE "linker_id" = $1 FOR UPDATE OF x
2005-08-04 08:29:10 LOG:  duration: 9.522 ms
2005-08-04 08:29:10 LOG:  statement: insert into linkers (organization_name, created, modified, subclass, linker_id) values ('asdf', '2005-08-04 08:29:07.373000-07', '2005-08-04 08:29:07.373000-07', 'COMPANY', 22)
2005-08-04 08:29:10 LOG:  duration: 37.169 ms



Another question: I did not find the method findOne in the Hibernate 2.1 API. Didn't I search enough or is this a method of yours?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 05, 2005 1:00 pm 
Newbie

Joined: Wed Aug 03, 2005 9:00 pm
Posts: 6
Yes, foneOne is a method I wrote, but all it does it look up something by the primary key.

And yes, the final insert you mention is WITHOUT the foreign key constraint. Everything works fine when the constraint in dropped.

So does hibernate just insert things in the same order they are saved to the session? Are there things that can change that order? Clearly with foreign key constraints the order is important but as far as I can tell my save statements are in the correct order and yet I have this problem...

Thanks for your help


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 08, 2005 3:13 am 
Beginner
Beginner

Joined: Fri Feb 11, 2005 12:03 pm
Posts: 48
Location: Kiel, Germany
I was totally wrong with my statement that the order of the inserts may be changed by hibernate. It's in the online reference:

http://www.hibernate.org/hib_docs/reference/en/html/manipulatingdata.html#manipulatingdata-flushing


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 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.