Reputation: 2290
I am trying to follow the guide outlined in this URI: https://grails.github.io/grails-doc/latest/guide/single.html#multipleDatasources
My application.yml file, contains the following description for datasources:
dataSources:
dataSource:
pooled: true
jmxExport: true
driverClassName: org.h2.Driver
username: sa
password:
raw:
dialect: org.hibernate.dialect.Oracle10gDialect
driverClassName: oracle.jdbc.driver.OracleDriver
username: rip
password: password
dbCreate: validate
url: jdbc:oracle:thin:@127.0.0.1:345:coolio
environments:
development:
dataSources:
dataSource:
dbCreate: create-drop
url: jdbc:h2:mem:devDb;MVCC=TRUE
test:
dataSources:
dataSource:
dbCreate: update
url: jdbc:h2:mem:testDb;MVCC=TRUE
production:
dataSources:
dataSource:
dbCreate: update
url: jdbc:h2:mem:prodDb;MVCC=TRUE
In my DatabaseService, I have the following code to try and inject the dataSource bean:
class DatabaseService {
static datasource = 'raw'
DataSource dataSource
public void testMyDb(User user) {
try {
println("we are in here with : " + dataSource.getConnection().getMetaData().getURL())
registerUser(new Sql(dataSource), user)
} catch (SQLException e) {
LOGGER.error("unable to register the user", e)
throw e
}
}
public void registerDeveloper(Sql sql, User user) {
sql.call("{call isertUser(?)}", [user.name])
}
The print statement in the DatabaseService file prints out:
we are in here with : jdbc:h2:mem:testDb
However, it should print out:
we are in here with : jdbc:oracle:thin:@127.0.0.1:345:coolio
What am I doing wrong? Why is it that the original Datasource bean is the one that gets instantiated?
UPDATED ATTEMPTS (1): I see a good thread here: https://github.com/grails/grails-core/issues/9690 , but even after replacing
static datasource = 'raw'
with
@Autowired
@Qualifier('dataSource_raw')
nothing changes. If I grab the Springs ApplicationContext, and print out the beans, dataSource_raw is indeed one of them.
UPDATED ATTEMPTS (2): I have tried to remove the entire environment section, with nothing changing.
Upvotes: 3
Views: 1952
Reputation: 1740
You can also declare as follows
def dataSource_raw
Without @Resource
annotation
Upvotes: 0
Reputation: 2188
Updated answer:
This seems to be a bug with grails 3. Not sure if it has been fixed in newer versions (>3.0.11). Even if we specify bean name with @Autowired and @Qualifier
annotation, grails injects the default bean in case of dataSource, transactionManager and sessionFactory
. This could be the case with other beans also, but I have tested only these three. I haven't tested the behaviour with domains or controllers.
To overcome this, what you can do is, instead of using these default names, use custom name along with @Autowired and @Qualifier
or @Resource
annotation.
With following way, you will get beans for default data source, even if you are specifying to use a different bean:
@Resource(name = "dataSource_raw")
DataSource dataSource
@Resource(name = "transactionManager_raw")
PlatformTransactionManager transactionManager
@Resource(name = "sessionFactory_raw")
SessionFactory sessionFactory
But with custom names, the bean with the name specified using @Qualifier
or @Resource
will be injected:
@Resource(name = "dataSource_raw")
DataSource rawDataSource
@Resource(name = "transactionManager_raw")
PlatformTransactionManager rawTransactionManager
@Resource(name = "sessionFactory_raw")
SessionFactory rawSessionFactory
Upvotes: 2