0 Replies Latest reply on Feb 27, 2007 1:04 AM by Josh Male

    Entity Callbacks for collection attributes

    Josh Male Newbie

      Hi,

      we use JBoss AS 4.0.4 in clustered mode with the EJB3 container configured.

      For JAAS, we store users, roles etc in a MySQL database and configure this in the login-config.xml file as normal.

      We also allow a client application to modify users, user groups and the roles to which they are assigned. To facilitate this, we use the EJB3 JPA layer to map the database tables to "entities", these being 'User', 'UserGroup' and 'Role'.

      Each of these entities has their own independent lifecycle. There is a bidirectional many-to-many relationship between 'User' and 'UserGroup' with 'User' being the owning side (see the snippet below):

      @ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.EAGER)
       @JoinTable(name = "UserToUserGroupMap",
       joinColumns = {@JoinColumn(name = "principalFK")},
       inverseJoinColumns = {@JoinColumn(name = "groupFK")})
       @Cache (usage=CacheConcurrencyStrategy.TRANSACTIONAL)
       public Set<UserGroup> getUserGroups()
       {
       return this.userGroups;
       }


      There is a unidirectional many-to-many relationship between 'UserGroup' and 'Role'(see the snippet below):

      @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.EAGER)
       @JoinTable(name = "UserGroupToRoleMap",
       joinColumns = {@JoinColumn(name = "groupFK")},
       inverseJoinColumns = {@JoinColumn(name = "roleFK")})
       @Cache (usage=CacheConcurrencyStrategy.TRANSACTIONAL)
       public Set<Role> getRoles()
       {
       return this.roles;
       }


      When a client/transaction updates on of these entity instances, we want to capture that event so that the other clients can be notified of the update. To achieve this we wanted to use the JPA entity callback mechanism. For each of the above entities, we added a callback such as:
      @PostUpdate
      void notifyObserversOfEntityUpdate()
      {
       // notify observers (performed asychronously using JMS)
      }


      It seems as though this callback is executed whenever a normal entity attribute is modified. It does not seem to be called if one of the many-to-many associations detailed above is modified however.

      At this point, I turned on hibernate TRACE level logging and noticed that collection attribute changes seem to be treated differently to non-collection attrubte changes. If one of the many-to-many collection attributes is modified, I see the following logs (please ignore the insertion as that is for another unrelated entity but still part of the same transaction):

      2007-02-22 10:39:55,274 TRACE [org.hibernate.event.def.AbstractFlushingEventListener] Scheduling collection removes/(re)creates/updates
      2007-02-22 10:39:55,276 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] Flushed: 1 insertions, 0 updates, 0 deletions to 4 objects
      2007-02-22 10:39:55,276 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] Flushed: 1 (re)creations, 0 updates, 1 removals to 4 collections

      However, if a non-collection attribute is modified, I see logs such as the following (please ignore the insertion as that is for another unrelated entity but still part of the same transaction):

      2007-02-22 13:23:23,051 TRACE [org.hibernate.event.def.AbstractFlushingEventListener] Scheduling collection removes/(re)creates/updates
      2007-02-22 13:23:23,051 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] Flushed: 1 insertions, 1 updates, 0 deletions to 4 objects
      2007-02-22 13:23:23,051 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] Flushed: 0 (re)creations, 0 updates, 0 removals to 4 collections


      What I would like to know is whether this is by design or whether it is a bug. If it is by design, then is there a way using JPA that I can get callbacks when collections change. Or, do I have to use a Hibernate specific interceptor or something?

      Thanks a lot...
      Josh