0 Replies Latest reply on Mar 30, 2011 11:43 AM by boban_jboss

    Envers returns all revisions of entity <= reqested revision number in ManyToMany relation

    boban_jboss

      Hi,

       

      it's difficult to explain and my english is soooo bad ...

      I have 2(3) entities, one of them are joined over inheritance. The entities FileResource and StorageNode are joined over a ManyToMany relation. Revisioning and other hibernate things are working well, only thing is not working like expected is get StorageNodes of FileResource with specified revision. Envers always return all StorageNodes.REV <= requested revision number? Should it not return only StorageNodes with requested REV? .

       

      I'm using hibernate 3.6.2 and FileResource has 3 revisions

       

      To load a FileResource with id 2 and revison 4 i do:

      Resource resource = AuditReaderFactory.get(sessionFactory.getCurrentSession()).find(ResourceImpl.class, 2, 4);

      it works like expected, i get the resource with specified revision. To get StorgeNodes of this loaded FileResouce revision i do:

      List<StorageNode> storageNodes = resource.getStorageNodes();
      

      This call returns this StorageNodes:

      sn_test_name (rev 1)
      sn2_test_name (rev 3)
      sn3_test_name (rev 4)
      

      The loaded FileResource 2 with revision 4 is only referenced by sn3_test_name (rev 4) StorageNode. Why envers returns here all revisions? Is it maybe a bug?

       

      Here is an Example of my code and database entries:

       

      @Audited
      @Entity(name = "resource")
      @Inheritance(strategy = InheritanceType.JOINED)
      @SequenceGenerator(    name = "resourceIdSequence", sequenceName = "resource_id_seq",
          allocationSize = 1
      )
      public class ResourceImpl
      implements Resource
      {
          private static final long serialVersionUID = -5852061235776305002L;
      
          @Id
          @GeneratedValue(generator = "resourceIdSequence",
              strategy = GenerationType.SEQUENCE)
          @Column(nullable = false)
          protected long id;
      
          @Column(nullable = false)
          protected String uuid = UuidGenerator.createUuid();
      
          @NotAudited
          protected String name;
      
          @Temporal(TemporalType.TIMESTAMP)
          protected Date time;
      
          protected String author;
      
          @NotAudited
          protected String path;
      
          @NotAudited
          @ManyToOne(targetEntity = ResourceImpl.class, fetch = FetchType.EAGER)
          @JoinColumn(name = "parent_id")
          protected Resource parent;
      
          @NotAudited
          @OneToMany(targetEntity = ResourceImpl.class, mappedBy = "parent",
                     fetch = FetchType.LAZY, orphanRemoval = true)
          protected List<Resource> children;
      
          @NotAudited
          @ManyToOne(targetEntity = NamespaceImpl.class, fetch = FetchType.EAGER)
          @JoinColumn(name = "namespace_id")
          protected Namespace namespace;
      
          @NotAudited
          @OneToOne(targetEntity = LockInfoImpl.class, mappedBy = "resource",
                    orphanRemoval = true)
          protected LockInfo lockInfo;
      
          @NotAudited
          @OneToMany(targetEntity = ResourcePropertyImpl.class, mappedBy = "resource",
                     fetch = FetchType.LAZY, orphanRemoval = true)
          protected List<ResourceProperty> properties;
      
          ... getter setter
      }
      

       

      @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
      @Entity(name = "fileresource")
      @Table(name = "file_resource")
      @PrimaryKeyJoinColumn(name = "resource_id")
      public class FileResourceImplextends ResourceImpl
      implements FileResource
      {
          private static final long serialVersionUID = -3576586818372426631L;
      
          private long size;
      
          private String hash;
      
          @NotAudited
          private boolean expired = false;
      
          @ManyToMany(targetEntity = StorageNodeImpl.class, fetch = FetchType.LAZY)
          @JoinTable(name = "stored_resource",
                     joinColumns = @JoinColumn(name = "resource_id"),
                     inverseJoinColumns = @JoinColumn(name = "storagenode_name")
          )
          private List<StorageNode> storageNodes;
      
          ... getter setter
      }
      

       

      @Entity(name = "storagenode")
      @Table(name = "storage_node")
      public class StorageNodeImpl implements StorageNode{
          private static final long serialVersionUID = 2321859209769972438L;
      
          @Id
          @Column(nullable = false)
          private String name;
      
          private int port = 80;
      
          @Enumerated(EnumType.STRING)
          private StorageNode.Status status;
      
          @Column(nullable=false)
          private long capacity;
      
          @Column(name = "free_capacity", nullable = false)
          private long freeCapacity = 0;
      
          @Temporal(TemporalType.TIMESTAMP)
          @Column(name = "last_capacity_check")
          private Date lastCapacityCheck;
      
          @Column(name = "mount_point", length = 512, nullable = false)
          private String mountPoint = "/opt/archive";
      
          @ManyToMany(targetEntity = FileResourceImpl.class,
                      mappedBy = "storageNodes", fetch = FetchType.LAZY)
          private List<FileResource> fileResources;
      
          @NotAudited
          @OneToMany(targetEntity = ReservationImpl.class,
                     mappedBy = "storageNode", fetch = FetchType.LAZY)
          private List<Reservation> reservations;
      
          ... getter setter
      }
      

       

      Table revison_entity:

       id | author |   timestamp   | expired 
      ----+--------+---------------+---------
        1 | CADN   | 1301489501186 | f
        2 | CADN   | 1301490327329 | f
        3 | CADN   | 1301491018255 | f
        4 | CADN   | 1301491591750 | f
      

       

      Table resource_aud:

       id | rev | revtype | author |        time         |               uuid               
      ----+-----+---------+--------+---------------------+----------------------------------
        1 |   1 |       0 | Author | 2010-09-01 00:00:00 | 0dc9b45bd4444890a3bb6880988175ef
        2 |   1 |       0 | Author | 2010-09-01 00:00:00 | 33701ac5938d46c188b633381436560a
        2 |   2 |       1 | Boban  | 2010-09-01 00:00:00 | 33701ac5938d46c188b633381436560a
        2 |   3 |       1 | Boban  | 2010-09-01 00:00:00 | 33701ac5938d46c188b633381436560a
        2 |   4 |       1 | Boban  |                     | uiuiuiuiuiuiuiuiuiu
      

       

      Table file_resource_aud:

       resource_id | rev | hash | size 
      -------------+-----+------+------
                 2 |   1 |      |    0
                 2 |   2 |      | 1111
                 2 |   3 |      | 1111
                 2 |   4 |      | 1111
      

       

      Table stored_resource_aud (the join table resource <-> storage_node):

       rev | resource_id | storagenode_name | revtype 
      -----+-------------+------------------+---------
         1 |           2 | sn_test_name     |       0
         3 |           2 | sn2_test_name    |       0
         4 |           2 | sn3_test_name    |       0
      

       

      Table storage_node:

           name      | port |  capacity  | status | free_capacity |    last_capacity_check     | mount_point  
      ---------------+------+------------+--------+---------------+----------------------------+--------------
       sn_test_name  |   80 | 1073741824 | ACTIVE |             0 |                            | /opt/archive
       sn2_test_name |   80 |   10000000 | ACTIVE |           333 | 2011-03-30 15:01:47.18339  | /opt/archive
       sn3_test_name |   80 |   10000000 | ACTIVE |           444 | 2011-03-30 15:25:51.784414 | /opt/archive