views:

380

answers:

2

We have 2 different server environments using the same Hibernate configuration. One server has JNDI support for datasource, but the other does not. Currently the Hibernate configuration is configured to use JNDI, which is causing problem on the server that does not support JNDI.

I have also tried to put the direct JDBC configuration together with JNDI configuration into the configuration file, but it looks like hibernate always favors JNDI over direct JDBC configuration if both exist.

My question is, will it be the same if both JNDI and connection_provider configuration both exists? Will Hibernate still use JNDI over connection_provider? Or is there any way to change the precedence of the database connection property?

I do not have access to the server all the time, so I thought I do ask the question before my window of the sever time.

Thanks in advance.

A: 

We have 2 different server environments using the same Hibernate configuration.

Well, it may not be the expected answer but I have the feeling that you are creating the problem yourself here: if your environments are different, use different configurations. What I would do is the following:

  • put everything common in hibernate.cfg.xml (bundled in the application)
  • put specific things in hibernate.properties files and place the "right one" in a root directory of the class path for each application (but outside the application).

For example, this would be the content of the hibernate.properties for the "JNDI environment":

hibernate.connection.datasource = java:/comp/env/jdbc/test
hibernate.transaction.factory_class = org.hibernate.transaction.JTATransactionFactory
hibernate.transaction.manager_lookup_class = org.hibernate.transaction.JBossTransactionManagerLookup
hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect

And this would be the content of the hibernate.properties for the "non JNDI environment":

hibernate.connection.driver_class = org.postgresql.Driver
hibernate.connection.url = jdbc:postgresql://localhost/mydatabase
hibernate.connection.username = myuser
hibernate.connection.password = secret
hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=20
hibernate.c3p0.timeout=1800
hibernate.c3p0.max_statements=50
hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
Pascal Thivent
Hi thanks for your answer. But whether or not the environment shares same config or not is out of my control :-( The system is set up like that by the time I join the project, and they are not welling to make any change to it... life is hard ...
Alvin
@Alvin I must be missing something. Does the actual solution work or not? My understanding is that it doesn't (in which case changing seems a natural choice).
Pascal Thivent
Perhaps I'm missing something, but are you trying to use Hibernate configuration under one and only ISessionFactory? If you require to distinct connection, then you will need to have named <session-factory> elements, in my understanding of the thing, and then building two instances of the ISessionFactory API. One for JNDI, and another for JDBC. Naming each <session-factory> elements like so seems reasonable to me. What do you both think of that? Indeed, this requires you have different mapping assemblies if the both the JNDI and the JDBC databases differ from each other.
Will Marcouiller
@Will I didn't understood the question as "I need to connect my application to two database" but as "my application is deployed in two environments and needs different database configuration parameters. BTW, this is Java :)
Pascal Thivent
Well, let's suppose I didn't mention about the assemblies! ;P But the concept is similar, I think, for what it is with the rest. ;) Am I wrong?
Will Marcouiller
@Pascal, the solution actually worked and I told the decision maker about this, but his position is: all the environments must use a single hibernate configuration file... so basically I have to cram all the configuration into one configuration file and that's why I was wondering if hibernate can be tweak to favor direct JDBC connection, but it sounds like it doesn't? However, I think your approach is the best practice and I will die trying to make the decision maker to change his mind. Thanks!
Alvin
@Alvin To be honest, I don't know how Hibernate will behave if you provide both configurations. Maybe it can fall back on the JDBC stuff if the JNDI lookup fails (I don't know what to expect in the JDNI environment). But I never tested this. Actually, I understand your position and the decision maker point of view. However, a common configuration makes sense when the environments are similar. If they are not, configuring things is the whole point of... configuration.
Pascal Thivent
+1  A: 

Use the URL method in the configuration file. In the code, manually try to get a connection to the JNDI source using the context.lookup("java:comp/env/..."). If that succeeds, set the Hibernate data source property and unset the url-related properties. If it fails let Hibnerate continue with the url configuration.

if (jndiDataSourceExists()) {
  configuration.setProperty(Environment.DATASOURCE, "jdbc/jndiname")
  configuration.setProperty(Environment.URL, null);
}
configuration.buildSessionFactory();
Brian Deterling