hibernate connection tomcat - java

I was working in a web site (production) in Tomcat 7, so now I created a copy of this website and change the hibernate.cfg.xml to work with another database ( testing ).
<property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/test</property>
<property name="hibernate.connection.username">fake</property>
<property name="hibernate.connection.password">fake</property>
However, when I open the new new site, everything is ok, but, is still working with the production database even when I changed the connection string.
Anybody knows if I need to change another thing?. I missing something?. I am quite new in tomcat.
Thanks in advance.

Probably the database connection is configured elsewhere, and this is a redundant configuration. Usually it is configured in a data source - check your tomcat xml config files, or any xml config files of your application (if using spring, for example).

Datasources in Tomcat can be configured in context.xml file. Most probably that is the case.

might be production database running on different port instead of 3306.

Related

Best practice? JNDI, Hibernate and Tomcat

I've got a web application, hosted with tomcat, which uses hibernate to talk to a database.
I'm looking at how I can easy the pain of configuration as I migrate from dev, to test and to prod.
I've seen JNDI mentioned a lot and at first glance it seems like a good idea. You configure a jndi resource on each tomcat instance and the web context just uses it.
However after examining it further it seems that in order to have a JNDI I've got to have all my database objects + hibernate in the tomcat lib files in order for this to work. This sounds scary to me, what if I want to deploy another context that uses a different version of hibernate?
Also, am I not just swapping the pain of maintaining configuration for the pain of breakages caused by mismatches between the installed jndi resource classes and the ones in my context.
Ideally I think what I'm wanting is to just say in tomcat. There is a database called X, it is at this server and has this user/pass.
I'd appreciate your thoughts on the best way to handle the need for different config in different environments without having an extra step after each deploy to update the config files.
Cheers,
Peter
You have confused things a bit, I believe.
JNDI is just a name assigned to a datasource pool. This datasource uses a JDBC driver which in global Tomcat classpath, but that about the only shared resource in the whole setup.
Datasource has connection URL, username, password and options for connections defined, which may differ per server, but application doesn't care about it -- all it knows is the JNDI name, e.g. "jdbc/myDatasource".
All hibernate JARs, and well as any other JARs and whats not are to be packaged within the WAR. They are "visible" only within the WAR, and therefore you can have multiple applications using conflicting versions of libraries deployed to the same Tomcat.
No need to pollute lib/ directory of Tomcat. This is a bad practice, as you correctly observed.

Custom resource in JNDI on different application servers

