-->
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.  [ 10 posts ] 
Author Message
 Post subject: hibernate with jsf problem
PostPosted: Thu Dec 07, 2006 10:11 am 
Newbie

Joined: Thu Dec 07, 2006 9:48 am
Posts: 18
Hi, I'm coding a simple program that lists and adds book to a table just for practice. Listing works fine, but i cant add book, got a exception and trying to solve it for 3 hours. I'll try to keep this message simple.

Hibernate version: 3.2
I'm using JSF, with a hibernate session control filter. (one session per request)

There are,

a Book class mapped to book table.
Code:
<hibernate-mapping>
    <class name="com.invent.model.Book" table="book" catalog="test">
        <id name="id" type="java.lang.Integer">
            <column name="ID" />
            <generator class="increment" />
        </id>
        <property name="author" type="java.lang.String">
            <column name="Author" length="25" />
        </property>
        <property name="title" type="java.lang.String">
            <column name="Title" length="25" />
        </property>
        <property name="available" type="java.lang.Boolean">
            <column name="Available" />
        </property>
    </class>
</hibernate-mapping>


a BookDelegate to list / add . (managed bean, request scope)
Code:
public class BookDelegate
{

   private long id;
   private String author;
   private String title;
   private boolean available;

   .. getters/setters..

   public Collection getBooks()
   {
      Session session = HibSessionFilter.getSession();
      return session.createQuery("from Book").list();
   }

   public void addBook(ActionEvent event)
   {
      Session session = HibSessionFilter.getSession();
   try
   {
      session.saveOrUpdate(new Book(this.id, this.author, this.title, this.available));
      session.flush();
   } catch (Exception e)
   {
      System.out.println(e.getMessage());
   }
   }
}


a editBook.jsf to add books.
Code:
<h:form>
   <h:panelGrid columns="2" border="1">
   <h:outputText value="Author:" />
   <h:inputText id="author" value="#{BookDelegate.author}" />
   <h:outputText value="Title:" />
   <h:inputText id="title" value="#{BookDelegate.title}" />
   <h:outputText value="Available:" />
   <h:selectBooleanCheckbox id="available"   value="#{BookDelegate.available}" />
   </h:panelGrid>

   <h:commandButton value="Save" action="listBooks" actionListener="#{BookDelegate.addBook}" />
         
</h:form>


There are 2 records in DB. The next ID will be 3. When BookDelegate.addBook executed,

Exception:
identifier of an instance of com.invent.model.Book was altered from 3 to 3

exception occurs. If I try adding another book I got,

identifier of an instance of com.invent.model.Book was altered from 4 to 4

... (No record inserted to table, max(ID) of table is still 2.)

The generated SQL (show_sql=true):
Hibernate: select max(ID) from book

Name and version of the database you are using:
Mysql 5.1


Any help will be greatly appreaciated.

- GB


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 07, 2006 10:55 am 
Expert
Expert

Joined: Tue Jul 11, 2006 10:21 am
Posts: 457
Location: Columbus, Ohio
Never explicitly set the identifier of a POJO unless you set generator="assigned". Leave the identifier in the default state (unsaved-value) and Hibernate will fetch the next identifier at the appropriate time. It does not even matter if you change the identifier to the same value, Hibernate will still detect that as a change and throw the exception that you got.
Code:
session.saveOrUpdate(new Book(this.id, this.author, this.title, this.available));


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 07, 2006 11:10 am 
Newbie

Joined: Thu Dec 07, 2006 9:48 am
Posts: 18
Ananasi wrote:
Never explicitly set the identifier of a POJO unless you set generator="assigned". Leave the identifier in the default state (unsaved-value) and Hibernate will fetch the next identifier at the appropriate time. It does not even matter if you change the identifier to the same value, Hibernate will still detect that as a change and throw the exception that you got.
Code:
session.saveOrUpdate(new Book(this.id, this.author, this.title, this.available));


