Change SqlSessionFactory properties in runtime

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Change SqlSessionFactory properties in runtime

Jose María Zaragoza
Hello:

I'm using MyBatis 3.4.6

I'd like to set some properties according to JVM environment ( TEST vs PRO )
The <properties> element in the configuration.xml is

<properties>
<property name="schema_name" value="PRO"/>
</properties>


SQL sentences in XML mappers refer to ${schema_name}

I can edit this configuration.xml and XML mappers
But I cannot load the configuration programmatically

1) I tried to define a Spring BeanPostProcessor component to change
SqlSessionFactory configuration in runtime , but it doesnt work . I
dont know why

@Override
    public final Object postProcessAfterInitialization(final Object
bean, final String beanName) {

    if (bean instanceof SqlSessionFactory) {

        SqlSessionFactory sqlSessionFactory = ((SqlSessionFactory)bean)
        Properties properties  =
sqlSessionFactory.getConfiguration().getVariables()
        properties.put("schema_name", "TEST");
        sqlSessionFactory.getConfiguration().setVariables(properties);
     }
        return bean;
    }


2) I could pass schema_name as parameter in every query  and to
calculate its value when DAO is initialized , but I would like to
avoid that

3) I could read properties from configuration-dev.properties or
configuration.properties, but I want to choose it in runtime

Any suggestions ?

Thanks and regards

--
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Change SqlSessionFactory properties in runtime

Erwan Letessier
I don't really understand what you mean by choosing at runtime. That is: a condition checked at runtime would determine in which environment it running ?
Anyway I have same requirement: queries with a schema name that depends on environment.
Here what I do (actually adapted annotations from CDI to Spring). It reads additional properties from properties files that are not necessarily package in the app (as long as there are in the classpath)
@Configuration public class SessionFactoryProvider {
@Bean public SqlSessionFactory getFactory() throws IOException {
    final Reader reader = Resources.getResourceAsReader("mybatis-config-bi.xml");
final Properties properties = new Properties();
properties.load(Resources.getResourceAsReader("aFileInClasspath.properties"));
properties.load(Resources.getResourceAsReader("anotherFile.properties"));
return new SqlSessionFactoryBuilder().build(reader, properties);
}
Maybe your code does not produce the expected effect  because the ${schema_name} in the mapper queries are resolved before postProcessAfterInitialization is invoked.

Erwan Letessier


On Wed, Oct 24, 2018 at 11:13 AM Jose María Zaragoza <[hidden email]> wrote:
Hello:

I'm using MyBatis 3.4.6

I'd like to set some properties according to JVM environment ( TEST vs PRO )
The <properties> element in the configuration.xml is

<properties>
<property name="schema_name" value="PRO"/>
</properties>


SQL sentences in XML mappers refer to ${schema_name}

I can edit this configuration.xml and XML mappers
But I cannot load the configuration programmatically

1) I tried to define a Spring BeanPostProcessor component to change
SqlSessionFactory configuration in runtime , but it doesnt work . I
dont know why

@Override
    public final Object postProcessAfterInitialization(final Object
bean, final String beanName) {

    if (bean instanceof SqlSessionFactory) {

        SqlSessionFactory sqlSessionFactory = ((SqlSessionFactory)bean)
        Properties properties  =
sqlSessionFactory.getConfiguration().getVariables()
        properties.put("schema_name", "TEST");
        sqlSessionFactory.getConfiguration().setVariables(properties);
     }
        return bean;
    }


2) I could pass schema_name as parameter in every query  and to
calculate its value when DAO is initialized , but I would like to
avoid that

3) I could read properties from configuration-dev.properties or
configuration.properties, but I want to choose it in runtime

Any suggestions ?

Thanks and regards

--
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.

--
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Change SqlSessionFactory properties in runtime

Guy Rouillier-2
In reply to this post by Jose María Zaragoza
Take a look at MyBatis User's Guide, Properties section.  You can
indeed load a specified set of properties (different files, if you'd
like), then include those properties when you create your
SqlSessionFactory.  The section in the guide includes an example of
exactly that:

