Announcement Announcement Module
Collapse
No announcement yet.
Issues with iBatis SqlMapClientDaoSupport and spring:aop Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Issues with iBatis SqlMapClientDaoSupport and spring:aop

    I seem to be having issues with any iBatis DAO object and the SqlMapClientDaoSupport. Anytime that I try to apply an aspect to the implementation class it will throw a VerifyError saying:

    Code:
    java.lang.VerifyError: (class: MyDAOImpl$$FastClassByCGLIB$$1b1b5a56, method: invoke signature: (ILjava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;) Incompatible object argument for function call
    	at java.lang.Class.getDeclaredConstructors0(Native Method)
    	at java.lang.Class.privateGetDeclaredConstructors(Class.java:2389)
    	at java.lang.Class.getConstructor0(Class.java:2699)
    	at java.lang.Class.getDeclaredConstructor(Class.java:1985)
    	at net.sf.cglib.core.ReflectUtils.getConstructor(ReflectUtils.java:244)
    	at net.sf.cglib.core.ReflectUtils.newInstance(ReflectUtils.java:220)
    	at net.sf.cglib.reflect.FastClass$Generator.firstInstance(FastClass.java:76)
    ....
    While this happens on any AOP injection, including just performance monitoring type stuff, the Spring AOP for Tx defined as:
    Code:
        <tx:jta-transaction-manager/> 
        <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
        
        <tx:advice id="ibatisAutoTxAdvice" transaction-manager="transactionManager">
        	<tx:attributes>
        		<tx:method name="count*"  read-only="true" propagation="REQUIRED" rollback-for="my.package.structure.CustomRollbackException" />
        		<tx:method name="select*" read-only="true" propagation="REQUIRED" rollback-for="my.package.structure.CustomRollbackException" />
        		<tx:method name="insert*" propagation="REQUIRED" rollback-for="my.package.structure.CustomRollbackException" />
        		<tx:method name="update*" propagation="REQUIRED" rollback-for="my.package.structure.CustomRollbackException" />
        	</tx:attributes>
        </tx:advice>
    
        <aop:config proxy-target-class="true">
            <aop:pointcut id="ibatisAutoCode"      			
                          expression="execution(* my.package.structure.MyDAOImpl.*(..))"/>
            <aop:advisor pointcut-ref="ibatisAutoCode" advice-ref="ibatisAutoTxAdvice"/>
        </aop:config>
    After several hours of googling to somewhere to go next, I'm pretty much stuck. This seems to happen when the bean definition gets invoked:
    Code:
     
       <bean id="MyDAO" class="my.package.structure.MyDAOImpl"
            p:sqlMapClient-ref="autoGenSQLMap" />
    Removing the aspect causes everything to start up and run properly, except that the transaction management from higher level callers isn't honored and so things don't rollback correctly.


    Anyone have any ideas about the VerifyErrors and spring:aop on these iBatis objects? I saw a number of posts that looked like it was working for other people, but following that nothing seemed to work on either of the development machines I was using.
    Last edited by res; Jul 19th, 2009, 12:45 AM.

  • #2
    First off all why are you using 2 different ways of driving transactions? You have the tx:annotation driven AND an aop:config block, I would start by removing one of those.

    How are you applying the aspects because that is a part that is absent from your code samples.

    Comment


    • #3
      Originally posted by Marten Deinum View Post
      First off all why are you using 2 different ways of driving transactions? You have the tx:annotation driven AND an aop:config block, I would start by removing one of those.
      Actually have tried that too; however explaining the why is fairly straight forward. The aspects are being applied to the iBator generated code but the parts I'm writing myself use the annotation tags. I didn't want to go in and modify all the generated code with annotation tags in the event that I made changes and needed to regenerate them. So the two don't overlap - the package structure where the aspects are being applied don't have any annotations.

      Transactions really aren't the heart of the issue, though I am having an issue with those in particular here. Any aspects applied to these objects fail later when you try to create a spring bean out of them.


      Originally posted by Marten Deinum View Post
      How are you applying the aspects because that is a part that is absent from your code samples.
      I'm not sure I understand your question. It's using spring's AOP and not anything directly. The relevant aop:config and tx:advice sections for the aspects are in the second block above. I just changed things a little to remove my package structure. BTW - I do know that the way the example above is written that the aspect is applied to only one class. I did that during my troubleshooting to narrow down things to a workable example, but the same error gets repeated regardless of bean involved.

      This is all on JBoss and the underlying DB is mysql (InnoDB); however I'm considering on the specific transaction issue to try another DB. I've converted to the InnoDB engine and from the command line transactions are working. Even if that is the issue I'd like to apply profiling to the DB calls so this is still an issue for me.

      If that didn't address your question, can you help me understand more specifically what you're looking for in terms of how the aspect is applied? I could post code of one of the beans, but it's nothing special as this is just the code which iBator generates. The only particularly unique thing is their inheritance structure and the extension of SqlMapClientDaoSupport.


      Thanks for the help.
      Last edited by res; Jul 19th, 2009, 09:11 AM.

      Comment


      • #4
        Your description doesn't really make it clearer for me also I don't have any clue if the generated code is suitable/fit for using spring (my experiences with generated code aren't that good ).

        You mention you have issues with other aspects but here you only show the transaction stuff not any other aspect you ( are trying to) apply. That is what I was asking for how do you apply those additional aspects.

        Next to that I really suggest you go for 1 transaction strategy in your case that would be to drop the annotations. This already removes one cause for generating double proxies.

        Comment


        • #5
          BTW - This also goes away when I remove the interface from the iBatis object.

          i.e., Normally the pattern applied with iBatis is the following:
          Code:
          public class MyDAOImpl extends SqlMapClientDaoSupport implements MyDAO
          Whenever I apply an aspect to this and then try to create a spring bean (like the one in the initial post, 3rd close block) it throws the VerifyError. I just found that when I remote the interface from the implements section that it will also work with all the aspect related code I have above.

          Is there a different pattern I should be following here for iBatis? Perhaps this is more of an object which implements any interface problem with aspects than it is with this code. iBatis just brings it out because they implement a suitable pattern to trigger the condition.

          Comment


          • #6
            You are using class proxying you might try to disable that, it can be that there is something else that is creating an interface based proxy also....

            Comment


            • #7
              Originally posted by Marten Deinum View Post
              Your description doesn't really make it clearer for me also I don't have any clue if the generated code is suitable/fit for using spring (my experiences with generated code aren't that good ).

              You mention you have issues with other aspects but here you only show the transaction stuff not any other aspect you ( are trying to) apply. That is what I was asking for how do you apply those additional aspects.

              Next to that I really suggest you go for 1 transaction strategy in your case that would be to drop the annotations. This already removes one cause for generating double proxies.
              I understand now I think. There is no other aspect trying to be applied. In the past when I tried to apply a performance based aspect such as this:
              Code:
                 <aop:config>
                    <aop:aspect id="performanceLogAspect"
                                ref="services_PerformanceTimer">
                       <aop:pointcut id="servicesMethods" expression="execution(* services..*(..))" />
                       <aop:around pointcut-ref="servicesMethods" method="profile"/>
                    </aop:aspect>
                 </aop:config>
              I also had issues, but only with the iBatis code.

              As for suitability - it follows the same pattern as the rest of this code. To be honest, there really isn't much in there - it's just the example class declaration I provided a minute ago and contains blocks like:
              Code:
              	public int countByExample(MyExample example) {
              		Integer count = (Integer) getSqlMapClientTemplate().queryForObject(
              				"MyTable.ibatorgenerated_countByExample", example);
              		return count;
              	}
              Where MyExample is just a POJO with a few parameters. To be clear, this also happens on my own code as long as it extends SqlMapClientDaoSupport and implements anything.

              Comment


              • #8
                Originally posted by Marten Deinum View Post
                You are using class proxying you might try to disable that, it can be that there is something else that is creating an interface based proxy also....
                Tried to disable via removing proxy-target-class="false". Same result. Also deleted the tx:annotation and initially it looks like it might have started up alright this time.

                I added back in the tx:annotation but also put proxy-target-class="false" and everything started up fine. So apparently there is some spillover


                Edit: Confirmed that this is working. For some reason when you specify the proxy-target-class with the annotations it spills over into the standard aop:spring pointcut as well. So even though I'm not using annotations in the affected classes, if you try to use that flag with annotations it will affect the system in such a fashion as to cause the VerifyError failue.

                So ultimately the solution was to change:
                Code:
                 <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
                ...
                 <aop:config proxy-target-class="true">
                ...
                to

                Code:
                 <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="false"/>
                ...
                 <aop:config>
                ...
                Last edited by res; Jul 19th, 2009, 02:07 PM.

                Comment

                Working...
                X