-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TRUNK-6136 - Add static method to retrieve the configured OpenMRS Dat… #4150
Conversation
…aSource from Hibernate
@mseaton how do you plan to access this from your module? Is it via |
@dkayiwa this is a static method, so I just plan to access it directly |
I do not see any problem resulting from this simple change. Though it looks ugly to provide direct public access to the data access layer via |
I agree @dkayiwa . We could try doing something like exposing the underlying datasource via JNDI, which log4j seems to be able to handle as an alternative to a static method for retrieving a connection, but that likely has it's own drawbacks and is not something I've done much before, so am less comfortable making that change. The main reason I felt this was OK is because a static public utility method already exists for getting a connection to the same database (DatabaseUpdater.getConnection()), it just creates a fresh connection every time instead of leveraging a connection pool, so this isn't really introducing any new access to the data layer that doesn't already exist. Would it be better to move this static method off of HibernateContextDAO and into a utility class instead, to isolate the business of getting a connection from the implementation of using the HibernateContextDAO to do so? I could certainly add the static DataSource variable and static "getConnection()" method to someplace like the existing "DatabaseUtil" class... Thoughts @dkayiwa / @ibacher ? |
Or just to move the user-accessible version of it into
I don't know that JNDI adds a whole ton of value here... It's nice for the case where you want to configure a data source in the container (e.g. Tomcat) and use it in the application or share a connection pool across applications, but ultimately, since we pull the connection string and credentials from the runtime properties, something like log4J would need to be able to update itself between the connection not being available (because OpenMRS is starting up, but the logger is already working) and the connection being available... |
Yes, I could do this. It would involve adding a new public instance method to HibernateContextDao and ContextDao to get either the Connection or the underlying DataSource, and then adding a public static method on Context to use the contextDao to retrieve this. Would this be better?
This will be an issue regardless. Having a static getConnection method that relies on the Context means that the Context needs to be started for this to be accessible. The alternative would be to roll a new, totally separate connection pool from the one used by Hibernate. I also am curious if this is more correct for other reasons (eg. will logging with the same connection pool as used for domain persistence be disruptive). Thoughts? |
@mseaton do you happen to know why this change works only in core but failed when you put it in your module? Second question: |
@dkayiwa I haven't fully debugged, but best I can gather is that the first time a class tries to get an instance of a Logger, log4j will initialize, and module classes are not loaded or available to the classloader yet at this time. Perhaps a deeper dive of the logging configuration is needed to ensure it is working as expected. |
I don't know |
@ibacher / @dkayiwa - I've moved the static method onto Context as suggested. Let me know what you think of this approach. Notably, I also removed the cached reference to the DataSource, so this will retrieve the DataSource from the sessionFactory using SessionFactoryUtils each time "getConnection()" is invoked. I hope this will be cheap, but will see with testing. My JDBC appender, configured like this, is working for me in a dev SDK instance: |
*/ | ||
public Connection getDatabaseConnection() { | ||
try { | ||
DataSource dataSource = SessionFactoryUtils.getDataSource(sessionFactory); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No big deal though, i would just do SessionFactoryUtils.getDataSource(sessionFactory).getConnection()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -177,4 +178,10 @@ public interface ContextDAO { | |||
* @see Context#updateSearchIndexForType(Class) | |||
*/ | |||
public void updateSearchIndexForType(Class<?> type); | |||
|
|||
/** | |||
* @return a Connection to the OpenMRS database |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think of mentioning that this is a pooled connection?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
#4150) TRUNK-6136 - Add static method to retrieve the configured OpenMRS DataSource from Hibernate
openmrs#4150) TRUNK-6136 - Add static method to retrieve the configured OpenMRS DataSource from Hibernate
…aSource from Hibernate
Note: This PR is against 2.5.x branch