PDA

View Full Version : Spring/Hibernate/JBoss


tads
Aug 25th, 2005, 08:34 AM
I all :-)

I´m newbie with Spring.

Currently I´m using Jboss 3.2.3, Hibernate 2.14 and Oracle 9i.
I´ve created a SAR (jboss-service.xml) that initiates the SessionFactory.

I´m trying to use Spring with this architeture.
I´ve created the applicationContext.xml as following:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
<bean id="dataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:/sitds</value>
</property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate.LocalSessionFact oryBean">
<property name="dataSource"><ref bean="dataSource"/></property>
<property name="mappingResources">
<list>
<value>project/manager/AreaTO.hbm.xml</value>
.
.
.
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
net.sf.hibernate.dialect.OracleDialect
</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate.HibernateTransac tionManager">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>

<bean id="areaDAO"
class="project.manager.HibernateAreaDAO">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>

</beans>


When I start the JBoss, There is no in the log generated by JBoss about spring.

When I try to use a method like this:


query = " from AreaTO a";
query += " order by a.naArea";

list = (ArrayList) this.getHibernateTemplate().find(query);


The HibernateTemplate is null, so the above code doesn´t work.

Only the sar is initiated.

With SAR, we can shared the connection pool in the web, ejb and other.

How can I do this using spring?

Can somebody give a tip about this?

thank you very much

tads
Aug 25th, 2005, 10:08 AM
I forgot one detail. I´m using with Struts, too :oops:

cmgharris
Aug 25th, 2005, 10:11 AM
You say I´ve created a SAR (jboss-service.xml) that initiates the SessionFactory. without giving any details.

Here's how I did it, using SingletonBeanFactoryLocator, so you can get the same BeanFactory from an EJB or webapp:

public class OrderUnload extends org.jboss.system.ServiceMBeanSupport implements OrderUnloadMBean {
BeanFactoryReference bfr = null;
OrderUnloader unloader;

public void startService() {
BeanFactoryLocator bfl = SingletonBeanFactoryLocator.getInstance();
bfr = bfl.useBeanFactory("org.stl.wo.appcontext");
setUnloader((OrderUnloader)bfr.getFactory().getBea n("orderUnloader"));
}

public void unloadOrders() {
try {
unloader.unloadOrders();
} catch (Exception e) {
System.out.println("Download of Orders failed:");
e.printStackTrace();
}
}

public void stopService() {
if (bfr != null) {
bfr.release();
}
}

public void setUnloader(OrderUnloader unloader) {
this.unloader = unloader;
}
}

The fact that you don't get the Spring logs appearing in the jboss log makes me wonder whether the application context is actually being created.

tads
Aug 25th, 2005, 10:37 AM
Hi,

I´ve created the jboss-service.xml like this:


<server>
<mbean code="net.sf.hibernate.jmx.HibernateService" name="jboss.jca:service=HibernateFactory, name=HibernateFactory">
<depends>jboss.jca:service=RARDeployer</depends>
<depends>jboss.jca:service=LocalTxCM,name=sitds</depends>
<attribute name="MapResources">
project/manager/AreaTO.hbm.xml,
.
.
.
</attribute>
<attribute name="JndiName">java:/hibernate/HibernateFactory</attribute>
<attribute name="Datasource">java:/sitds</attribute>
<attribute name="Dialect">net.sf.hibernate.dialect.OracleDialect</attribute>
<attribute name="UseOuterJoin">true</attribute>
<attribute name="ShowSql">true</attribute>
<attribute name="UserTransactionName">UserTransaction</attribute>
<attribute name="TransactionStrategy">net.sf.hibernate.transaction.JTATransactionFactory</attribute>
<attribute name="TransactionManagerLookupStrategy">net.sf.hibernate.transaction.JBossTransactionManag erLookup</attribute>
</mbean>
</server>


This file (into META-INF) and the mapping files (*.hbm.xml) was
compressed into a file .sar.