Preface:
Most of J2EE applications are using container managed datasources through JNDI. This is fine as it gives one place for configuring these connections.
The problem arises when we want to use ORM framework (like hibernate) or something that have to know the default schema (mostly for Oracle, may be others too), which can be different from the username that is used to connect to the DB.
I want to put the default schema name somewhere close to the datasource definition. One of the options would be to put it in JNDI. I will then manually read of from there before construction the EntityManager (well actually using Spring).
As I found out there is a simple way to specify custom resource (in this situation it will be String with default schema name) in Apache Tomcat like this (correct me if I'm wrong):
<Environment name="schemaNames/EmployeeDB"
type="java.lang.String"
value="empl"
description="Schema name of Employees Database for HR Applications"/>
Anyway, considering this can be done in Apache Tomcat, how should I configure the same custom JNDI resource (of String type) within other application servers:
JBoss 4/5
WebSphere 6/7
WebLogic 9/10
If you know about other servers that would be great too.
Also, as an alternative I don't want to put the schema name in system properties or environment variables.
Thank you very much !
Update:
Found some way of achieving it on JBoss. I didn't test it tho.
http://forums.java.net/jive/thread.jspa?messageID=316228
Found information for WebLogic, but they talk about doing it programmaticly and not with configuration:
http://weblogic-wonders.com/weblogic/2010/06/12/binding-objects-in-weblogic-servers-jndi-tree/
http://forums.oracle.com/forums/thread.jspa?messageID=4397353
For WebSphere you can actually set the default schema in your defined DataSource. It is a custom property called currentSchema. (ie, in V7 it is Resources > JDBC > Data sources > your data source name > Custom properties > currentSchema.
Otherwise you can use a Name Space Binding and define it there: (ie, in V7 it is Environment > Naming > Name Space Bindings. You can use JNDI to look this up if you don't want to programmatically set it in WebSphere.
Can't speak to JBoss and WebLogic as I haven't worked with them.
If you are using Hibernate, this is the property to add in persistence unit :
<property name="hibernate.default_schema" value="myschema" />
That is the prefix that JPA will insert for table names.
If you need something 'closer' to the AS Datasources definitions, you may inject some DB-specific SQL at DB connection time; for instance Oracle,
ALTER SESSION SET CURRENT_SCHEMA =
On JBoss, you may add this in the datasource definition :
<new-connection-sql>
ALTER SESSION SET CURRENT_SCHEMA=myschema
</new-connection-sql>
Also editable in JBoss 7 Admin.
On Weblogic, you may inject this in the Connection Pools.
On Websphere, this should be similar.
On JBoss, you can use a special MBean(org.jboss.naming.JNDIBindingServiceMgr) and a service.xml to configure JNDI-entries, and then map these entries into your webapps. There is a lengthy explication for this rather non-trivial process here:
http://usna86-techbits.blogspot.com/2011/01/jboss-jndi-and-javacompenv.html
I'm still looking for a a way to place an entire properties-file/resourcebundle into jndi, as this manual mapping gets very tedious when you have a lot of properties that you want to put into jndi and make available for your webapps.
This same problem has been bothering be for quite a while for WebLogic, in particular 10.3.5 (11g).
I spent most of a day looking around and all I found was this: http://code.google.com/p/weblogic-jndi-startup/. It works just fine. It is a little restrictive: it requires the object you want to add to JNDI to have a constructor with a single String parameter.
For what I needed, weblogic-jndi-startup didn't work, so I built on Roger's code and came up with this: https://bitbucket.org/phillip_green_idmworks/weblogic-jndi-custom-resource-configuration/. I have a write up for it at http://coder-in-training.blogspot.com/2012/03/weblogic-jndi-custom-resource.html

How to change database settings for a deployed war file?

We have a WAR file that is deployed however we want to change the database settings. How do I get about doing that? I opened the WAR file in an IDE and there are like 2-3 places that have the database settings. What is the proper way of changing it?
Thank You
The proper way is to use a datasource at the application level and to administer it at the application server level. Check the MySQL DBCP Example in the Tomcat documentation.
The tomcat instance should be set up to provide a datasource through JNDI.

Programaticly create datasource for JBoss 4.2.x

Would it be possible to programmaticly create a data source in jboss and still have a valid jndi entry for the entity manager to use?
Creating the data source is where I am lost, I hope I can use a MBean that runs on stat-up to handle this.
This would not be my preferred method, but the application I am working on has a global configuration file hosted on another server I am suppose to use for configuration.
update: In this instance I need to create a data source programticly or change the jdbc url of an exsiting datasource. I don't know the DB server url until runtime.
Rather than poking around in the guts of JBoss in order to do this, I suggest using a 3rd-party connection pool utility, such as Apache Commons DBCP. There are instructions on how to programmatically register a DBCP datasource on JNDI here.
The first two lines of the sample code should be unnecessary, just create the default InitialContext and then rebind the datasource reference into it as described.
Here's a post that describes how to create a jboss service archive (SAR) that you can put in your EAR that will deploy a data source when the EAR is deployed, and remove it when the EAR in undeployed.

can Web/Meta-Inf/Context.xml read in Tomcat from some properties file

I've context.xml in my web/meta-inf/ folder containing database connection (pool) details. Now i want the database details for my application to be provided by end user in some properties file and context.xml reading the db connection info from the properties file instead of hard coing them in the file directly.
is it possible for tomcat to replace the placeholders from some properties file?
i read about context-manager but not sure where to place that.
Please provide your inputs.
Thanks
Abhishek
You can do it in a better way.
In our case we had different databases for different profiles, like dev, UAT, pre-prod, support etc.
So what I did was, I put my context.xml in its default location <TOMCAT_HOME>/conf.
Had the following in the resource config of context.xml:
<Resource name="jdbc/someDS"
auth="Container"
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.OracleDriver"
url="${appName.db.url}"
username="${appName.db.user}"
password="${appName.db.password}"
maxActive="30"
maxIdle="10"
defaultAutoCommit="true"
maxWait="-1"/>
I created three tomcat servers - server-dev, server-uat, server-support
and passed the corresponding values for each database in the vm arguments of tomcat in eclipse/intellij's tomcat server config (like shown below):
-DappName.db.url=jdbc:oracle:thin:#<DB_SERVER>:1521:<SID> -DappName.db.user=DB_USER -appName.db.password=DB_PASSWORD
The advantage is, the developers then don't need to change the database every-time, they just need to start a particular server. This was very handy and saved a lot of time during our development.
Adding the JNDI resources to Context.xml isn't enough. You will need to define their use in WEB-INF/web.xml also. Check this for a step by step.
As I understand it, your goal is to have application configuration outside of your .war to allow a system administrator to configure the system.
One way to achieve that is to not place the context.xml in your .war file but to distribute that file alongside with your .war.
This file then has to be placed placed in CATALINA_HOME/conf/Catalina/HOSTNAME/APPLICATIONPATH.xml (e.g. CATALINA_HOME/conf/Catalina/localhost/myapp.xml).
This way, the database connection information can be edited directly in the external context configuration file without changing the .war file, you won't need placeholders in that scenario.
This is not the most comfortable way for the user as he/she has to edit an xml file but it should be feasible for most system administrators...
You can find more information on tomcat context configuration at tomcat.apache.org/tomcat-5.5-doc/config/context.html
I'm not sure it's possible to load the details from a properties file but you can have the details in the central server.xml file rather than context.xml. Once you've achieved that, you could probably externalize the connection details using a standard XML entity reference.
Instead of putting your database connection details in the context.xml, put them in the server.xml under a section, and then add a ResourceLink element to the context.xml that creates a link between the global data source and your context.
Unfortunately the documentation is fairly weak for what you're trying to achieve.
Follow the instructions on the "Resource Definitions" section of this page (about half way down), and pay particular attention to the (tiny) ResourceLink section below it:
http://tomcat.apache.org/tomcat-5.5-doc/config/globalresources.html
If I don't have database connection information at build time, I'll just configure a resource reference and tell the admin what name they need to give the connection pool. They can configure everything in the Tomcat admin console and I never have to know about it. This also makes it easier to build a single WAR file and use it in multiple environments since the database configuration details aren't part of the WAR.
See also:
Apache Tomcat 6.0 JNDI Resources
If you do know the details at build time and want to bake them into the WAR, try Ant filters.

Categories