如何在dropwizard上使用guice自动连接HibernateBundle?

时间:2014-04-27 08:08:30

标签: java hibernate guice dropwizard

我试图用guice / dropwizard配置hibernatebundle并需要帮助。 我使用hubspot / dropwizard-guice / 0.7.0第三方库以及dropwizard lib。

下面的代码显然不会工作,需要帮​​助才能搞清楚。我如何重写这个,以便将hibernatebundle和最终的会话工厂自动注入任何需要它的bean。

MyApplication.java

public class MyApplication extends Application<MyAppConfiguration> {

    private final HibernateBundle<MyAppConfiguration> hibernateBundle = new HibernateBundle<MyAppConfiguration>(MyModel.class) {
        @Override
        public DataSourceFactory getDataSourceFactory(MyAppConfiguration configuration) {
            return configuration.getDataSourceFactory();
        }
    };

    @Override
    public void initialize(Bootstrap<MyAppConfiguration> bootstrap) {
        bootstrap.addBundle(hibernateBundle);  // ???

        bootstrap.addBundle(
            GuiceBundle.<MyAppConfiguration>newBuilder()
                    .addModule(new MyAppModule())
                    .enableAutoConfig(getClass().getPackage().getName())
                    .setConfigClass(MyAppConfiguration.class)
                    .build()
        );
    }

}   

MyAppModule.java

public class MyAppModule extends AbstractModule {

    @Provides
    public SessionFactory provideSessionFactory(MyAppConfiguration configuration) {
            // really wrong as it creates new instance everytime.
        return configuration.getHibernateBundle().getSessionFactory(); // ???
    }

}

MyAppConfiguration.java

public class MyAppConfiguration extends Configuration {
    @Valid
    @NotNull
    private DataSourceFactory database = new DataSourceFactory();

    @JsonProperty("database")
    public DataSourceFactory getDataSourceFactory() {
        return database;
    }

    @JsonProperty("database")
    public void setDataSourceFactory(DataSourceFactory dataSourceFactory) {
        this.database = dataSourceFactory;
    }

        // ???
    public HibernateBundle<MyAppConfiguration> getHibernateBundle() {
        return new HibernateBundle<MyAppConfiguration>(MyModel.class) {
            @Override
            public DataSourceFactory getDataSourceFactory(MyAppConfiguration configuration) {
                return database;
            }
        };
    }

}  

4 个答案:

答案 0 :(得分:6)

以下是我最终的表现。我从来没有从这里或邮件列表得到答案,所以我会考虑这种hackish,可能不是正确的方法,但它适用于我。

在我的模块中(扩展了abstractmodule):

private final HibernateBundle<MyConfiguration> hibernateBundle =
        new HibernateBundle<MyConfiguration>(MyModel.class) {
            @Override
            public DataSourceFactory getDataSourceFactory(MyConfiguration configuration) {
                return configuration.getDataSourceFactory();
            }
        };

@Provides
public SessionFactory provideSessionFactory(MyConfiguration configuration,
                                            Environment environment) {

    SessionFactory sf = hibernateBundle.getSessionFactory();
    if (sf == null) {
        try {
            hibernateBundle.run(configuration, environment);
        } catch (Exception e) {
            logger.error("Unable to run hibernatebundle");
        }
    }

    return hibernateBundle.getSessionFactory();
}

修订:

public SessionFactory provideSessionFactory(MyConfiguration configuration,
                                            Environment environment) {

    SessionFactory sf = hibernateBundle.getSessionFactory();
    if (sf == null) {
        try {
            hibernateBundle.run(configuration, environment);
            return hibernateBundle.getSessionFactory();
        } catch (Exception e) {
            logger.error("Unable to run hibernatebundle");
        }
    } else {
        return sf;
    }
}

答案 1 :(得分:3)

我认为显式运行(配置,环境)调用(在@StephenNYC提供的答案中)有点奇怪,所以挖得更深一些。我发现dropwizard-guice中的AutoConfig没有正确设置ConfiguredBundle(HibernateBundle是这样的类型)。