The file jboss-app.xml was created to indicate
the .sar:


<?xml version="1.0"?>

<jboss-app>

<module>
<service>sit-hibernate.sar</service>
</module>

</jboss-app>


So, when the Jboss is started, I start the SessionFactory in an plugin
of Struts like this:


package project.web.struts.plugin;

import java.io.File;

import javax.naming.InitialContext;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;

import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.cfg.Configuration;

import org.apache.log4j.Logger;
import org.apache.struts.action.ActionServlet;
import org.apache.struts.action.PlugIn;
import org.apache.struts.config.ModuleConfig;

public class HibernatePlugin implements PlugIn
{
/**
* the key under which the SessionFactory instance is stored in the
* ServletContext.
*/
public static final String SESSION_FACTORY_KEY = SessionFactory.class
.getName();

/** Object to access log4j */
static Logger log = Logger.getLogger(HibernatePlugin.class);

/**
* indicates whether the SessionFactory instance will be stored in the
* ServletContext, or not.
*/
private boolean storedInServletContext = true;

/**
* the path to the xml configuration file. the path should start with a
* '/' character and be relative to the root of the class path. (DEFAULT:
* "/hibernate.cfg.xml")
*/
private String configFilePath = "/WEB-INF/hibernate.cfg.xml";

/** JNDI´s Name */
private String jndiName = "java:/hibernate/HibernateFactory";

/** servlet */
private ActionServlet servlet = null;

/** Module of configuration */
private ModuleConfig config = null;

/** Session Factory */
private SessionFactory factory = null;

/**
* Destroys the SessionFactory instance.
*/
public void destroy()
{
this.servlet = null;
this.config = null;

try
{
log.debug("Destroying SessionFactory...");

factory.close();

log.debug("SessionFactory destroyed...");
}
catch (Exception e)
{
log.error("Unable to destroy SessionFactory...(exception ignored)",
e);
}
}

/**
* Initializes the SessionFactory.
*
* @param servlet the ActionServlet instance under which the plugin will
* run.
* @param config the ModuleConfig for the module under which the plugin
* will run.
*
* @throws ServletException Exception
*/
public void init(ActionServlet servlet, ModuleConfig config)
throws ServletException
{
this.servlet = servlet;
this.config = config;

initHibernate();
}

/**
* Initializes Hibernate with the config file found at configFilePath.
*
* @throws ServletException Exception
*/
private void initHibernate() throws ServletException
{
Configuration configuration = null;
ServletContext context = null;

try
{
context = servlet.getServletContext();

String containerWeb = context.getServerInfo(); // 06/04/2004


InitialContext ctx = new InitialContext();

// SessionFactory ------------------------------------
this.factory = (SessionFactory)ctx.lookup(jndiName);


if (this.storedInServletContext)
{
log.debug("Storing SessionFactory in ServletContext...");
context.setAttribute(SESSION_FACTORY_KEY, this.factory);
}
}
catch (Throwable t)
{
log.error("Exception while initializing Hibernate.");
log.error("Rethrowing exception...", t);

throw (new ServletException(t));
}
}

/**
* Setter for property configFilePath.
*
* @param configFilePath New value of property configFilePath.
*
* @throws IllegalArgumentException Exception
*/
public void setConfigFilePath(String configFilePath)
{
if ((configFilePath == null) || (configFilePath.trim().length() == 0))
{
throw new IllegalArgumentException(
"configFilePath cannot be blank or null.");
}

if (log.isDebugEnabled())
{
log.debug("Setting 'configFilePath' to '" + configFilePath + "'...");
}

this.configFilePath = configFilePath;
}

/**
* Setter for property storedInServletContext.
*
* @param storedInServletContext New value of property
* storedInServletContext.
*/
public void setStoredInServletContext(String storedInServletContext)
{
if ((storedInServletContext == null)
|| (storedInServletContext.trim().length() == 0))
{
storedInServletContext = "false";
}

if (log.isDebugEnabled())
{
log.debug("Setting 'storedInServletContext' to '"
+ storedInServletContext + "'...");
}

this.storedInServletContext = new Boolean(storedInServletContext)
.booleanValue();
}
}


