4 Replies Latest reply on Dec 16, 2010 6:52 AM by rodrigo.uchoa

    Envers + Bulk inserts/updates

      Hi guys,

      I'm facing a situation that i gotta to make decision as soon as possible... The situation is: I have to do bulk insert/update(like 5000 or even more) of many records, the best/fastest way that I figured out was by using jdbc with the addBatch() method. so far so go, I got what I wanted. but by doing that way I would not being inserting in the auditing table right? how could i do this? What I could do is to create 2 PreparedStatement for persist on MyEntityTable and MyEntityTable_AUD....but how could i populate the MyEntityTable_AUD values(as the revisionVersion) to be persisted? any other solution for that? or It Envers would fit on that situation?

      Let me know if ain't clear enough...
      thanks in advance...

      =)

        • 1. Re: Envers + Bulk inserts/updates
          adamw

          Well in this case you need to populate the audit records manually, yes.

           

          Here's what I would do:

          * insert a new row into the revision table, get back the id

          * insert all your records, keeping the ids that were assigned to them

          * insert into the audit table, using the revision number generated and rev type 0, for each row inserted before

           

          Will that work for you?

           

          Adam

          • 2. Re: Envers + Bulk inserts/updates
            rodrigo.uchoa

            Adam,

             

            Is there a way I can insert audited records myself using Hibernate? I've done some research and I noticed  that envers is using Map based dynamic entities.

             

            So I tried something like this:

             

            //--- code

            Session sessionMap = session.getSession(EntityMode.MAP);

             

            Map<String, Object> mapOriginalId = new HashMap<String, Object>();

            mapOriginalId.put("id", new Integer(1));
            mapOriginalId.put("REV", revEntity); //revision entity already persisted

             

            Map<String, Object> mapEntity = new HashMap<String, Object>();
            mapEntity.put("originalId", mapOriginalId);
            mapEntity.put("REVTYPE", RevisionType.ADD);
            mapEntity.put("name", "My area");

             

            sessionMap.save("AUD_com.me.Area", mapEntity);

             

            //end of code

             

             

            My entity has only one property, "name", as you can see above. Anyway, the problem is that I'm getting a ClassCastException. It says my revision entity cannot be cast to Map:

             

            java.lang.ClassCastException: com.me.AudRevisionEntity cannot be cast to java.util.Map
                    at org.hibernate.property.MapAccessor$MapGetter.get(MapAccessor.java:90)
                    at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:206)
                    at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:3619)
                    at org.hibernate.type.EntityType.getHashCode(EntityType.java:310)
                    at org.hibernate.type.ComponentType.getHashCode(ComponentType.java:212)

             

             

            What am I doing wrong?

            • 3. Re: Envers + Bulk inserts/updates
              adamw

              Hmm this looks correct. Maybe if you could breakpoint on AbstractAuditWorkUnit.fillDataWithId, around line 68 and see how the map looks there?

               

              Adam

              • 4. Re: Envers + Bulk inserts/updates
                rodrigo.uchoa

                Thanks again for the help, Adam.

                 

                So, it seems that the exception occurs before getting into AbstractAuditWorkUnit. Heres the full stack trace, the last two bottom entries are mine:

                 

                java.lang.ClassCastException: br.mil.aer.cenipa.cargabasica.HistoricoRevisionEntity cannot be cast to java.util.Map
                        at org.hibernate.property.MapAccessor$MapGetter.get(MapAccessor.java:90)
                        at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:206)
                        at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:3619)
                        at org.hibernate.type.EntityType.getHashCode(EntityType.java:310)
                        at org.hibernate.type.ComponentType.getHashCode(ComponentType.java:212)
                        at org.hibernate.engine.EntityKey.generateHashCode(EntityKey.java:126)
                        at org.hibernate.engine.EntityKey.<init>(EntityKey.java:70)
                        at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:184)
                        at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:144)
                        at org.hibernate.ejb.event.EJB3SaveEventListener.saveWithGeneratedId(EJB3SaveEventListener.java:43)
                        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
                        at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56)
                        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
                        at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50)
                        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
                        at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:562)
                        at org.hibernate.impl.SessionImpl.save(SessionImpl.java:550)
                        at br.mil.aer.cenipa.cargabasica.Test.inserirHistorico(Test.java:123)
                        at br.mil.aer.cenipa.cargabasica.Test.main(Test.java:83)