SqlSessionFactory factory =
  sqlSessionFactoryBuilder.build(reader, props);

On Wed, 2018-10-24 at 11:13 +0200, Jose María Zaragoza wrote:

> Hello:
>
> I'm using MyBatis 3.4.6
>
> I'd like to set some properties according to JVM environment ( TEST
> vs PRO )
> The <properties> element in the configuration.xml is
>
> <properties>
> <property name="schema_name" value="PRO"/>
> </properties>
>
>
> SQL sentences in XML mappers refer to ${schema_name}
>
> I can edit this configuration.xml and XML mappers
> But I cannot load the configuration programmatically
>
> 1) I tried to define a Spring BeanPostProcessor component to change
> SqlSessionFactory configuration in runtime , but it doesnt work . I
> dont know why
>
> @Override
>     public final Object postProcessAfterInitialization(final Object
> bean, final String beanName) {
>
>     if (bean instanceof SqlSessionFactory) {
>
>         SqlSessionFactory sqlSessionFactory =
> ((SqlSessionFactory)bean)
>         Properties properties  =
> sqlSessionFactory.getConfiguration().getVariables()
>         properties.put("schema_name", "TEST");
>         sqlSessionFactory.getConfiguration().setVariables(properties)
> ;
>      }
>         return bean;
>     }
>
>
> 2) I could pass schema_name as parameter in every query  and to
> calculate its value when DAO is initialized , but I would like to
> avoid that
>
> 3) I could read properties from configuration-dev.properties or
> configuration.properties, but I want to choose it in runtime
>
> Any suggestions ?
>
> Thanks and regards
>
--
--
Guy Rouillier

--
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Change SqlSessionFactory properties in runtime

Jose María Zaragoza
Thanks Guy and Erwan
But I cannot load the configuration programmatically, because
SqlSessionFactory is injected in my code by an external library ( I
only can define a configuration.xml file )
My idea was to modify that SqlSessionFactory's configuration in
runtime , but I guess, ( like Erwan told me above ) that bindings are
performed when is SqlSessionFactory built and I cannot change it in
runtime

Regards

El jue., 25 oct. 2018 a las 3:08, Guy Rouillier
(<[hidden email]>) escribió:

>
> Take a look at MyBatis User's Guide, Properties section.  You can
> indeed load a specified set of properties (different files, if you'd
> like), then include those properties when you create your
> SqlSessionFactory.  The section in the guide includes an example of
> exactly that:
>
> SqlSessionFactory factory =
>   sqlSessionFactoryBuilder.build(reader, props);
>
> On Wed, 2018-10-24 at 11:13 +0200, Jose María Zaragoza wrote:
> > Hello:
> >
> > I'm using MyBatis 3.4.6
> >
> > I'd like to set some properties according to JVM environment ( TEST
> > vs PRO )
> > The <properties> element in the configuration.xml is
> >
> > <properties>
> > <property name="schema_name" value="PRO"/>
> > </properties>
> >
> >
> > SQL sentences in XML mappers refer to ${schema_name}
> >
> > I can edit this configuration.xml and XML mappers
> > But I cannot load the configuration programmatically
> >
> > 1) I tried to define a Spring BeanPostProcessor component to change
> > SqlSessionFactory configuration in runtime , but it doesnt work . I
> > dont know why
> >
> > @Override
> >     public final Object postProcessAfterInitialization(final Object
> > bean, final String beanName) {
> >
> >     if (bean instanceof SqlSessionFactory) {
> >
> >         SqlSessionFactory sqlSessionFactory =
> > ((SqlSessionFactory)bean)
> >         Properties properties  =
> > sqlSessionFactory.getConfiguration().getVariables()
> >         properties.put("schema_name", "TEST");
> >         sqlSessionFactory.getConfiguration().setVariables(properties)
> > ;
> >      }
> >         return bean;
> >     }
> >
> >
> > 2) I could pass schema_name as parameter in every query  and to
> > calculate its value when DAO is initialized , but I would like to
> > avoid that
> >
> > 3) I could read properties from configuration-dev.properties or
> > configuration.properties, but I want to choose it in runtime
> >
> > Any suggestions ?
> >
> > Thanks and regards
> >
> --
> --
> Guy Rouillier
>
> --
> 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 [hidden email].
> For more options, visit https://groups.google.com/d/optout.

