8 Replies Latest reply on May 29, 2013 9:43 AM by eduardo.postal

    @OneToMany make revision at insert but not at update

    mehdizehtaban

      I searched the forum but couldn't find out my similar problem. Here is it :

       

      I have an entity Called Person that is the parent of Customer Entity:

       

      @Entity

      @Table(name = "my_person")

      @TableGenerator(name="SEQ_GEN", table = "tbl_seq" , pkColumnName = "seq_name" , pkColumnValue = "my_person", valueColumnName = "seq_value", allocationSize = 50)

      @Audited

      public class MyPerson {

          @Id

          @Column(name = "person_id")

          @GeneratedValue(generator = "SEQ_GEN")

          public Long getPersonId() {

              return personId;

          }

       

          private void setPersonId(Long personId) {

              this.personId = personId;

          }

       

          public String getFirstName() {

              return firstName;

          }

       

          public void setFirstName(String firstName) {

              this.firstName = firstName;

          }

       

          public String getLastName() {

              return lastName;

          }

       

          public void setLastName(String lastName) {

              this.lastName = lastName;

          }

       

          @OneToMany(fetch = FetchType.LAZY, targetEntity = MyCustomer.class, mappedBy = "person"

                  , cascade = {CascadeType.ALL})

          public List<MyCustomer> getCustomers() {

              return customers;

          }

       

          public void setCustomers(List<MyCustomer> customers) {

              this.customers = customers;

          }

       

          @Version

          public Integer getVersion() {

              return version;

          }

       

          public void setVersion(Integer version) {

              this.version = version;

          }

       

          Long personId;

          String firstName;

          String lastName;

          List<MyCustomer> customers;

          Integer version;

      }

       

      And Customer Class :

      package test.envers;

       

      import com.foursun.cymap.common.data.to.PersonTO;

      import com.foursun.util.spring.SpringUtils;

      import org.hibernate.envers.Audited;

      import org.hibernate.envers.ModificationStore;

      import org.hibernate.envers.RelationTargetAuditMode;

       

      import javax.persistence.*;

       

      /**

      * @author Mehdi Zehtaban

      *         Date: May 14, 2011

      *         Time: 1:11:25 PM

      */

      @Entity

      @Table(name = "my_customer")

      @TableGenerator(name="SEQ_GEN", table = "tbl_seq" , pkColumnName = "seq_name" , pkColumnValue = "my_customer", valueColumnName = "seq_value", allocationSize = 50)

      @Audited

      public class MyCustomer {

          @Id

          @Column(name = "customer_id")

          @GeneratedValue(generator = "SEQ_GEN")

          public Long getCustomerId() {

              return customerId;

          }

       

          private void setCustomerId(Long customerId) {

              this.customerId = customerId;

          }

       

          public String getPanel() {

              return panel;

          }

       

          public void setPanel(String panel) {

              this.panel = panel;

          }

       

          @Audited

          @ManyToOne(fetch = FetchType.LAZY, targetEntity = MyPerson.class)

          @JoinColumn(name = "person_id")

          public MyPerson getPerson() {

              return person;

          }

       

          public void setPerson(MyPerson person) {

              this.person = person;

          }

       

          @Transient

          public Long getPersonId() {

              if (this.person != null){

                  return this.person.getPersonId();

              }

              return null;

          }

       

          public void setPersonId(Long personId) {

              if (personId != null){

                  this.person = SpringUtils.getEntityManager().getReference(MyPerson.class, personId);

              }

          }

       

       

          @Version

          public Integer getVersion() {

              return version;

          }

       

          public void setVersion(Integer version) {

              this.version = version;

          }

       

          Long customerId;

          String panel;

          MyPerson person;

          Integer version;

      }

       

      when I create a new instance of Customer a new revision of Person will be inserted in person_aud.

      but when I update a customer envers dont make a revision for Person.

      In some cases I need to make a new revision for parent relation whenever the child relation changed.

      And in some cases I dont need to.

      Is there any way to configure the relations?

        • 1. @OneToMany make revision at insert but not at update
          adamw

          That's because when you add a Customer, the collection in Person changes (a new element is added). If you only modify a Customer, the relation remains the same. This behavior is configurable and can be switched off using a configuration variable.

           

          Adam

          • 2. @OneToMany make revision at insert but not at update
            mehdizehtaban

            Dear Adam

            Thanks for your response. Please take attention that I want to make new revisions in some parent child relations but not in some other cases.

            For example imagine Customer entity and Order Entity and OrderItem.

            I want whenever OrderItems add/remove/update a new version of Order save.

            But whenever an Order add/remove/update dont make a new version of Customer.

            • 3. Re: @OneToMany make revision at insert but not at update
              ste8701

              @Adam,

               

              Dear Adam,

              i have posted a request with a quite similar problem some minutes ago. it is, that the updates made on the n-side are not audited on the 1-side(so just on the n-side as you mentioned)

              so my question is, what do you mean with "configuration variable" and how can i set it up? is there a tutorial where i can read about it?

               

              TIA

               

              Stefan

              • 4. Re: @OneToMany make revision at insert but not at update
                adamw

                The configuration option is not to create a revision for the one-side of the entity if only an entity is added or removed from the relation collection.

                 

                See org.hibernate.envers.revision_on_collection_change in http://docs.jboss.org/hibernate/envers/3.6/reference/en-US/html/configuration.html

                 

                Adam

                • 5. Re: @OneToMany make revision at insert but not at update
                  ste8701

                  Thank you for your answer Adam.

                  i'll try it out.

                  • 6. Re: @OneToMany make revision at insert but not at update
                    asolovey

                    Hi Adam,

                     

                    Is there a feature in the Envers roadmap to allow creating a revision of the one-side entity if there was an update of an element of the related collection attribute? For example, if the book quantity changes a revision of the author is created, where Author owns a list of Books.

                     

                    If there is no such a feature in the roadmap, can you please tell me if the following workaround is a valid and solid choice if I am after the complete list of revisions of Author, including the revisions of attributes of a Book:

                     

                     

                    1. Get the Author's revisions using the following query:

                      AuditQuery query = reader.createQuery().forRevisionsOfEntity(Author.class, false, true).add(AuditEntity.id().eq(authorId));Get

                    2. Get the Books revisions related to the author's ID using the following query:
                      AuditQuery relatedQuery = reader.createQuery().forRevisionsOfEntity(Book.class,false, true).add(AuditEntity.relatedId("author").eq(authorId));

                    3. Add them all to a set removing the duplicate revisions.

                     

                    Will this be a safe and sound way that will be supported by the future releases of Hibernate/Envers?

                     

                    Thanks,

                    Alexander Solovey

                    • 7. Re: @OneToMany make revision at insert but not at update
                      adamw

                      I don't think that feature is on the roadmap, but if you think it's needed, create a JIRA ticket, maybe more people will vote for it as well.

                       

                      Regarding the work-around, looks good!

                       

                      Adam

                      • 8. Re: @OneToMany make revision at insert but not at update
                        eduardo.postal

                        Hi, Adam

                         

                        I am facing exactly the same problem reported by Alexander.

                        Was a JIRA ticket created for this possible new feature? If so, could you please post the link of it?

                        It would be nice to have it on the next versions of Envers.

                         

                        Thanks,

                        Eduardo Postal