David Harrigan wrote:
> Hi,
>
> Firstly, I really do apologise for the length of this email, but it's the
> only way I can explain what is going on to support my question. I've hit
> a real problem in trying to get something which I thought would work, to
> actually work.
>
> I've pasted the code below, but my question is this:
>
> It appears that I can't have a sub-subclass of a @Remote Interface. In
> the example
> below ItemControllerBean and TagsControllerBean reference the same
> @Remote interface. If I try to deploy this, Glassfish blows up saying
> it can't rebind the EJB. If I
> remove one of the @Remote's (say from TagsControllerBean) it all works
> fine.
>
Multiple EJBs should be able to have the same business interfaces. Do
you have sun-ejb-jar.xml to specify a <jndi-name> for each bean? This
may help avoid conflict.
> This is a problem since I'm trying to use generics to simplify my
> code. You see,
> the GenericControllerBean only knows how to CRUD types - this is
> common across all of my entities. The specialisation comes into the
> subtype (i.e., ItemControllerBean) since it knows how to do some
> specific work that only relates to Items.
>
> So, what am I missing here? Is what I am attempting not allowed
> according to the EJB specification? Or perhaps it is allowed, but GF
> should be able to be clever in knowing that I'm referencing the same
> Remote interface.
>
> On another note, but relevant, why can't it be the case that if I
> remove @Remote from both ItemControllerBean and TagsControllerBean
> that the system should know that because these two objects inherit -
> indirectly - from GenericController, that GenericController should be
> treated as the @Remote interface - instead of me explicitly setting
> @Remote on these two classes? Is that not allowed according to EJB
> spec?
Not supported in EJB 3.0. For this to work, your bean classes need to
have the intended business interface in its implements clause.
-cheng
>
> I thank you for taking the time to look at this. I do hope you can help.
>
> -=david=-
>
> Here's the class hierarchy (I've removed some code (exceptions,
> logging)):
>
> @Remote
> public interface GenericController<T> {
>
> void insert(T type) throws DatabaseException;
> void remove(T type) throws DatabaseException;
> T update(T type) throws DatabaseException;
> T getById(int typeId) throws DatabaseException;
> String getEntityName();
> EntityManager getEntityManager();
> }
>
> public class GenericControllerBean<T> implements GenericController<T> {
>
> private final Class<T> entityClass;
> private final String entityClassName;
>
> @PersistenceContext(unitName = "mediaPu")
> private EntityManager em;
>
> @SuppressWarnings("unchecked")
> public GenericControllerBean() {
> this.entityClass =
> (Class<T>)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];
>
> entityClassName = entityClass.getSimpleName();
> }
>
> @SuppressWarnings("unchecked")
> public GenericControllerBean(final EntityManager em) {
> this();
> this.em = em;
> }
>
> @Override
> public String getEntityName() {
> return entityClassName;
> }
>
> @Override
> public EntityManager getEntityManager() {
> return em;
> }
>
> @Override
> public T getById(final int typeId) {
> return em.find(entityClass, typeId);
> }
>
> @Override
> public void insert(final T type) {
> em.persist(type);
> }
>
> @Override
> public void remove(final T type) throws DatabaseException {
> em.remove(type);
> }
>
> @Override
> public T update(final T type) throws DatabaseException {
> em.merge(type);
> }
> }
>
> @Stateless
> @Remote(GenericController.class)
> public class ItemControllerBean extends GenericControllerBean<Item> {
> public ItemControllerBean() {
> }
>
> public ItemControllerBean(final EntityManager em) {
> super(em);
> }
>
> public Item getItemById(final int itemId) throws DatabaseException {
> return getEntityManager().find(Item.class, itemId);
> }
> }
>
> @Stateless
> @Remote(GenericController.class)
> public class TagsControllerBean extends GenericControllerBean<Tags> {
>
> public TagsControllerBean() {
>
> }
>
> public TagsControllerBean(final EntityManager em) {
> super(em);
> }
>
> }
>
> In a WebService, I have this
>
> @EJB
> ItemControllerBean itemController
>