I´m trying to migrate this to used Spring too.

Thank you very much

[]´s

cmgharris
Aug 25th, 2005, 10:55 AM
It doesn't look to me as if the Spring ApplicationContext is created anywhere.
You either have to do this explicitly in code, or if you're using Spring MVC (which it seems you're not) it gets done for you by the DispatcherServlet.
I'm not sure what happens with the Spring/Struts integration, but it doesn't look like you're using that either.
There has to be something to cause your applicationContext.xml to be read and the ApplicationContext created.

tads
Aug 25th, 2005, 01:48 PM
Hi,

I discovered the problem in ApplicationContext.
Really the ApplicationContext was not being created.

Now the log generated is:



14:25:31,390 INFO [ContextLoader] Root WebApplicationContext: initialization started
14:25:31,390 INFO [Engine] Loading Spring root WebApplicationContext
14:25:31,750 INFO [XmlBeanDefinitionReader] Loading XML bean definitions from ServletContext resource [/WEB-INF/applicationContext.xml]
14:25:32,296 INFO [XmlWebApplicationContext] Bean factory for application context [Root WebApplicationContext]: org.springframework.beans.factory.support.DefaultL istableBeanFactory defining beans [dataSource,sessionFactory,transactionManager,area DAO]; root of BeanFactory hierarchy
14:25:32,390 INFO [XmlWebApplicationContext] 4 beans defined in application context [Root WebApplicationContext]
14:25:32,437 INFO [CollectionFactory] JDK 1.4+ collections available
14:25:32,484 INFO [XmlWebApplicationContext] Unable to locate MessageSource with name 'messageSource': using default [org.springframework.context.support.DelegatingMes sageSource@122fe15]
14:25:32,500 INFO [XmlWebApplicationContext] Unable to locate ApplicationEventMulticaster with name 'applicationEventMulticaster': using default [org.springframework.context.event.SimpleApplicati onEventMulticaster@192ee25]
14:25:32,515 INFO [UiApplicationContextUtils] No ThemeSource found for [Root WebApplicationContext]: using ResourceBundleThemeSource
14:25:32,562 INFO [DefaultListableBeanFactory] Pre-instantiating singletons in factory [org.springframework.beans.factory.support.Default ListableBeanFactory defining beans [dataSource,sessionFactory,transactionManager,area DAO]; root of BeanFactory hierarchy]
14:25:32,562 INFO [DefaultListableBeanFactory] Creating shared instance of singleton bean 'dataSource'
14:25:32,859 INFO [DefaultListableBeanFactory] Creating shared instance of singleton bean 'sessionFactory'
.
.
.
.
.
14:25:36,203 INFO [ConnectionProviderFactory] Initializing connection provider: org.springframework.orm.hibernate.LocalDataSourceC onnectionProvider
14:25:36,218 INFO [TransactionManagerLookupFactory] No TransactionManagerLookup configured (in JTA environment, use of process level read-write cache is not recommended)
14:25:36,218 INFO [SettingsFactory] Use scrollable result sets: true
14:25:36,218 INFO [SettingsFactory] Use JDBC3 getGeneratedKeys(): false
14:25:36,218 INFO [SettingsFactory] Optimize cache for minimal puts: false
14:25:36,218 INFO [SettingsFactory] Query language substitutions: {}
14:25:36,218 INFO [SettingsFactory] cache provider: net.sf.ehcache.hibernate.Provider
14:25:36,218 INFO [Configuration] instantiating and configuring caches
14:25:36,218 INFO [SessionFactoryImpl] building session factory
14:25:36,703 INFO [SessionFactoryObjectFactory] no JNDI name configured
14:25:36,718 INFO [DefaultListableBeanFactory] Creating shared instance of singleton bean 'transactionManager'
14:25:36,859 INFO [HibernateTransactionManager] Using DataSource [org.jboss.resource.adapter.jdbc.WrapperDataSource @1bd8c6e] of Hibernate SessionFactory for HibernateTransactionManager
14:25:36,906 INFO [DefaultListableBeanFactory] Creating shared instance of singleton bean 'areaDAO'
14:25:37,015 INFO [ContextLoader] Using context class [org.springframework.web.context.support.XmlWebApp licationContext] for root WebApplicationContext
14:25:37,015 INFO [ContextLoader] Root WebApplicationContext: initialization completed in 5625 ms
14:25:37,031 INFO [Engine] StandardWrapper[/sigmai:default]: Loading container servlet default
14:25:37,031 INFO [ContextLoader] Root WebApplicationContext: initialization started
14:25:37,031 INFO [Engine] Loading Spring root WebApplicationContext
14:25:37,046 INFO [XmlBeanDefinitionReader] Loading XML bean definitions from ServletContext resource [/WEB-INF/applicationContext.xml]
14:25:37,125 INFO [XmlWebApplicationContext] Bean factory for application context [Root WebApplicationContext]: org.springframework.beans.factory.support.DefaultL istableBeanFactory defining beans [dataSource,sessionFactory,transactionManager,area DAO]; root of BeanFactory hierarchy
14:25:37,125 INFO [XmlWebApplicationContext] 4 beans defined in application context [Root WebApplicationContext]
14:25:37,125 INFO [XmlWebApplicationContext] Unable to locate MessageSource with name 'messageSource': using default [org.springframework.context.support.DelegatingMes sageSource@1428ffa]
14:25:37,125 INFO [XmlWebApplicationContext] Unable to locate ApplicationEventMulticaster with name 'applicationEventMulticaster': using default [org.springframework.context.event.SimpleApplicati onEventMulticaster@fa8ba9]
14:25:37,125 INFO [UiApplicationContextUtils] No ThemeSource found for [Root WebApplicationContext]: using ResourceBundleThemeSource
14:25:37,125 INFO [DefaultListableBeanFactory] Pre-instantiating singletons in factory [org.springframework.beans.factory.support.Default ListableBeanFactory defining beans [dataSource,sessionFactory,transactionManager,area DAO]; root of BeanFactory hierarchy]
14:25:37,125 INFO [DefaultListableBeanFactory] Creating shared instance of singleton bean 'dataSource'
14:25:37,125 INFO [DefaultListableBeanFactory] Creating shared instance of singleton bean 'sessionFactory'