Thanks for the reply,but unfortunatelly, I have already tried with other constructor:
Code:
session.saveOrUpdate(new Book(this.author, this.title, this.available));


and it causes same exception. The really weird thing is, Book.setID is called only one time, during a request-response. Thats the output:

Code:
Hibernate: select max(ID) from book
>> setID executed <<
identifier of an instance of com.invent.model.Book was altered from 3 to 3


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 07, 2006 11:26 am 
Expert
Expert

Joined: Tue Jul 11, 2006 10:21 am
Posts: 457
Location: Columbus, Ohio
Book.setId should be called zero times using an increment generator. The only one who should be calling setId is Hibernate itself when it hydrates the POJO from the database and after it persists. So that's kind of odd. Lemme look at your mapping files again and I'll see what I can see.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 07, 2006 11:30 am 
Expert
Expert

Joined: Tue Jul 11, 2006 10:21 am
Posts: 457
Location: Columbus, Ohio
Can you post the Book POJO please. That would help.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 07, 2006 11:49 am 
Newbie

Joined: Thu Dec 07, 2006 9:48 am
Posts: 18
Ananasi wrote:
Quote:
Book.setId should be called zero times using an increment generator. The only one who should be calling setId is Hibernate itself when it hydrates the POJO from the database and after it persists.


I'think that's exactly what you said,

Code:
Hibernate: select max(ID) from book
>> setID executed ID set to 3
identifier of an instance of com.invent.model.Book was altered from 3 to 3


setID only called one time, after hibernate selects max ID..

thats book.java

Code:
   private long id;
   private String author;
   private String title;
   private boolean available;

   public Book()
   {
   }
   public Book(long id, String author, String title, boolean available)
   {
      this.id = id;
      this.author = author;
      this.title = title;
      this.available = available;
   }
   public Book(String author, String title, boolean available)
   {
      this.author = author;
      this.title = title;
      this.available = available;
   }

   public String getAuthor()
   {
      return author;
   }
   public void setAuthor(String author)
   {
      this.author = author;
   }
   public boolean getAvailable()
   {
      return available;
   }
   public void setAvailable(boolean available)
   {
      this.available = available;
   }
   public long getId()
   {
      return id;
   }
   public void setId(long id)
   {
      this.id = id;
      System.out.println(">> setID executed ID set to " + Integer.toString((int)this.id));
      
   }
   public String getTitle()
   {
      return title;
   }
   public void setTitle(String title)
   {
      this.title = title;
   }


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 07, 2006 11:51 am 
Newbie

Joined: Thu Dec 07, 2006 9:48 am
Posts: 18
.. duplicate message .. sorry my connection sucked.


Last edited by GBerberoglu on Thu Dec 07, 2006 1:53 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 07, 2006 12:13 pm 
Expert
Expert

Joined: Tue Jul 11, 2006 10:21 am
Posts: 457
Location: Columbus, Ohio
Hmm...your mapping file has
Code:
<id name="id" type="java.lang.Integer">
, yet your POJO has
Code:
private long id;

Try changing the POJO to
Code:
private Integer id;

If you are using Java5, the culprit may be boxing/unboxing. Besides, identifiers should generally be Serializable, makes things easier down the road.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 07, 2006 4:23 pm 
Newbie

Joined: Thu Dec 07, 2006 9:48 am
Posts: 18
Ananasi wrote:
Hmm...your mapping file has
Code:
<id name="id" type="java.lang.Integer">
, yet your POJO has
Code:
private long id;

Try changing the POJO to
Code:
private Integer id;

If you are using Java5, the culprit may be boxing/unboxing. Besides, identifiers should generally be Serializable, makes things easier down the road.



Thanks a million!!! OMG i've lost 3 hours because of a type problem!


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 07, 2006 4:54 pm 
Expert
Expert

Joined: Tue Jul 11, 2006 10:21 am
Posts: 457
Location: Columbus, Ohio
Sometimes it just takes a fresh set of eyeballs. ;)


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