-->
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.  [ 11 posts ] 
Author Message
 Post subject: Update Before Insert
PostPosted: Sun Feb 27, 2011 10:33 pm 
Newbie

Joined: Sat Mar 29, 2008 4:49 pm
Posts: 19
At my wit's end and I can't seem to find the solution on the forums or documentation because I don't know what I'm looking for (keywords to use). Essentially I have two classes:

Code:
<class name="Foo" table="FOO">
        <id name="id" type="long">
            <column name="ID" />
            <generator class="assigned" />
        </id>
        <list name="myBars" table="BAR" >
            <key>
                <column name="ID" not-null="true" />
            </key>
            <list-index></list-index>
            <one-to-many class="Bar" />
        </list>
</class>

and
Code:
<class name="Bar" table="BAR">
        <id name="id" type="long">
            <column name="ID" />
            <generator class="assigned" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
</class>


In my Java code, I do:

Code:
  Bar bar = new Bar();
  bar.setName("Me");
  List<Bar> bars = new Vector<Bar>();
  bars.add(bar);
  Foo foo = new Foo();
  foo.setMyBars(bars);
  Transaction tx = session.beginTransaction();
  session.save(foo);
  tx.commit();


When I do, I get the following in the logs:

Code:
Hibernate: insert into FOO (ID) values (?)
Hibernate: update BAR set ID=?, idx=? where ID=?
Exception in thread "main" org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
   at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:85)
   at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:70)
   at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:90)
   at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
   at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:268)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:188)
   at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
   at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
   at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
   at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)
   at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)


The problem is Hibernate tries to update a value that does not yet exist. If I try to save bar first, I get:

Code:
Hibernate: insert into BAR (NAME, ID) values (?, ?)
Exception in thread "main" org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
   at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96)
   at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
   at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
   at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:114)
   at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:109)
   at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:244)
   at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2411)
   at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2874)
   at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:79)
   at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:265)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:184)
   at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
   at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
   at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
   at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)
   at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)
Caused by: java.sql.BatchUpdateException: Batch entry 0 insert into BAR (NAME, ID) values ('Me', '0') was aborted.  Call getNextException to see the cause.
   at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2586)
   at org.postgresql.core.v3.QueryExecutorImpl$1.handleError(QueryExecutorImpl.java:459)
   at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1811)
   at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:407)
   at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2725)
   at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
   at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
   ... 15 more


In this case, Hibernate tries to INSERT into BAR first, but the FK constraint won't allow it. I'm not sure what to do. I can't seem to find the right Hibernate config magic to get it to work. I'm using PostgreSQL and the PostgreSQLDialect, Hibernate3 3.6.1-Final.


Top
 Profile  
 
 Post subject: Re: Update Before Insert
PostPosted: Mon Feb 28, 2011 1:22 am 
Regular
Regular

Joined: Fri Nov 12, 2010 4:13 am
Posts: 81
Location: India
Check out this discussion it may help you.

viewtopic.php?f=1&t=1008355

_________________
Thanks & Regards,
Chirag


Top
 Profile  
 
 Post subject: Re: Update Before Insert
PostPosted: Mon Feb 28, 2011 1:38 am 
Newbie

Joined: Sat Mar 29, 2008 4:49 pm
Posts: 19
I went through the thread you pointed me to. That is talking about Hibernate detecting that a change had occurred to a related class (is dirty) and so updates the related table as well. I'm not sure how that is related to the issue that I have. My setters are strictly setters so if a change had occurred, then it's a valid change (as opposed to some data manipulation being done in the setter).

About the only clue that I don't understand and which might be what you were referring to was the use of the @Transient annotation. Is that what you were referring me to?

I need to get Hibernate to either:

  1. Do an "INSERT INTO FOO (ID) VALUES (?)" then "INSERT INTO BAR (ID, NAME) VALUES (?, ?)" (and not "UPDATE BAR ..."); or,
  2. Do the "INSERT INTO BAR ..." first but somehow make PostgreSQL ignore the constraint until the "INSERT INTO FOO ..." was done; or even,
  3. Not make Hibernate generate the constraint on BAR's id


Top
 Profile  
 
 Post subject: Re: Update Before Insert
PostPosted: Mon Feb 28, 2011 2:17 am 
Regular
Regular

Joined: Fri Nov 12, 2010 4:13 am
Posts: 81
Location: India
Other problem i can see is you are using generator class=assigned for generating id.So how are you assigning id's to table foo and bars??

_________________
Thanks & Regards,
Chirag


Top
 Profile  
 
 Post subject: Re: Update Before Insert
PostPosted: Mon Feb 28, 2011 2:22 am 
Newbie

Joined: Sat Mar 29, 2008 4:49 pm
Posts: 19
Actually, I just switched my id (after re-reading the documentation) from primitive type long to the non-primitive Long and am now using generator class="sequence". I get exactly the same results as above (with the only difference being that instead of starting id at 0, it now starts at 1), so that doesn't seem to be it.