But, when I try execute a method of HibernateTemplate, this is null.
I have DAOFactory and the DAO´s:



//================================================== ===================================
public abstract class DAOFactory
{
public static final int HIBERNATE = 1;

/**
* Returns the Factory used by DAOs. Only use Hibernate in this case.
*
* @return DAOFactory
*/
public static DAOFactory getDAOFactory(int whichFactory)
{
switch (whichFactory)
{
case HIBERNATE:
return new HibernateDAOFactory();
default:
return null;
}
}

/**
* Returns the Area DAO
*
* @return AreaDAO
*/
public abstract AreaDAO getAreaDAO();
}

//================================================== ===================================
public class HibernateDAOFactory extends DAOFactory
{

/**
* Returns the Area DAO
*
* @return AreaDAO
*/
public AreaDAO getAreaDAO()
{
return new HibernateAreaDAO();
}
}

//================================================== ===================================
public class HibernateAreaDAO extends HibernateDaoSupport implements AreaDAO
{
/**
* List the all Area.
*
* @return arrayList
*/
public ArrayList find()
{
ArrayList list = null;
String query = "";
boolean flagWhere = false;

query = " from AreaTO a";
query += " order by a.naArea";

// ERROR: this.getHibernateTemplate() returns null


list = (ArrayList) this.getHibernateTemplate().find(query);

return list;
}

}


I don´t know what occurs. I think that I forgeting some thing.

Thanks for your help!!! :-)