5 Replies Latest reply on Mar 23, 2011 4:18 PM by adamw

    Requesting a collection of ids

    aminmc

      Hi

       

      Not sure if this has been discussed already, so apologies up front, at present I have some code that makes a request for audit history for one entity at a time.  Is it possible to pass in  a collection of ids and get back some kind  of map of id --> collection of audit data?

       

      Any help would be appreciated.

       

      Thanks

        • 1. Requesting a collection of ids
          aminmc

          Hi

           

          I was trying to looking around to see if it's possible to request revision info for a collection of ids for the same entity type.  I checked out the envers source code but could'nt see any tests for this.  I tried this code:

           

               reader.createQuery().forRevisionsOfEntity(Entity.class, false, true).

                                  add(AuditEntity.property("id").in(ids)).getResultList();

           

          But I get a exception:

           

          ava.lang.ClassCastException: java.lang.Long cannot be cast to java.util.Map

                    at org.hibernate.property.MapAccessor$MapGetter.get(MapAccessor.java:118)

                    at org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue(AbstractComponentTuplizer.java:77)

                    at org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValues(AbstractComponentTuplizer.java:83)

           

          Thanks

          • 2. Requesting a collection of ids
            adamw

            I would use a query, that's correct. "id" is a reserved hibernate property for the primary key of the entity, in case of audit entities that is the original id + the revision number. Try "originalId.id" instead.

             

            Adam

            • 3. Re: Requesting a collection of ids
              aminmc

              Hi Adam,

               

              Thanks for your reply.  The originalId.id seems to work.  I did notice something else while debugging and I'm not whether it is just a mapping issue.  Basically I have the following object model:

               

              ContainerObject -->

                 <!-- This is what I want to audit -->

                Set<ContainerObjectData>

               

               

              @Audited

              ContainerObjectData

               

              reference ContainerObject which is not audited using (@NotAudited).

               

              I noticed that when I create 2 containerObjectData i see 2 entries in the revision data (2 adds).  However when i independently update a containerObjectData I notice that there are 4 entries when i do the query.  2 modifications when I only updated one.  Is this correct behaviour?  Here is the full mapping of the objects:

               

               

              @Entity

              @Table(name = "CONTAINER_OBJECT")

              public class ContainerObject {

               

               

                  @Id

                  @GeneratedValue(strategy = GenerationType.AUTO)

                  @Column(name = "ID")

                  private Long id;

               

               

                  @Column(name="OBJECT_ID")

                  private String objectId;

               

               

                  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "belongingTo")

                  private Set<ContainerObjectData> datas = new HashSet<ContainerObjectData>();

               

                   public void add(ContainerObjectData data) {

                      data.setBelongingTo(this);

                      datas.add(data);

                  }

               

              ... rest removed ...    

              }

               

               

               

              @Entity

              @Table(name = "CONTAINER_OBJECT_DATA")

              @Audited

              public class ContainerObjectData {

               

               

                  @Id

                  @GeneratedValue(strategy = GenerationType.AUTO)

                  @Column(name = "ID")

                  private Long id;

               

               

                  @Column(name = "NAME")

                  private String name;

               

               

                  @Column(name = "VALUE")

                  private String value;

               

               

                  @ManyToOne(cascade = CascadeType.ALL)

                  @JoinColumn(name = "OBJECT_CONTAINER_ID")

                  @NotAudited

                  private ContainerObject belongingTo;

               

                   ... getters and setters removed ...

              }

               

              This is my test case (using Spring)

               

               

               

                  @Test

                  public void performTest() {

                      final ContainerObject containerObject = new ContainerObject();

                      containerObject.setObjectId(UUID.randomUUID().toString());

               

               

                      final ContainerObjectData data1 = new ContainerObjectData();

                      data1.setName("NAME");

                      data1.setValue("TEST123");

                      containerObject.add(data1);

               

               

                      final ContainerObjectData data2 = new ContainerObjectData();

                      data2.setName("Account");

                      data2.setValue("RANDOM123");

                      containerObject.add(data2);

               

               

                      transactionTemplate.execute(new TransactionCallbackWithoutResult() {

                          @Override

                          protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {

                              hibernateTemplate.save(containerObject);

               

               

                              hibernateTemplate.flush();

                              hibernateTemplate.clear();

               

               

                          }

                      });

               

               

                      transactionTemplate.execute(new TransactionCallbackWithoutResult() {

                          @Override

                          protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {

                              data1.setValue("NEW_VALUE");

                              hibernateTemplate.update(data1);

               

               

                              hibernateTemplate.flush();

                              hibernateTemplate.clear();

               

               

                          }

                      });

              }

               

              And my query is :

               

              List<List<Object[]>> results = reader.createQuery().forRevisionsOfEntity(ContainerObjectData.class, false, true)

                                      .add(AuditEntity.property("originalId.id").in(ids)).getResultList();

               

              ids are the ids of the objectContainerData entities.  When I debug I see 4 entries in the results container when i expect to see 3 as i updated data1.

               

              Hope this makes sense! I can provide a full project with test if required.

               

               

               

               

              Cheers

              • 4. Re: Requesting a collection of ids
                aminmc

                Hi

                 

                Just an update:

                 

                Not sure what happened but it seems to be working now.  I get the correct revision information. For example if I update ObjectContainerData A twice i get 2 revision info (ADD, MOD) and get one record for ObjectCOntainerData B( ADD).  It's strange that it's working now. I haven't changed the mapping. Somewhat concerned....

                 

                Cheers

                • 5. Re: Requesting a collection of ids
                  adamw

                  Do you have multiple transactions in your test? If it's two txs then you should have two ADDs and one MOD I think.

                   

                  Adam