https://github.com/HubSpot/dropwizard-guice/pull/35开始,代码现在看起来像这样:

@Singleton
public class MyHibernateBundle extends HibernateBundle<NoxboxConfiguration> implements ConfiguredBundle<MyConfiguration>
{
    public MyHibernateBundle()
    {
        super(myDbEntities(), new SessionFactoryFactory());
    }

    private static ImmutableList<Class<?>> myDbEntities()
    {
        Reflections reflections = new Reflections("com.acme");
        ImmutableList<Class<?>> entities = ImmutableList.copyOf(reflections.getTypesAnnotatedWith(Entity.class));
        return entities;
    }

    @Override
    public DataSourceFactory getDataSourceFactory(NoxboxConfiguration configuration)
    {
        return configuration.getMyDb();
    }
}

@Provides
public SessionFactory sessionFactory(MyHibernateBundle hibernate)
{
    return checkNotNull(hibernate.getSessionFactory());
}

这背后的魔力是MyHibernateBundle实现了ConfiguredBundle,dropwizard-guice现在可以自动获取并实例化。

答案 2 :(得分:0)

这是我解决它的方式:
将Hibernate包放在guice模块中,并将bootstap对象作为guice模块构造函数的参数传递,以便可以将hibernate包添加到其中。
配置可以保持与使用没有guice的hibernate-bundle完全一样 我使用了dropwizard-hibernate v0.7.1和dropwizard-guice v0.7.0.3

MyAppModule.java:

public class MyAppModule extends AbstractModule {
  private final HibernateBundle<MyAppConfiguration> hibernateBundle = new HibernateBundle<MyAppConfiguration>(MyModel.class) {
    @Override
    public DataSourceFactory getDataSourceFactory(MyAppConfiguration configuration) {
        return configuration.getDataSourceFactory();
    }
  };

  public MyAppModule(Bootstrap<MyAppConfiguration> bootstrap) {
    bootstrap.addBundle(hibernateBundle);
  }

  @Override
  protected void configure() {
  }

  @Provides
  public SessionFactory provideSessionFactory() {
    return hibernateBundle.getSessionFactory();
  }
}

MyApplication.java:

public class MyApplication extends Application<MyAppConfiguration> {

  @Override
  public void initialize(Bootstrap<MyAppConfiguration> bootstrap) {
    bootstrap.addBundle(
            GuiceBundle.<MyAppConfiguration>newBuilder()
                    .addModule(new MyAppModule(bootstrap))
                    .enableAutoConfig(getClass().getPackage().getName())
                    .setConfigClass(MyAppConfiguration.class)
                    .build()
    );
  }

  @Override
  public void run(final MyAppConfiguration configuration, final Environment environment) throws Exception {
  }

}  

MyAppConfiguration.java:

public class MyAppConfiguration extends Configuration {
  @Valid
  @NotNull
  @JsonProperty("database")
  private DataSourceFactory database = new DataSourceFactory();

  public DataSourceFactory getDataSourceFactory() {
    return database;
  }
}

答案 3 :(得分:-1)

我没有在dropwizard中使用hibernate,但我使用过Guice,你真的只需要担心MyAppModule。那将是魔术的发生地点:

public class MyAppModule extends AbstractModule {

    @Singleton
    @Provides
    public SessionFactory provideSessionFactory(MyAppConfiguration configuration) {
        HibernateBundle<MyAppConfiguration> hibernate = new HibernateBundle<ExampleConfiguration>(MyModel.class) {
            @Override
            public DataSourceFactory getDataSourceFactory(MyAppConfiguration configuration) {
                return configuration.getDataSourceFactory();
            }
        }

        return hibernate.getSessionFactory();
    }
}

(有关多个类,请参阅here

MyAppConfiguration.java和MyApplication.java不应该包含任何hibernate包引用。然后,您应该能够在任何需要的地方@Inject一个SessionFactory。