Help Writing MyBatis Generator PluginAdatper

879 views
Skip to first unread message

Daniel Wilkerson

unread,
Mar 26, 2015, 11:39:54 AM3/26/15
to mybati...@googlegroups.com
Hi all. I posted this earlier but after clicking post it disappeared. If this has shown up twice, I apologize.

We use MyBatis Generator to generate MyBatis artifacts for one our our databases. I am working on a new version of our code that uses camel and bindy to improve things. I'm basically looking to markup our existing MyBatis model classes with Bindy annotations and preserve them between regenerating the files.

Do any of you know of a plugin that already exists that performs this? If not, I would need some guidance on implementing my own PluginAdapter subclass to build in this capability.

I've read through the MBG page on implementing plugins and get the general idea, but there are a lot of details that are fuzzy. I'm using JBoss Developer Studio 7.1 (basically Eclipse) and have migrated the new project to using a Maven build (v 3.0.4 runtime and the M2 Eclipse plugin). Previously our process was to "right click" on the generator config file and use the context menu item in Package Explorer to execute MGB. With this new version I'm looking to move away from that completely and use Maven to run MBG almost exclusively...Although, I'd still like to have the menu option available if needed.

I pulled the MBG source from git and see the following projects:

mybatis-generator-core
mybatis-generator-maven-plugin
mybatis-generator-systests-common
mybatis-generator-systests-ibatis2-java2
mybatis-generator-systests-ibatis2-java5
mybatis-generator-systests-mybatis3

Do I need to add all of these to Eclipse in order to code/build/test my PluginAdapter? Is there a simpler way to do it? Also, once I've built a working PluginAdapter, how do I deploy it so it is included into Eclipse like the version I'm using? Basically, I don't want to change my development workflow to something convoluted in order to build in this functionality.

I only want to override the methods needed that pertain to managing the model generation. I don't want to muck around with the SQL Mappers, XML files and such. Only preserve annotations between runs. Ideally I'd like to configure the custom annotations in the generator config and have them added to the model class fields when the generator is run.

I hope I did an OK job of explaining all that. Any help from an experienced Plugin writer would be amazing.

Thanks in advance!

Daniel



Steve Hill

unread,
Mar 26, 2015, 2:42:24 PM3/26/15
to mybati...@googlegroups.com
Daniel:

I would recommend looking at some of the samples - they are called out on this page. http://mybatis.github.io/generator/reference/plugins.html

Adding plugin's is very simple.  We have a number that perform special operations and add special methods to the generated mapper files.  From Eclipse; as long as you have the core generator libraries you should have everything you need to create a plugin.

Once the plugin is created you add it to the mybatis generator xml file under the "context" element and it will fire.  The syntax looks like the following.

        <plugin type="com.xxx.xxx.mybatis.VirtualPrimaryKeyPlugin"/>

When we first started development we added breakpoints until we understood how the code was flowing.

Thanks!
Steve.
--
You received this message because you are subscribed to the Google Groups "mybatis-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mybatis-user...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Jeff Butler

unread,
Mar 26, 2015, 5:07:21 PM3/26/15
to mybati...@googlegroups.com
If you commit to maven, it is very easy:

1. Create a Maven JAR project to hold your plugin.  That project only needs a dependency to mybatis-generator-core
2. In the project where you use the generator maven plugin, add your project #1 as a dependency of mybatis-generator-maven-plugin

You can do both as Eclipse Maven projects and debug as normal.  You might have to "mvn install" project #1 locally first, but it works well.

Doing it with the menu option is more difficult and I'm not sure you can make it work.  I don't have any option to control the classpath for that menu option, so you would probably need to add your plugin to the system classpath (ugh).

Jeff Butler

Daniel Wilkerson

unread,
Apr 23, 2015, 3:36:25 PM4/23/15
to mybati...@googlegroups.com
Hi Jeff and Steve. Thanks for the helpful information! I apologize for being slow to respond. A lot of work and getting pulled many different directions at the same time.

