Confusion reigns
rdiddly Jul 3, 2013 10:50 AMI am trying to move from EJB 2.1 to EJB 3.1 (and JBoss 4.2.2 to JBoss AS 7). I have posted numerous questions here, but it seems that either there's no one here to answer questions or I'm not asking the right questions, so I'll keep trying to formulate the right question.
I have taken one of my SLSBs and gone through many different attempts to make it available to a helper class deployed in a war in the same ear as contains the ejb-jar that has the SLSB.
My persistence.xml file is packaged in a jar file and deployed to the ear's lib folder.
1) When I don't include markup in ejb-jar.xml declaring the ContentManagerBaan, I don't see any output from JBoss on startup to suggest that the Bean has been bound to JNDI, even though the Bean is declared with the @Stateless and @LocalBean annotations, so I define it in ejb-jar.xml. Using this strategy, I'm able to lookup the Bean from within the helper class packaged in the war.
Here's the code and markup related to my issue:
public interface ContentManagerBusiness {
public Banner getTopNavBarBanner();
}
public class ContentManagerBeanBase implements ContentManagerBusiness {
private static final Logger log = Logger.getLogger(ContentManagerBeanBase.class);
@PersistenceContext(unitName="app")
private EntityManager em;
@Override
public Banner getTopNavBarBanner() {
Banner answer = null;
try {
Session hbmSession = (Session) em.getDelegate();
Object o = hbmSession.getNamedQuery(Banner.NamedQuery.GetTopNavBarBanner.getQueryName())
.setMaxResults(1)
.uniqueResult();
answer = (Banner) o;
} catch (Exception e) {
log.error("Failed getting content for topNavBar banner.", e);
}
return answer;
}
}
@Stateless
@LocalBean
public class ContentManagerBean extends ContentManagerBeanBase {
}
persistence.xml:
<persistence-unit name="app" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/appDB</jta-data-source>
<jar-file>../appEJB.jar</jar-file>
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
<property name="hibernate.cache.use_second_level_cache" value="true" />
<property name="hibernate.cache.use_query_cache" value="true" />
</properties>
</persistence-unit>
ejb-jar.xml:
<session>
<ejb-name>ContentManager</ejb-name>
<local>com.app.session.contentManager.ContentManagerLocal</local>
<ejb-class>com.app.session.contentManager.ejb.ContentManagerBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
When my pom.xml declared the scope of the dependency on the ejb jar for the war's build as compile, I found that the ejb jar file was included in the war's lib folder. With this setup I was able to run the code to the point where I had a ClassCastException in the ContentManagerBean when attempting to cast the return of the uniqueResult call to an instance of Banner. This appeared to be a classloader problem, and I thought it made no sense to include the ejb jar in the war's lib folder if it was being deployed as part of the ear, so I changed the scope of the dependency to provided. This removed the ejb jar from the war's lib folder, leaving me with a single definition of the Banner class. (The Banner class is a model class, mapped by a hbm.xml descriptor. The class is defined in the ejb's jar.)
2) After removing the ejb jar from the war's lib folder, I find that the PersistenceContext declared in the ContentManagerBusinessBase is null at run time.
I hope that someone can shed some light on what it is I'm doing wrong with the information I've provided. Short of that, I hope that someone will ask me to provide some additional information, or give me a clue as to what I should look at. I am using Oracle's online docs on JEE 6 and O'Reilly's Enterprise JavaBeans 3.1 and searches all over the internet, but so far have had no luck figuring out what I'm doing wrong.
Thanks in advance.