-->
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: Why pre-insert use update command?
PostPosted: Wed Feb 03, 2010 3:23 am 
Newbie

Joined: Wed Feb 03, 2010 3:05 am
Posts: 5
Hi.

Why change of entity properties in pre-insert event listnener is done by update command? Is there any way to do this with only one insert?
Code:
658  [main] DEBUG org.hibernate.SQL  -
    insert
    into
        TestowaEncja
        (createDate, createUser, deleteDate, deleteUser, modifyDate, modifyUser, tekst)
    values
        (?, ?, ?, ?, ?, ?, ?)
658  [main] TRACE org.hibernate.jdbc.AbstractBatcher  - preparing statement
659  [main] TRACE org.hibernate.persister.entity.AbstractEntityPersister  - Dehydrating entity: [pl.naszafirma.model.core.TestowaEncja#<null>]
659  [main] TRACE org.hibernate.type.CalendarType  - binding null to parameter: 1
659  [main] TRACE org.hibernate.type.StringType  - binding null to parameter: 2
659  [main] TRACE org.hibernate.type.CalendarType  - binding null to parameter: 3
659  [main] TRACE org.hibernate.type.StringType  - binding null to parameter: 4
659  [main] TRACE org.hibernate.type.CalendarType  - binding null to parameter: 5
659  [main] TRACE org.hibernate.type.StringType  - binding null to parameter: 6
659  [main] TRACE org.hibernate.type.StringType  - binding 'abc' to parameter: 7
662  [main] DEBUG org.hibernate.id.IdentifierGeneratorFactory  - Natively generated identity: 2
662  [main] DEBUG org.hibernate.jdbc.AbstractBatcher  - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
662  [main] TRACE org.hibernate.jdbc.AbstractBatcher  - closing statement
(...)
669  [main] TRACE org.hibernate.jdbc.ConnectionManager  - registering flush begin
672  [main] TRACE org.hibernate.persister.entity.AbstractEntityPersister  - Updating entity: [pl.naszafirma.model.core.TestowaEncja#2]
672  [main] DEBUG org.hibernate.jdbc.AbstractBatcher  - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
673  [main] DEBUG org.hibernate.SQL  -
    update
        TestowaEncja
    set
        createDate=?,
        createUser=?,
        deleteDate=?,
        deleteUser=?,
        modifyDate=?,
        modifyUser=?,
        tekst=?
    where
        id=?
673  [main] TRACE org.hibernate.jdbc.AbstractBatcher  - preparing statement
673  [main] TRACE org.hibernate.persister.entity.AbstractEntityPersister  - Dehydrating entity: [pl.naszafirma.model.core.TestowaEncja#2]
673  [main] TRACE org.hibernate.type.CalendarType  - binding '2010-02-03 08:15:21' to parameter: 1
673  [main] TRACE org.hibernate.type.StringType  - binding 'user' to parameter: 2
673  [main] TRACE org.hibernate.type.CalendarType  - binding null to parameter: 3
673  [main] TRACE org.hibernate.type.StringType  - binding null to parameter: 4
673  [main] TRACE org.hibernate.type.CalendarType  - binding '2010-02-03 08:15:21' to parameter: 5
673  [main] TRACE org.hibernate.type.StringType  - binding 'user' to parameter: 6
673  [main] TRACE org.hibernate.type.StringType  - binding 'abc' to parameter: 7
673  [main] TRACE org.hibernate.type.LongType  - binding '2' to parameter: 8
673  [main] DEBUG org.hibernate.jdbc.AbstractBatcher  - Executing batch size: 1


Top
 Profile  
 
 Post subject: Re: Why pre-insert use update command?
PostPosted: Wed Feb 03, 2010 3:35 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
Could it be because you are calling session.save() before you are setting the properties of the entity? I recall seeing something similar a long time ago, but I can't find it right now...


Top
 Profile  
 
 Post subject: Re: Why pre-insert use update command?
PostPosted: Wed Feb 03, 2010 3:51 am 
Newbie

Joined: Wed Feb 03, 2010 3:05 am
Posts: 5
I have pre-insert event listener, where I set some properties of entity:
Code:
   public boolean onPreInsert(PreInsertEvent event) {
      if (event.getEntity() instanceof EntityBase) {
         EntityBase entityBase = (EntityBase) event.getEntity();
         addMetadata(entityBase, true, true, false);
      }
      return false;
   }

   private void addMetadata(EntityBase entityBase, boolean create,
         boolean update, boolean delete) {

      EntityMetadata metadata = entityBase.getMetadata();
      Calendar calendar = Calendar.getInstance();

      if (create) {
         metadata.setCreateDate(calendar);
         metadata.setCreateUser("user");

      }

      if (update) {
         metadata.setModifyDate(calendar);
         metadata.setModifyUser("user");
      }

      if (delete) {
         metadata.setDeleteDate(calendar);
         metadata.setDeleteUser("user");
      }
   }


Below is a sample code which I use to create entity:

Code:
      Transaction tx = session.beginTransaction();

      TestowaEncja encja = new TestowaEncja();
      encja.setTekst("abc");
      session.save(encja);

      tx.commit();


I call session.save() after "base" property is set, but before setting properties in pre-insert event. If this is a problem, how can I fix it?


Top
 Profile  
 
 Post subject: Re: Why pre-insert use update command?
PostPosted: Wed Feb 03, 2010 4:31 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
If I recall correctly the issue I remember was only about the order of calling setter methods vs. calling session.save(). There was no event listener involved. But the result is maybe the same... When save() is called, Hibernate takes the current state as the original state and only property values that are set at the time of save() go into the insert statement. Changes made after that are of course detected but they go into an update statement.

When is the event listener called? When you call commit()? It would fit with the above theory... I have no clue what to do to prevent it though.


Top
 Profile  
 
 Post subject: Re: Why pre-insert use update command?
PostPosted: Wed Feb 03, 2010 5:11 am 
Newbie

Joined: Wed Feb 03, 2010 3:05 am
Posts: 5
Event is triggered inside the save method, before the insert command is printed in the log. Update command is printed in the call to commit.

To solve this I can use the save event listener, which correctly generates the insert command with all data, but in this case I do not understand the need for pre-insert event in the Hibernate API.

When updating entity:
Code:
      Transaction tx = session.beginTransaction();
      TestowaEncja encja2 = (TestowaEncja) session.load(TestowaEncja.class, id);
      encja2.setTekst("foo");
      tx.commit();

only pre-update event is called and it works correctly.

I think its weird to use the pre-update event listener for updating entities and save event listener (instead of pre-insert) for creating


Top
 Profile  
 
 Post subject: Re: Why pre-insert use update command?
PostPosted: Wed Feb 03, 2010 5:43 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
I also think it seems a bit strange. If the pre-insert listener is called in the save() method I would have assumed (just as you) that it would be called before the insert sql was generated. I don't know the internals of Hibernate well enough to say if what you are seeing is expected or not. In some cases (depending on which id generator that is used) the insert sql doesn't happen until commit() is called. Maybe the pre-insert listener would work in that scenario, but on the other hand, it seems a bit risky to have different behaviour.

What about the PreInsertEvent.getState() method? In the Interceptor interface there are similar parameters that the documentation clearly says that you can modify and that changes will be propagated both to the database and to the entity. Maybe you can try to change the values in that array. It may be a bit difficult to know which property goes into what array index. In the Interceptor interface there is at least a second parameter with the property names.


Top
 Profile  
 
 Post subject: Re: Why pre-insert use update command?
PostPosted: Wed Feb 03, 2010 7:02 am 
Newbie

Joined: Wed Feb 03, 2010 3:05 am
Posts: 5
nordborg wrote:
... (depending on which id generator that is used) ...

Thanks for the tip :)

The problem is related with strategy of generating ids.

When using @GeneratedValue (strategy = GenerationType.IDENTITY) with PostgreSQL database, ID column is bigserial (for long Java type). When you add records to the database, ID values are automatically generated based on the sequence tablename_id_seq. (I think using MySQL with AUTO_INCREMENT generates a similar problem)

Inside session.save() hibernate assigned ID for the entity. In the case, to get ID, entity must be added to the database.

Changing strategy to sequence solve only insert-update problem. In save method there is only one query for next sequence number and insert command is generated in commit method, but it doesn't contain values set in pre-insert listener.

At this moment a have two options:

1) Use pre-insert with identity id generator and insert-update chain of commands
2) Use save event listener.

I think second option is better :)


Top
 Profile  
 
 Post subject: Re: Why pre-insert use update command?
PostPosted: Wed Feb 03, 2010 7:37 am 
Newbie

Joined: Wed Feb 03, 2010 3:05 am
Posts: 5
I must correct myself: values set in pre-update event listener arent comitted to database :/


Top
 Profile  
 
 Post subject: Re: Why pre-insert use update command?
PostPosted: Sun Nov 21, 2010 5:31 pm 
Newbie

Joined: Tue May 18, 2010 5:39 am
Posts: 19
I had the same problem and was able to solve it using Listeners. I describe this in my blog at http://anshuiitk.blogspot.com/2010/11/h ... event.html . Let me know in case you have any doubts which I can clarify after reading the post.

_________________
AG
http://anshuiitk.blogspot.com


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.