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.
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?
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
--
PGP Key Id: E2BE72FC
Public Key: http://www.harrigan.info/public.asc