-->
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.  [ 8 posts ] 
Author Message
 Post subject: replication problem
PostPosted: Mon Sep 26, 2005 6:47 pm 
Newbie

Joined: Mon Sep 26, 2005 6:34 pm
Posts: 5
Hello,

i'm using hibernate 3.0.5 and try to "copy" data from a main database to clients. i guess replicate() is the right way to do this as it is ment to keep the id and handle existing objects correctly.
sadly, hibernate regenerates ids for objects i add using replicate. shouldn't the following example generate a "Shop" object with id 30 assuming the table is empty before? or am i expecting the wrong result?

Code:
Session session = ... get session from factory...;

// init sample domain object
Shop shop = new Shop();
shop.setId(30);
shop.setName( "Shop 30" );

session.replicate( shop, ReplicateMode.OVERWRITE );

in the real app the domain objects will be transported in serialized form, so the initialization is just for the testing. the id is "native" generated and i tried it with hsql and mysql. the result is always a new object with id 1.
what am i doing wrong?

thanks in advance,
jan kopcsek


Top
 Profile  
 
 Post subject: Re: replication problem
PostPosted: Mon Sep 26, 2005 6:56 pm 
Expert
Expert

Joined: Mon Jul 04, 2005 5:19 pm
Posts: 720
codewright wrote:
the id is "native" generated


what happens when you change this to "assigned" ;)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 26, 2005 8:19 pm 
Newbie

Joined: Mon Sep 26, 2005 6:34 pm
Posts: 5
actually i don't want to have an assigned id, because you are able to add objects as well. isn't it possible to ignore the generator in this case? most identity mechanism can handle a given id, i guess, and just generate when there is a need to do so.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 27, 2005 7:46 am 
Newbie

Joined: Mon Sep 26, 2005 6:34 pm
Posts: 5
the funny thing is, not even "assigned" works. in fact, hibernate won't save anything when i switch the generator to assigned :-/

this seems very strange to me. the mapping is pretty simple, it's looking this way:

Code:
<hibernate-mapping package="my.company.package">
   <class name="Shop" table="shops">
      <id name="id" type="long" unsaved-value="0" column="id">
            <generator class="assigned"/>
      </id>

      <property name="name" type="string">
         <column name="name" length="50"/>
      </property>
   </class>
</hibernate-mapping>


the test case looks pretty much the same as written above plus some assertations of course. is there any chance that some versions will help? not really i guess, as they might make the behaviour better if there is an existing object, but not if there is no object at all.

any advice?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 27, 2005 7:53 am 
Newbie

Joined: Mon Sep 26, 2005 6:34 pm
Posts: 5
thats what the log is saying when using assigned id. i have cut it a little.

Code:
org.hibernate.impl.SessionImpl  - opened session at timestamp: 4619557920124928
org.hibernate.persister.entity.BasicEntityPersister  - Getting version: [my.company.package.Shop#30]
org.hibernate.jdbc.AbstractBatcher  - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
org.hibernate.jdbc.ConnectionManager  - opening JDBC connection
org.hibernate.connection.DriverManagerConnectionProvider  - total checked-out connections: 0
org.hibernate.connection.DriverManagerConnectionProvider  - using pooled JDBC connection, pool size: 0
org.hibernate.SQL  - select id from shops where id =?
org.hibernate.jdbc.AbstractBatcher  - preparing statement
org.hibernate.type.LongType  - binding '30' to parameter: 1
org.hibernate.jdbc.AbstractBatcher  - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
org.hibernate.jdbc.AbstractBatcher  - closing statement
org.hibernate.event.def.DefaultReplicateEventListener  - no existing row, replicating new instance [my.company.package.Shop#30]
org.hibernate.impl.SessionImpl  - closing session
org.hibernate.jdbc.ConnectionManager  - closing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
org.hibernate.connection.DriverManagerConnectionProvider  - returning connection to pool, pool size: 1


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 27, 2005 1:15 pm 
Newbie

Joined: Mon Sep 26, 2005 6:34 pm
Posts: 5
okok, seems like i don't really understand what replicate() is aiming at.

First question: does replicate work with anything else than assigned ids?

if yes, why does it want (according to some comment in the code) to generate new ids in case of native generation for example? how will i ever be able to find the matching entry in the original database? or do i need another unique column if i want an unchanged "id"?

if not (say, it works just with assigned ids), what is it good for? doesn't saveOrUpdate nearly do the same? or merge or something?

i mean, i just want to copy objects from one db to another while preserving the ids and using the same data model (say mappings, which includes a native generator for the id). do i need different mappings for the two locations? what if i want to replicate in a duplex manner?

i would really appreciate some advice here.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 27, 2005 1:24 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
replicate() with identity columns is a kinda fundamentally flowed idea.

(1) there is no good way to ensure pk uniqueness across different databases
(2) on some dbs you can't simply insert an explicit value into an identity column


So use some other identifier strategy if you need to use replicate().


Top
 Profile  
 
 Post subject: Implement a custom ReplicateEventListener
PostPosted: Thu May 25, 2006 5:41 am 
Newbie

Joined: Thu May 25, 2006 5:20 am
Posts: 1
Hello,

I managed to workaround this problem by setting a custom ReplicateEventListener for the operation replicate.

Code:
public class IdPreservingReplicateEventListener extends DefaultReplicateEventListener {

    private static final Log log = LogFactory.getLog(IdPreservingReplicateEventListener.class);

    protected Serializable performSaveOrReplicate(Object entity, EntityKey key, EntityPersister persister, boolean useIdentityColumn, Object anything, EventSource source) throws HibernateException {
        if (key == null) {
            Serializable id = persister.getIdentifier(entity, source.getEntityMode());
            key = new EntityKey(id, persister, source.getEntityMode());
           
            if (log.isDebugEnabled()) {
                log.debug("Replacing null key with entity key (" + key + ") overriding default behavior of DefaultReplicateEventListener");
            }
           
            useIdentityColumn = false;
        }
       
        return super.performSaveOrReplicate(entity, key, persister, useIdentityColumn, anything, source);
    }
}


With the default behavior the key would be null and useIdentityColumn is true. I both generate the key from the copied entity and set useIdentityColumn to false. This does the trick. The ids from the copied entity (which I defined in my mapping document with a native id generator strategy) are preserved and the new entity has the same id in the other datastore.
For replication I use:
Code:
session.replicate(entity, ReplicationMode.OVERWRITE);

The hibernate event system and how to set the custom listener is described in the hibernate reference documentation (version 3.1.3) in chapter 12.2. It can also be set with Spring in the session factory bean.


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