Announcement Announcement Module
Collapse
No announcement yet.
JdkDynamicAopProxy overwrites equals() Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • JdkDynamicAopProxy overwrites equals()

    First, thanks everybody for that springframework.
    I am converting an old project to test AOP, and stumbled about an error enhancing my POJOs. I tried to build lazy-loading and caching aspects and overwrote equals() and hashCode(). But JdkDynamicAopProxy overwrites equals() as well (to compare it to other JdkDynamicAopProxy) thus breaking the POJOs.
    To me the question is wether it is necessary to overwrite equals while passing through hashCode(), toString(), etc.. It breaks existing code and results in strange behaviour with Maps, e.g. two keys(Proxies) are not equal() but might return the same value(via the proxied.hashCode()).
    Or is there a thing i missed (besides rewriting my code :wink: )

  • #2
    Equality is deemed to be meet object and all advisors equal. That is the same target object with different advice will not be considered equal. If your advisors/advice are a shared instance or equal, equal should behave as you expect. If it doesn't, please give a simple example.

    Comment


    • #3
      Proxy example

      Thank you for your fast reply, i will try to give a short example. (By the way, i am a newbie to AOP :wink: )

      Let's say i have a database with cars and persons. Every car has an owner (person), and maybe other relations. So when i load a car from the database, i do not query for the complete owner but create an OwnerProxy just filled with its ID. When an owner method other than getId (or related, like hashCode(), equals()) is invoked, the object reconnects to the database and fills up the remainding values.
      So, there are arbitrary OwnerProxies enclosing the same owner-entity. Do two cars belong to the same owner? car1.getOwner().equals(car2.getOwner()) works for the ID, not the OwnerProxy, because every query creates a new prototype of the OwnerProxy.


      Code:
        <!-- Advisor pointcut definition for before advice   -->
         <bean id="proxyBeforeAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor" singleton="false">
            <property name="pattern"><value>.*</value></property>
            <property name="advice"><ref local="proxyBeforeAdvice"/></property>
         </bean>
      
         <!-- Advice classes -->
         <bean id="proxyBeforeAdvice" class="test.advice.proxying.ProxyBeforeAdvice" singleton="false"/>
      
        <bean id="owner" class="org.springframework.aop.framework.ProxyFactoryBean">
         	<property name="proxyInterfaces"><value>test.Owner</value></property>
              <property name="singleton"><value>false</value></property>
              <property name="interceptorNames">
                  <list>
                  	<value>proxyBeforeAdvisor</value>
      	        <value>_owner</value>
                  </list>
              </property>
         </bean>
      
         <bean id="_owner" class="test.OwnerImpl" singleton="false" />
      All Objects, advisors and advice are prototypes, because I mix 'loaded ' state into the owner:
      Code:
      public class ProxyBeforeAdvice
          implements MethodBeforeAdvice &#123;
      
          public ProxyBeforeAdvice&#40;&#41; &#123;
          &#125;
      
          private boolean loaded = false;
      
          public void before&#40;Method method, Object&#91;&#93; attributes, Object target&#41; throws Throwable &#123;
              String name = method.getName&#40;&#41;;
              if &#40;"getId".equals&#40;name&#41;&#41; &#123;
      		// no need to reload
              &#125;
      	....
      	&#125;
      	else if &#40;!loaded&#41; &#123;
                  	reconnect&#40;&#40;Entity&#41;target&#41;;
              &#125;
         &#125;

      Comment

      Working...
      X