I've started an Eclipse/Maven project to try my hand at this, but to test out the plugin before including it in the project where I'm using MBG, how do I launch it? Is there a maven plugin to test run this? I feel like I sound like I've never coded and ever used Eclipse (which is not true...lol) but am a little confused how to execute the plugin during initial development (i.e. before plugging into the MGB config in my MyBatis project)? I'm at the super basic stage of making sure I have my project configured, building, and running correctly before attempting to get neck deep in coding one these plugins.

I apologize if these questions see a bit basic. Perhaps I'm making it harder in my mind than it actually is. It certainly wouldn't be the first time...lol. =D

Daniel

Daniel Wilkerson

unread,
Apr 23, 2015, 5:13:35 PM4/23/15
to mybati...@googlegroups.com
I knew as soon as I posted my response question about running MBG in my Eclipse project I'd figure it out. Murphy was an optimist.

But...I am having an issue with Maven and MBG not finding the postgresql JDBC driver. I have it as a dep in my POM file and have the generatorConfig.xml in the src/main/resources directory but get a ClassNotFoundException for the Postgres JDBC driver.

I never had this problem when using the right-click menu option to generate. How do I make sure MBG can see the JDBC driver dependency and make sure it's on the classpath? Do I need to add a <classPathEntry> in my generatorConfig that points to the .m2 directory where my deps are stored?

<<<<<<<<<My Pom file>>>>>>>>>>>>>>>>>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.workpalce.somesystem.data</groupId>
  <artifactId>mbgplugin</artifactId>
  <version>0.0.1-SNAPSHOT</version>
    <dependencies>
  <dependency>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-core</artifactId>
    <version>1.3.2</version>
  </dependency>
  <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
    </dependency>
    <dependency>
        <groupId>postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>9.1-901.jdbc4</version>
    </dependency>
  </dependencies>
  <build>
      <plugins>
          <plugin>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-maven-plugin</artifactId>
          <version>1.3.0</version>
        </plugin>
      </plugins>
  </build>   
</project>

<<<<<<<<<<<<<<<<< CONSOLE OUTPUT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
[DEBUG]   (f) verbose = false
[DEBUG] -- end configuration --
java.lang.RuntimeException: Exception getting JDBC Driver
[INFO] ------------------------------------------------------------------------
    at org.mybatis.generator.internal.db.ConnectionFactory.getDriver(ConnectionFactory.java:84)
    at org.mybatis.generator.internal.db.ConnectionFactory.getConnection(ConnectionFactory.java:53)
    at org.mybatis.generator.config.Context.getConnection(Context.java:487)
    at org.mybatis.generator.config.Context.introspectTables(Context.java:396)
    at org.mybatis.generator.api.MyBatisGenerator.generate(MyBatisGenerator.java:222)
    at org.mybatis.generator.maven.MyBatisGeneratorMojo.execute(MyBatisGeneratorMojo.java:184)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: java.lang.ClassNotFoundException: org.postgresql.Driver
    at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:50)
    at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:244)
    at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:230)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:191)
    at org.mybatis.generator.internal.ObjectFactory.externalClassForName(ObjectFactory.java:89)
    at org.mybatis.generator.internal.db.ConnectionFactory.getDriver(ConnectionFactory.java:81)
    ... 26 more
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.063s
[INFO] Finished at: Thu Apr 23 16:53:29 EDT 2015
[INFO] Final Memory: 6M/123M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.mybatis.generator:mybatis-generator-maven-plugin:1.3.0:generate (default-cli) on project mbgplugin: Exception getting JDBC Driver -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.mybatis.generator:mybatis-generator-maven-plugin:1.3.0:generate (default-cli) on project mbgplugin: Exception getting JDBC Driver
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:217)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: org.apache.maven.plugin.MojoExecutionException: Exception getting JDBC Driver
    at org.mybatis.generator.maven.MyBatisGeneratorMojo.execute(MyBatisGeneratorMojo.java:208)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
    ... 19 more
[ERROR]
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException




On Thursday, March 26, 2015 at 11:39:54 AM UTC-4, Daniel Wilkerson wrote:

Jeff Butler

