ejb@glassfish.java.net

Templating Stateless EJBs...

From: Drayton Brown <draytonbrown_at_gmail.com>
Date: Thu, 14 May 2009 14:33:42 +0100

Hi all!

Please forgive me if this is not the correct place for this query, and if so
I would greatly appreciate some advice on where I could better post this.

Basically I would like to implement the classes which I have outlined below.
I'm fairy confident that the Entity classes are ok, but I have included them
here for clarity.
I make use of template classes quite extensively, which I believe has lead
to an exception which I've posted below...

ENTITIES

@MappedSuperclass
public abstract class Base implements Serializable
{
//This is the base class for all entities. It maps fields common in all
entities such as the primary key, the time stamps for when the entity was
created and last updated, etc...}

@MappedSuperclass
public abstract class StatefullEntity<T extends myProject.entities.State>
extends Base {

//This is the super class for all entities which have a state, it maps the
stateful entity to a state type. Like this:

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "state_id", nullable = false)
    private T state;

    public T getState() {
        return state;
    }

    public void setState(T state) {
        this.state = state;
    }
}

@MappedSuperclass
public abstract class State extends Base {
//This is a super class for all state types. It includes fields common to
all state entities, such as name, the service level agreement for how long
an entity is allowed to be in this state, etc...
}

@Entity
@Table(name = "device_states")
public class DeviceState extends State {
//This entity represents a state that a device may be in.
}

@Entity
@Table(name = "devices")
public class Device extends StatefullEntity<DeviceState> implements
Serializable {
//This entity represents a device on the real world. It is statefull (i.e.
it can be 'STARTING', RUNNING' etc.) and its state types are represented by
the 'DeviceState' entity
}

FACADES

public abstract class Base<E extends myProject.entities.Base> {
//This is the base for all my facades. It inlcudes methods common to all
facades, like 'create(E entity)' which persists a given entity.
}

public abstract class StatefullEntityFacade<SE
extends myProject.entities.StatefullEntity, S
extends myProject.entities.State>
        extends Base<SE> {
//This is the super class for all facades which manage entities which have a
state. It includes methods like 'public List<SE> findByState(S state)'
}

public abstract class StateFacade<S extends myProject.entities.State>
        extends Base<S>{
//This is the super class for all facades that manage states. For example, I
have included a method 'public S findByName(String stateName)' which returns
a state based on the name passed in.
}

@Stateless
public class DeviceStateFacade extends StateFacade<DeviceState> implements
DeviceStateFacadeLocal{
//For me this class is empty as I have all the methods I would like
implemented in 'StateFacade'. This class just serves the purpose of defining
which state type I would like to manage
}

@Stateless
public class DeviceFacade extends StatefullEntityFacade<Device, DeviceState>
implements DeviceFacadeLocal {
//This class is the facade that manages devices.
}

INTERFACES

public abstract interface Base<T extends myProject.entities.Base> {

    public void create(Device t);

    public void edit(Device t);

    public void remove(Device t);

    public Device find(Object id);

    public List<Device> find(Integer startRow, Integer pageSize);

    public List<Device> findAll();

}

public abstract interface StatefullEntityFacadeLocal<SE
extends myProject.entities.StatefullEntity, S
extends myProject.entities.State> extends Base<SE> {

    public List<SE> findByState(S state);
}

public abstract interface StateFacadeLocal<S
extends myProject.entities.State> extends Base<S> {

    public S findByName(String stateName) throws NoResultException,
NonUniqueResultException;
}

@Local
public interface DeviceStateFacadeLocal extends
StateFacadeLocal<DeviceState> {
}

@Local
public interface DeviceFacadeLocal extends
StatefullEntityFacadeLocal<Device, DeviceState>{

    public Device findByName(String name) throws DeviceFacadeException;
}

EXCEPTION

Deploying application in domain failed; Exception [TOPLINK-28018] (Oracle
TopLink Essentials - 2.1 (Build b44-fcs (07/31/2008))):
oracle.toplink.essentials.exceptions.EntityManagerSetupException
Exception Description: predeploy for PersistenceUnit [Spooler-ejbPU] failed.
Internal Exception: Exception [TOPLINK-30007] (Oracle TopLink Essentials -
2.1 (Build b44-fcs (07/31/2008))):
oracle.toplink.essentials.exceptions.PersistenceUnitLoadingException
Exception Description: An exception was thrown while loading
class: myProject.facades.interfaces.local.DeviceFacadeLocal to check whether
it implements @Entity, @Embeddable, or @MappedSuperclass.
Internal Exception: java.lang.ClassNotFoundException:
myProject.facades.interfaces.local.DeviceFacadeLocal

From this exception I would think that TopLink is complaining that there are
annotations missing from my local interface 'DeviceFacadeLocal'. However I
am certain that this is not the real problem since the annotations
it suggests are Entity specific from what I understand.

If any further information is needed to understand the problem, please feel
free to let me know.

I'm using Glassfish 2 ur2 (Sun Java System Application Server 9.1.1 (build
b44-fcs))

If anyone could help me out with this I would appreciate it greatly!

Thanks
Drayton