--
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Change SqlSessionFactory properties in runtime

Mark Nolan

I'm not quite sure I understand what your requirement is. What do you mean by "injected in my code by an external library"? Something other than Spring?

Is your goal simply to get rid of a one line xml configuration file? In which case, why? If your particular set up involves using some external library and the only way that library lets you configure MyBatis is through a configuration file, why would you fight against it? It gives you a perfectly serviceable way of configuring the tool and anyone else who is aware of the library will surely expect you to configure it by the mechanism provided. Follow the principle of least astonishment. If you don't like that, you should get rid of the external library altogether.

In any case, surely Erwan has already given you an option. Since you want to configure in code, you must be familiar with Spring Configuration classes: that's what his example does. The SqlSessionFactory is defined in his configuration class and then injected everywhere else. Can't you do that?

Note that everything that departs from the norm gets increasingly complex and hard to maintain. However, if your application is a servlet, you could create a ContextLoaderListener that pre-processes the mapper files. I wouldn't advise it: I would be looking for an alternative that was more "expected" for the poor SOBs that have to maintain my code after I move on.

Mark.
.




On Thu, 25 Oct 2018 at 12:21, Jose María Zaragoza <[hidden email]> wrote:
Thanks Guy and Erwan
But I cannot load the configuration programmatically, because
SqlSessionFactory is injected in my code by an external library ( I
only can define a configuration.xml file )
My idea was to modify that SqlSessionFactory's configuration in
runtime , but I guess, ( like Erwan told me above ) that bindings are
performed when is SqlSessionFactory built and I cannot change it in
runtime

Regards

El jue., 25 oct. 2018 a las 3:08, Guy Rouillier
(<[hidden email]>) escribió:
>
> Take a look at MyBatis User's Guide, Properties section.  You can
> indeed load a specified set of properties (different files, if you'd
> like), then include those properties when you create your
> SqlSessionFactory.  The section in the guide includes an example of
> exactly that:
>
> SqlSessionFactory factory =
>   sqlSessionFactoryBuilder.build(reader, props);
>
> On Wed, 2018-10-24 at 11:13 +0200, Jose María Zaragoza wrote:
> > Hello:
> >
> > I'm using MyBatis 3.4.6
> >
> > I'd like to set some properties according to JVM environment ( TEST
> > vs PRO )
> > The <properties> element in the configuration.xml is
> >
> > <properties>
> > <property name="schema_name" value="PRO"/>
> > </properties>
> >
> >
> > SQL sentences in XML mappers refer to ${schema_name}
> >
> > I can edit this configuration.xml and XML mappers
> > But I cannot load the configuration programmatically
> >
> > 1) I tried to define a Spring BeanPostProcessor component to change
> > SqlSessionFactory configuration in runtime , but it doesnt work . I
> > dont know why
> >
> > @Override
> >     public final Object postProcessAfterInitialization(final Object
> > bean, final String beanName) {
> >
> >     if (bean instanceof SqlSessionFactory) {
> >
> >         SqlSessionFactory sqlSessionFactory =
> > ((SqlSessionFactory)bean)
> >         Properties properties  =
> > sqlSessionFactory.getConfiguration().getVariables()
> >         properties.put("schema_name", "TEST");
> >         sqlSessionFactory.getConfiguration().setVariables(properties)
> > ;
> >      }
> >         return bean;
> >     }
> >
> >
> > 2) I could pass schema_name as parameter in every query  and to
> > calculate its value when DAO is initialized , but I would like to
> > avoid that
> >
> > 3) I could read properties from configuration-dev.properties or
> > configuration.properties, but I want to choose it in runtime
> >
> > Any suggestions ?
> >
> > Thanks and regards
> >
> --
> --
> Guy Rouillier
>
> --
> 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 [hidden email].
> For more options, visit https://groups.google.com/d/optout.

--
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.

--
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.