unread,
Apr 23, 2015, 5:23:24 PM4/23/15
to mybati...@googlegroups.com
Try adding the postgres driver as a dependency of the plugin, not a dependency of the project (declare the <dependency> under the <plugin>).

Jeff Butler


Daniel Wilkerson

unread,
Apr 23, 2015, 5:29:49 PM4/23/15
to mybati...@googlegroups.com
That did it! Thank you Jeff! I appreciate your help and patience with the silly questions.

I've only recently started moving to Maven based projects. Most of the time I can get around Maven just fine, but some of those little nuances haven't sunk all the way in yet. I didn't realize you could add deps to a plugin like that. I do now though! ;0)

Thanks!
Daniel


On Thursday, March 26, 2015 at 11:39:54 AM UTC-4, Daniel Wilkerson wrote:

Daniel Wilkerson

unread,
Apr 24, 2015, 11:24:24 AM4/24/15
to mybati...@googlegroups.com
Hi Jeff and Steve.

Trying to get any of the plugins to fire and Maven is unable to instantiate them. I've tried my skeleton version from yesterday afternoon and tried one of the existing plugins in core. Neither would instantiate.

I plugged them into the generator config with <plugin type="mbgplugin.MyNewPlugin"/> for example, but I get error below. The error below was after trying the CachePlugin to see if it would fire. Do I need to add any kind of classpath entry to the generator Maven plugin?

[INFO] ------------------------------------------------------------------------

[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.044s
[INFO] Finished at: Fri Apr 24 11:16:08 EDT 2015

[INFO] Final Memory: 6M/123M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.mybatis.generator:mybatis-generator-maven-plugin:1.3.0:generate (default-cli) on project mbgplugin: Cannot instantiate object of type org.mybatis.generator.plugins.CachePlugin -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.mybatis.generator:mybatis-generator-maven-plugin:1.3.0:generate (default-cli) on project mbgplugin: Cannot instantiate object of type org.mybatis.generator.plugins.CachePlugin

    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:217)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: org.apache.maven.plugin.MojoExecutionException: Cannot instantiate object of type org.mybatis.generator.plugins.CachePlugin

    at org.mybatis.generator.maven.MyBatisGeneratorMojo.execute(MyBatisGeneratorMojo.java:208)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
    ... 19 more
[ERROR]
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException


On Thursday, March 26, 2015 at 11:39:54 AM UTC-4, Daniel Wilkerson wrote:

Daniel Wilkerson

unread,
Apr 24, 2015, 4:45:37 PM4/24/15
to mybati...@googlegroups.com
Just wanted to update from my last post so others might benefit from what I did to get the plugin to get instantiated by the MBG Maven plugin...

I had to run the install goal first to have the jar file built for the first time, then needed to add another dependency underneath the <plugin> tag for the MBG plugin. This link, http://blog.javaforge.net/post/30577502737/mybatis-generator-plugins, helped me suss out the issue.

<plugin>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-maven-plugin</artifactId>
          <version>1.3.0</version>
          <configuration>
                <configurationFile>${basedir}/src/main/resources/generatorConfig.xml
                </configurationFile>
                <outputDirectory>${basedir}/src/main/java</outputDirectory>
                <verbose>true</verbose>
                <overwrite>true</overwrite>
            </configuration>
          <dependencies>

              <dependency>
                <groupId>postgresql</groupId>
                <artifactId>postgresql</artifactId>
                <version>9.1-901.jdbc4</version>
            </dependency>
            <dependency>
                <groupId>my.groupid.path.here</groupId>
                <artifactId>mbgplugin</artifactId>
                <version>${project.version}</version>
            </dependency>
          </dependencies>
        </plugin>


I did have to use the full/absolute path to my eclipse project in the targetProject attribute of the generatorConfig.xml. Is there a way to do relative paths when using Maven only (not the menu option to generate)? I tried, but it complained that it couldn't find the project. It wasn't until I used the absolute path that it became happy again.

If I have to use the absolute it's cool, but I'd rather use a relative path if possible.

On Thursday, March 26, 2015 at 11:39:54 AM UTC-4, Daniel Wilkerson wrote:
Reply all
Reply to author
Forward
0 new messages