Announcement Announcement Module
Collapse
No announcement yet.
Routing data sources with AbstractRoutingDataSource Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Routing data sources with AbstractRoutingDataSource

    Hi,

    I've implemented horizontal partioning with Spring's AbstractRoutingDataSource and hibernate. I've used this article as reference:
    http://blog.springsource.com/main/20...ource-routing/

    Although my code is running I've ran into some problems, I've realized that I need a better understanding of the AbstractRoutingDataSource.

    My dao is a HibernateDaoSupport, in my dao I do the following:
    1. assign different values to the CustomerContextHolder
    2. and then usesgetHibernateTemplate().xxx() methods in order to retrieve data.

    My problem is that I've noticed that some times the determineCurrentLookupKey() is not called before the usesgetHibernateTemplate().xxx() methods, meaning I will not get the correct datasource event 1 happaned but since determineCurrentLookupKey() was not called, no ds routing was performed and I did not get the correct ds.

    I've notice that when I call getHibernateTemplate().save() or getHibernateTemplate().get() then determineCurrentLookupKey() is called and I get the correct ds. it does not happen when I call other methods.

    my question is:

    is there a way to force spring to call determineCurrentLookupKey() before moving on to other tasks?


    Thanks in advance,
    lior.

  • #2
    Problem solved, I had to initiate a new transaction after I've set the CustomerContextHolder value. This is not ideal but it works...

    I would love to hear about other solutions

    Comment


    • #3
      Dynamic DB switching

      Hi ,
      Great to hear you have horizontal partitioning using this approach working
      Can you post some code sample for the Hibernate configuration which made this work ?

      Thanks

      r2d2

      Comment


      • #4
        Hi liorbb,
        how did you initiate a new transaction?
        Could you provide some code example?
        I have similar problem. The getHibernateTemplate.saveOrUpdate do not work, it takes the wrong DB. The getHibernateTemplate.find() works.

        Thanks fabatt

        Comment


        • #5
          I'm also interested. Can you give us more insights ?

          Comment


          • #6
            I found a solution for my problem.
            The function getHiberanteTemplate().saveOrUpdateAll() did not work. It didn't save no data in any DB.
            When I save object by object, using getHiberanteTemplate().save() it works!
            Seems to be some bug by using saveOrUpdateAll() with AbstractRoutingDataSource

            regards fabatt

            Comment


            • #7
              Originally posted by fabatt View Post
              I found a solution for my problem.
              The function getHiberanteTemplate().saveOrUpdateAll() did not work. It didn't save no data in any DB.
              When I save object by object, using getHiberanteTemplate().save() it works!
              Seems to be some bug by using saveOrUpdateAll() with AbstractRoutingDataSource

              regards fabatt
              do you have a version field in your object class ?

              If no try to add this filed annotated with @version et try saveOrUpdate again.

              Comment


              • #8
                ramcis, thank you for your reply.
                could you give me more information about this?
                how do I add a object field in my object by annotated, by implementing Serializable and create a serialVersionUID variable?

                I use hibernate xml file to match db and my java class.

                thanks

                Comment


                • #9
                  Ok I added the follwoing to my hbm.xml file:
                  Code:
                  <version name="version" column="VERSION" access="field">
                  and following code to my java class:
                  Code:
                  private Integer version;	/* used for optimistic locking */
                  And a value will be inserted into my VERSION column. For every row is the same value.

                  But now I get an exception. I save the data into my first DB, ok.
                  Then I change DB and want to save the same data into the second db and it makes BUM:
                  Error by saving user data: org.springframework.orm.hibernate3.HibernateOptimi sticLockingFailureException: Object of class [*******.Phonebook] with identifier [51710]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [**********.Phonebook#51710]

                  Comment


                  • #10
                    Hola .. Sólo quiero mirar a su alrededor para aprender más de este furom. Todas las informaciones son muy apreciados
                    Last edited by mark09; Nov 13th, 2009, 12:34 PM.

                    Comment


                    • #11
                      Originally posted by fabatt View Post
                      Ok I added the follwoing to my hbm.xml file:
                      Code:
                      <version name="version" column="VERSION" access="field">
                      and following code to my java class:
                      Code:
                      private Integer version;	/* used for optimistic locking */
                      And a value will be inserted into my VERSION column. For every row is the same value.

                      But now I get an exception. I save the data into my first DB, ok.
                      Then I change DB and want to save the same data into the second db and it makes BUM:
                      Error by saving user data: org.springframework.orm.hibernate3.HibernateOptimi sticLockingFailureException: Object of class [*******.Phonebook] with identifier [51710]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [**********.Phonebook#51710]

                      Can you print the stacktrace ?
                      It seems a problem with cache. How do you switch dataSource ?

                      Comment


                      • #12
                        What a pity. For the next 3 weeks I'm out of office, so I can't post the stacktrace. When I'm back I will do that!
                        I make the dataSource switch like this

                        As told before. By using the getHibernate().find or getHibernate().save it works.
                        By using getHibernate().saveOrUpdateAll it didn't.
                        Befor leaving the office on Friday I had to find a solution. Saving object by object as mentioned in some post before was to slowly!

                        My current workaround works like this:
                        I have a List of Phonebook object called pbList, which I save into 2 different DB.
                        Before I save the pbList I iterate twice over the list for evey DB, and then I create new Phonebook object for evert DB and save them with saveOrUpdateAll.

                        What do you mean with cache? So when I'm back i can going google about this cachin stuff.

                        Thanks again for your help and I will be back in 3 weeks and post you the stacktrace!

                        have a nice time

                        regards fabatt
                        Last edited by fabatt; Nov 15th, 2009, 05:28 AM.

                        Comment


                        • #13
                          hi ramcis,

                          i'm now back into the office.
                          Here is the stacktrace:
                          Code:
                          - ERROR:org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:301) Could not synchronize database state with session
                          org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [....synchronizer.appldb.tables.custom.Phonebook#88058]
                          	at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1765)
                          	at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2407)
                          	at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2307)
                          	at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2607)
                          	at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:92)
                          	at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
                          	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
                          	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140)
                          	at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
                          	at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
                          	at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
                          	at org.springframework.orm.hibernate3.HibernateAccessor.flushIfNecessary(HibernateAccessor.java:390)
                          	at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:420)
                          	at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
                          	at org.springframework.orm.hibernate3.HibernateTemplate.saveOrUpdateAll(HibernateTemplate.java:764)
                          	at ....synchronizer.appldb.dao.PhonebookDBDaoImpl.saveAllPhonebook(PhonebookDBDaoImpl.java:101)
                          	at ....synchronizer.appldb.service.PhonebookServiceImpl.saveAllPhonebook(PhonebookServiceImpl.java:130)
                          	at ....synchronizer.phonebook.planon.PlanonImporter.saveUserData(PlanonImporter.java:648)
                          	at ....synchronizer.phonebook.PhonebookImporter.main(PhonebookImporter.java:118)
                          org.springframework.orm.hibernate3.HibernateOptimisticLockingFailureException: Object of class [....synchronizer.appldb.tables.custom.Phonebook] with identifier [88058]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [....synchronizer.appldb.tables.custom.Phonebook#88058]
                          	at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:654)
                          	at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)
                          	at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:424)
                          	at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
                          	at org.springframework.orm.hibernate3.HibernateTemplate.saveOrUpdateAll(HibernateTemplate.java:764)
                          	at ....synchronizer.appldb.dao.PhonebookDBDaoImpl.saveAllPhonebook(PhonebookDBDaoImpl.java:101)
                          	at ....synchronizer.appldb.service.PhonebookServiceImpl.saveAllPhonebook(PhonebookServiceImpl.java:130)
                          	at ....synchronizer.phonebook.planon.PlanonImporter.saveUserData(PlanonImporter.java:648)
                          	at ....synchronizer.phonebook.PhonebookImporter.main(PhonebookImporter.java:118)
                          Caused by: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [....synchronizer.appldb.tables.custom.Phonebook#88058]
                          	at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1765)
                          	at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2407)
                          	at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2307)
                          	at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2607)
                          	at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:92)
                          	at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
                          	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
                          	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140)
                          	at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
                          	at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
                          	at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
                          	at org.springframework.orm.hibernate3.HibernateAccessor.flushIfNecessary(HibernateAccessor.java:390)
                          	at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:420)
                          	... 6 more
                          - ERROR:....synchronizer.phonebook.planon.PlanonImporter.saveUserData(PlanonImporter.java:653) Error by saving user data: org.springframework.orm.hibernate3.HibernateOptimisticLockingFailureException: Object of class [....synchronizer.appldb.tables.custom.Phonebook] with identifier [88058]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [....synchronizer.appldb.tables.custom.Phonebook#88058]
                          any hint is very welcome!

                          regards fabatt

                          Comment


                          • #14
                            solved!
                            in my opinion it's a bug into hibernate.
                            I have an arraylist which I want save into 2 db's.
                            by saving the first it works. before saving it hibernate takes the value for the filed id from a sequence:
                            Code:
                            		
                            <id name="id" type="int">
                            	<column name="ID" />
                            	<generator class="sequence">
                            	<param name="sequence">PHONEBOOK_ID</param>
                            </generator>
                            </id>
                            and save the data successfully into the correct db and store the id also in the java objects which are in my arraylist.

                            Now I change the datasource and some strange behaviour happens.
                            Hiberante checks if the id stored in the java object exists into the db. for this checks it looks into the first, the WRONG db!
                            Hiberante finds the id's, and now it makes an update in the correct DB??
                            But this second db is empty and nothing happens.

                            my solutioin:
                            After inserting values into the second db, I set all id's into the java objects to 0, and now it works....

                            regards fabatt

                            Comment


                            • #15
                              Originally posted by fabatt View Post
                              solved!
                              in my opinion it's a bug into hibernate.
                              I have an arraylist which I want save into 2 db's.
                              by saving the first it works. before saving it hibernate takes the value for the filed id from a sequence:
                              Code:
                              		
                              <id name="id" type="int">
                              	<column name="ID" />
                              	<generator class="sequence">
                              	<param name="sequence">PHONEBOOK_ID</param>
                              </generator>
                              </id>
                              and save the data successfully into the correct db and store the id also in the java objects which are in my arraylist.

                              Now I change the datasource and some strange behaviour happens.
                              Hiberante checks if the id stored in the java object exists into the db. for this checks it looks into the first, the WRONG db!
                              Hiberante finds the id's, and now it makes an update in the correct DB??
                              But this second db is empty and nothing happens.

                              my solutioin:
                              After inserting values into the second db, I set all id's into the java objects to 0, and now it works....

                              regards fabatt
                              Good to hear that you solved your problem

                              Comment

                              Working...
                              X