Top
 Profile  
 
 Post subject: Re: Update Before Insert
PostPosted: Mon Feb 28, 2011 2:32 am 
Regular
Regular

Joined: Fri Nov 12, 2010 4:13 am
Posts: 81
Location: India
Does your table bar have same primary key name as id??


<class name="Foo" table="FOO">
<id name="ID">
<generator class="sequence">
<param name="sequence">SEQ_FOO</param>
</generator>

</id>
<list name="myBars" table="BAR" cascade="all">
<key column="ID" not-null="true"/>
<one-to-many class="Bar" />
</list>
</class>


<class name="Bar" table="BAR">
<id name="barId">
<generator class="sequence">
<param name="sequence">SEQ_BAR</param>
</generator>
<property name="ID" type="java.lang.String">
<property name="name" column="name" type="java.lang.String">
</property>
</class>


Try this code.

_________________
Thanks & Regards,
Chirag


Top
 Profile  
 
 Post subject: Re: Update Before Insert
PostPosted: Mon Feb 28, 2011 3:19 am 
Newbie

Joined: Sat Mar 29, 2008 4:49 pm
Posts: 19
Yes, BAR has the same PRIMARY KEY column (ID) as the FOREIGN KEY in FOO. I just assumed that that was as it was supposed to be. I've modified my config to use a different primary key for BAR as the foreign key for FOO. It seems to work now if I remove the not-null="true" parameters. With not-null="true", Hibernate complains that "not-null property references a null or transient value: Bar._.Foo.leaderStepGroupsBackref". I remove it and it works fine.

At one point in time, I got a config (which had not-null="true") that resulted in an error where it was stating that something had to have insert="false" and update="false", but I can't seem to reproduce it anymore.

Obviously I'm working here from a state of ignorance as to how Hibernate (or even SQL) is supposed to work. Is the correct approach then to create an entirely new key in BAR that references the primary key in FOO?


Top
 Profile  
 
 Post subject: Re: Update Before Insert
PostPosted: Mon Feb 28, 2011 3:23 am 
Newbie

Joined: Sat Mar 29, 2008 4:49 pm
Posts: 19
Ah ... when I add the ID property in BAR, I get:
Code:
Repeated column in mapping for entity: Bar column: ID (should be mapped with insert="false" update="false")


And when I actually add 'insert="false" update="false"' to the ID property in BAR, I get:
Code:
Unable to instantiate default tuplizer [org.hibernate.tuple.entity.PojoEntityTuplizer]


Top
 Profile  
 
 Post subject: Re: Update Before Insert
PostPosted: Mon Feb 28, 2011 3:40 am 
Regular
Regular

Joined: Fri Nov 12, 2010 4:13 am
Posts: 81
Location: India
How can u assign two values to same column by generator=sequence and one coming from FOO.Instead you create a primary key column with unique name for Bar and ID column will be assigned by primary key of your FOO table.

FOO TABLE :
id (primary key)

BAR TABLE :
barId (primary key)
id (foreign key to table)
..

this will be your table format.And xml mapping i have already given to you.

_________________
Thanks & Regards,
Chirag


Top
 Profile  
 
 Post subject: Re: Update Before Insert
PostPosted: Mon Feb 28, 2011 3:45 am 
Regular
Regular

Joined: Fri Nov 12, 2010 4:13 am
Posts: 81
Location: India
Quote:
Repeated column in mapping for entity: Bar column: ID (should be mapped with insert="false" update="false")


Ya this error comes when you are using ID column twice once in property and other in id column.SO you to specify it with insert=false and update=false.


Quote:
Unable to instantiate default tuplizer [org.hibernate.tuple.entity.PojoEntityTuplizer]


This error comes when your xml mapping file is having some error i.e. parseable error.Result of it maybe you havent close the tag or named any attribute incorrectly.

_________________
Thanks & Regards,
Chirag


Top
 Profile  
 
 Post subject: Re: Update Before Insert
PostPosted: Mon Feb 28, 2011 11:26 am 
Newbie

Joined: Sat Mar 29, 2008 4:49 pm
Posts: 19
chirag.naikec wrote:
How can u assign two values to same column by generator=sequence and one coming from FOO.Instead you create a primary key column with unique name for Bar and ID column will be assigned by primary key of your FOO table.

FOO TABLE :
id (primary key)

BAR TABLE :
barId (primary key)
id (foreign key to table)
..

this will be your table format.And xml mapping i have already given to you.

Is it possible, then, to have the following:
Code:
FOO TABLE:
id (primary key)
barId (foreign key to BAR.id)

BAR TABLE:
id (primary identifier)
idx (index within id)
primary key id, idx

That way, if I had two lists in FOO table, it would just be a second identifier into BAR table. I know this is possible in SQL and is even common practice. How would I set up Hibernate configs to do this (or even my POJOs if it's necessary to change it)?


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