import java.io.Serializable;
public class CanNotCreateEntityException extends DatabaseException implements Serializable {
private static final long serialVersionUID = 7267419933728670364L;
public CanNotCreateEntityException(){
super();
}
public CanNotCreateEntityException(String message) {
super(message);
}
public CanNotCreateEntityException(Throwable cause) {
super(cause);
}
public CanNotCreateEntityException(String message, Throwable cause) {
super(message, cause);
}
}
In einer Bean gibt es eine Methode, die diese wirft.
Code:
@Override
public User addUser(Person p, String name, String pass) throws CanNotCreateEntityException{
try{
User u = new User(p, name, pass);
em.persist(u);
return u;
}
catch(Exception cnc){
throw new CanNotCreateEntityException("Benutzer-Datensatz konnte nicht angelegt werden. " + cnc.getMessage());
}
}
und im Control einen Block, der diese Methode aufruft.
Code:
try {
bean.addUser(new Person("Anonym", "Anonymus"), "user", "password");
}
catch (CanNotCreateEntityException e) {
JOptionPane.showMessageDialog(log.getContentPane(), "Die Person konnte nicht hinzugefügt werden.");
}
catch (Exception e){
JOptionPane.showMessageDialog(log.getContentPane(), "TEST");
}
Mein Problem ist nun, dass obwohl in der Bean jede Exception eine CanNotCreateEntityException wirft, diese im Control nicht geworfen wird und nur der catch-Block der Standard-Exception aufgerufen wird. Warum?
Mein (zugegen, nicht sehr naheliegender) erster Gedanke wäre, die Fehlermeldung mal ausgeben und schauen was sie denn genau ist und woher sie kommt. :wink:
Wäre auch gut, wenn du uns das Ergebnis (bzw. den Stacktrace) zeigen kannst.
Die Exception entsteht, weil der User zum zweiten mal angelegt wird und das Benutzername Feld auf unique eingestellt ist. Nur die Exception sollte dann doch in der Bean entstehen. Aber sie entsteht erst im Control. Warum?
1. Was bedeutet "Die Exception entsteht erst im Control"?
2. Du hast ja dankenswerterweise in Deiner Exception-Klassen den Konstruktor mit dem String und dem Throwable implementiert; nutze den doch auch, damit das Exception-Chaining funktioniert.
Statt
Code:
throw new CanNotCreateEntityException("Benutzer-Datensatz konnte nicht angelegt werden. " + cnc.getMessage());
also besser
Code:
throw new CanNotCreateEntityException("Benutzer-Datensatz konnte nicht angelegt werden. ", cnc);
oder auch
Code:
throw new CanNotCreateEntityException("Benutzer-Datensatz konnte nicht angelegt werden: " + cnc.getMessage(), cnc);
Damit meine ich, dass die Methode bean.adduser(...) aufgerufen wird und der try Block der Methode
Code:
try{
User u = new User(p, name, pass);
em.persist(u);
return u;
}
fehlerfrei durchlaufen wird. Dort entsteht der Fehler, der durch die Erstellung des Users mit einem schon bestehendem Namen, nicht. Also der try Block wird fehlerfrei durchlaufen. Erst im try-catch Block des Controls wird diese Exception ausgelößt. Deshalb funktionieren die throws auch nicht.
Code:
try {
bean.addUser(new Person("Anonym", "Anonymus"), "user", "password");
}
catch (CanNotCreateEntityException e) {
JOptionPane.showMessageDialog(log.getContentPane(), "Die Person konnte nicht hinzugefügt werden.");
}
[color=red] catch (Exception e){
JOptionPane.showMessageDialog(log.getContentPane(), "TEST");
}[/color]
Der rote catch Block wird ausgelößt.
zu 2) Hab ich gemacht, aufgrund von 1) funktioniert es nicht.
Die Initialiesierung der Bean sieht folgendermaßen aus:
Code:
InitialContext ctx;
try {
ctx = new InitialContext();
bean = (RechnerManagerRemote) ctx.lookup("ejb/RechnerManagerBeanJNDI");
} catch (NamingException e) {
JOptionPane.showInternalMessageDialog(log, "Die Session konnte nicht eröffnet werden.");
e.printStackTrace();
}
Es gibt kine @EJB Anotation. Könnte es daran liegen?
Von den spärlichen Informationen die du bisher geliefert hast, wäre die IMHO einfachste Erklärung: du hast eine NullPointerException weil "bean" null ist (wer weiss schon, ob diese Referenz richtig in deinem Programm umhergereicht wird...).
Tut mir leid, zumindest ich kann nicht erraten was bei dir passiert. Andere in diesem Forum, die sich mit EE besser auskennen, könnten vielleicht.
Ich habe nichts gemacht und nun erscheint keine Exception sichtbar. Es wird nur folgende in den ServerLog des Glassfish Servers eingetragen
Code:
[#|2008-09-09T20:32:25.034+0200|WARNING|sun-appserver9.1|oracle.toplink.essentials.session.file:/C:/Server/Glassfish/domains/domain1/applications/j2ee-apps/ITVerwaltung/ITVerwaltungEJB_jar/-person|_ThreadID=21;_ThreadName=p: thread-pool-1; w: 8;_RequestID=54521ed5-9151-4555-9d4d-98083eec6c22;|
Local Exception Stack:
Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2.0.1 (Build b04-fcs (04/11/2008))): oracle.toplink.essentials.exceptions.DatabaseException
Internal Exception: java.sql.SQLTransactionRollbackException: Eine Sperre konnte innerhalb der vorgegebenen Zeit nicht angefordert werden.
Error Code: -1
Call: UPDATE SEQUENCE SET SEQ_COUNT = SEQ_COUNT + ? WHERE SEQ_NAME = ?
bind => [50, SEQ_GEN]
Query: DataModifyQuery()
at oracle.toplink.essentials.exceptions.DatabaseException.sqlException(DatabaseException.java:311)
at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:654)
at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:703)
at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:492)
at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:452)
at oracle.toplink.essentials.internal.sessions.AbstractSession.executeCall(AbstractSession.java:690)
at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:214)
at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.executeNoSelectCall(DatasourceCallQueryMechanism.java:257)
at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.executeNoSelect(DatasourceCallQueryMechanism.java:237)
at oracle.toplink.essentials.queryframework.DataModifyQuery.executeDatabaseQuery(DataModifyQuery.java:86)
at oracle.toplink.essentials.queryframework.DatabaseQuery.execute(DatabaseQuery.java:628)
at oracle.toplink.essentials.internal.sessions.AbstractSession.internalExecuteQuery(AbstractSession.java:1834)
at oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:952)
at oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:924)
at oracle.toplink.essentials.sequencing.QuerySequence.update(QuerySequence.java:344)
at oracle.toplink.essentials.sequencing.QuerySequence.updateAndSelectSequence(QuerySequence.java:283)
at oracle.toplink.essentials.sequencing.StandardSequence.getGeneratedVector(StandardSequence.java:96)
at oracle.toplink.essentials.sequencing.DefaultSequence.getGeneratedVector(DefaultSequence.java:168)
at oracle.toplink.essentials.sequencing.Sequence.getGeneratedVector(Sequence.java:281)
at oracle.toplink.essentials.internal.sequencing.SequencingManager$Preallocation_Transaction_NoAccessor_State.getNextValue(SequencingManager.java:420)
at oracle.toplink.essentials.internal.sequencing.SequencingManager.getNextValue(SequencingManager.java:848)
at oracle.toplink.essentials.internal.sequencing.ClientSessionSequencing.getNextValue(ClientSessionSequencing.java:110)
at oracle.toplink.essentials.internal.descriptors.ObjectBuilder.assignSequenceNumber(ObjectBuilder.java:240)
at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.assignSequenceNumber(UnitOfWorkImpl.java:355)
at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.registerNotRegisteredNewObjectForPersist(UnitOfWorkImpl.java:3260)
at oracle.toplink.essentials.internal.ejb.cmp3.base.RepeatableWriteUnitOfWork.registerNotRegisteredNewObjectForPersist(RepeatableWriteUnitOfWork.java:339)
at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.registerNewObjectForPersist(UnitOfWorkImpl.java:3220)
at oracle.toplink.essentials.internal.ejb.cmp3.base.EntityManagerImpl.persist(EntityManagerImpl.java:205)
at com.sun.enterprise.util.EntityManagerWrapper.persist(EntityManagerWrapper.java:440)
at ch.telag.it.beans.RechnerManagerBean.addUser(RechnerManagerBean.java:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.enterprise.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1067)
at com.sun.enterprise.security.SecurityUtil.invoke(SecurityUtil.java:176)
at com.sun.ejb.containers.BaseContainer.invokeTargetBeanMethod(BaseContainer.java:2895)
at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:3986)
at com.sun.ejb.containers.EJBObjectInvocationHandler.invoke(EJBObjectInvocationHandler.java:203)
at com.sun.ejb.containers.EJBObjectInvocationHandlerDelegate.invoke(EJBObjectInvocationHandlerDelegate.java:117)
at $Proxy41.addUser(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.corba.ee.impl.presentation.rmi.ReflectiveTie._invoke(ReflectiveTie.java:154)
at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(CorbaServerRequestDispatcherImpl.java:687)
at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:227)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(CorbaMessageMediatorImpl.java:1846)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:1706)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleInput(CorbaMessageMediatorImpl.java:1088)
at com.sun.corba.ee.impl.protocol.giopmsgheaders.RequestMessage_1_2.callback(RequestMessage_1_2.java:223)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:806)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.dispatch(CorbaMessageMediatorImpl.java:563)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.doWork(CorbaMessageMediatorImpl.java:2567)
at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:555)
Caused by: java.sql.SQLTransactionRollbackException: Eine Sperre konnte innerhalb der vorgegebenen Zeit nicht angefordert werden.
at org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(Unknown Source)
at org.apache.derby.client.am.SqlException.getSQLException(Unknown Source)
at org.apache.derby.client.am.PreparedStatement.executeUpdate(Unknown Source)
at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:647)
... 55 more
Caused by: org.apache.derby.client.am.SqlException: Eine Sperre konnte innerhalb der vorgegebenen Zeit nicht angefordert werden.
at org.apache.derby.client.am.Statement.completeExecute(Unknown Source)
at org.apache.derby.client.net.NetStatementReply.parseEXCSQLSTTreply(Unknown Source)
at org.apache.derby.client.net.NetStatementReply.readExecute(Unknown Source)
at org.apache.derby.client.net.StatementReply.readExecute(Unknown Source)
at org.apache.derby.client.net.NetPreparedStatement.readExecute_(Unknown Source)
at org.apache.derby.client.am.PreparedStatement.readExecute(Unknown Source)
at org.apache.derby.client.am.PreparedStatement.flowExecute(Unknown Source)
at org.apache.derby.client.am.PreparedStatement.executeUpdateX(Unknown Source)
... 57 more
|#]
Zum letzten Mal: schreib doch - zumindest testweise - in den catch-Block ein printStackTrace; damit siehst Du eindeutig, welceh Exception kommt, und wo sie geworfen wurde.
Wie schon oben beschrieben handelt es sich um eine EJBException, die im Try-Block des Controls aufgerufen wird. Der Fehler lag darin, das die Synchronisierung mit der Datenbank später stattfindet. durch die Anweisung em.flush in der Bean ist dieser Fehler Behoben.