Technical FAQ:Questions about WebLogic EJBFAQ Index
The following SQLException was thrown from my JDBC code: "The coordinator has rolled back the transaction. No further JDBC access is allowed within this transaction."What's going on? This exception, which is thrown by the WebLogic JTS JDBC driver, means that the transaction in which the JDBC Connection was participating was rolled back at some point prior to or during the JDBC call. The rollback may have happened in an earlier EJB invoke that was part of the transaction or the rollback may have occurred because the transaction timed out. In either case, the transaction will be rolled back, the connection returned to the pool and the database resources released. In order to proceed, the JTS JDBC Connection must be closed and reopened in a new transaction.
I'm having trouble accessing a Microsoft Access database using EJB and the JDBC-ODBC bridge. What's going on? The Microsoft Access database does not support the type of transaction processing required for use with EJB and the JDBC-ODBC bridge. We recommend that you use another, more robust database such as Microsoft's SQL Server, Informix, Sybase, or Oracle.
How can I make my EJBeans compile faster? By default, ejbc uses javac as a compiler. For faster performance, specify a different compiler (such as Symantec's sj) using the -compiler flag. Note that when you use the -compiler flag, you must set both the -classpath and -d flags.
How can I implement my own custom finder methods for a container-managed bean? Bean-provided finder methods are not allowed under the EJB spec (section 9.10.6). To implement your own finder, you have to use bean-managed persistence. WebLogic supports an extensive list of container-generated finder methods, which are documented in The WebLogic Server EJB environment.
When my EJB application produces a rollback exception, the application seems to come to a complete halt. Is there something I can do to optimize how these exceptions are handled? This problem has been observed when running Windows NT and Oracle and may be due to the way that NT prioritizes threads. The problem is currently under investigation by WebLogic. You may be able to improve performance of your application by decreasing the number of execute threads and increasing the number of connections in the connection pools. For database intensive applications, this is generally a good idea anyway, because the extra threads will waste time waiting for a database connection to become available. Remember that you should set the number of execute threads at least one higher than the number of connections in the connection pool.
We are using WebLogic COM from a Visual Basic client to access EJBeans that are deployed under WebLogic. If a bean method throws an exception, is it possible to get the exception object, invoke a method on it and then determine if the error generated by Visual Basic is a ValidationException or a RemoteException? Unfortunately, there are many things you can't do in Visual Basic that you can do in Java. When using Visual Basic, you are limited to looking up RMI and EJB objects and calling methods on those objects. The best way to handle exceptions is to catch them in the EJBean and return an error message or code to the Visual Basic client.
I am using bean-managed persistence. Does my persistence mechanism need to use the WebLogic JTS driver? Yes, you must use the WebLogic JTS pool driver for bean-managed EJB persistence. Please see The WebLogic Server EJB Environment for instructions. You must set up a connection pool for use with EJB, and you must access that pool only with the JTS pool driver. WebLogic has successfully tested EJB persistence with both the jDriver for Oracle driver and Cloudscape.
In late June 1998, WebLogic discovered (and reported to Microsoft) a Microsoft SDK for Java bug that affects EJB users. Microsoft SDK for Java serializes objects in a manner that is different from what other JVMs expect, and which causes serialization problems when using EJBeans. It means that you must use Microsoft SDK For Java instead of Java when running any EJB utilities such as DDCreator or the EJB compiler (ejbc) if you intend to run WebLogic under Microsoft SDK For Java and use EJBeans. See the EJB examples for a build script (buildms.bat) that demonstrates this. I downloaded WebLogic 3.0.3, the version that has EJB, to experiment a little with EJB. When I bring up a lot of clients using the same bean, my program eventually stops working. What's the problem? WebLogic EJB in version 3.0.3 is based on the 0.8 Enterprise JavaBean specification. In version 3.0.3, WebLogic released an early availability version of Enterprise JavaBeans -- before the specification was considered fully ready -- to give our customers some experience with the API. There are some problems in concurrency control, which is based on a transitional version of JTS (Java Transaction Services) expect, and which causes serialization problems when using EJBeans. It means that you must use Microsoft SDK for Java instead of Java when running any EJB utilities such as DDCreator or the EJB compiler (ejbc) if you intend to run WebLogic under Microsoft SDK for Java and use EJBeans. See the EJB examples for a build script (buildms.bat) that demonstrates this.
When writing my EJBeans, is there anything that I should keep in mind to make my beans portable and compatible with EJB servers today and in the future? If you add code that imports WebLogic-specific classes, such as weblogic.security.acl.Security, then you will have made your bean specific to WebLogic. This may be a problem if you are building a bean for third-party use that needs to run in any EJB-compliant server. The following note from Sun describes three methods that will be changed in a future release of EJB.
Note on EJB forward compatibility WebLogic is following option (b): it currently supports these methods, and will deprecate them in a future release of EJB.
I'd like to use the WebLogic EJB service and plug it into my CORBA-based architecture. I can make my ORB work with JavaBlend. But how does WebLogic EJB fit into the picture? Currently you cannot export a WebLogic EJBean to CORBA directly. We are looking at adding this in the future. For now, you can gateway to your EJBeans via the WebLogic Remote and WebLogic Events services which are directly exportable to CORBA. We agree on the importance of object-relational mapping. Stay tuned.
Why is my WebLogic Server running under Microsoft SDK for Java throwing an exception when it loads my EJBeans? There is an incompatibility in the way in which JavaSoft SDK and Microsoft SDK for Java serialize objects, in this case with javax.ejb.deployment.SerializableField. We have logged an issue with Microsoft, but until it is fixed, you need to "create" your EJBeans (such as the EJB examples) using jview.exe instead of Sun's java.exe. Here is how to do this for the examples shipped with WebLogic:
We have received verification that the bug (the removal of a class initializer resulted in a different serialization ID) has been fixed in the final SDK 3.0 VM.
Why is there no polymorphic-type response from a create() or find() method? Section 9.7.8 of the EJB 1.0 spec reads: 'The return type for a create method must be the enterprise Bean's remote interface type.' Further on, it reads: 'The return type for a finder method must be the enterprise Bean's remote interface type, or a collection thereof.' The weblogic.ejbc compiler strictly checks this and prohibits any polymorphic type of response from a create or find method. I'd like a method in the base class for a home interface such as: public BaseEntityBean findByPrimaryKey(BasePK key); I'd like to polymorphically call any valid methods on BaseEntityBean. But since I can't do this, I'm forced to use reflection to invoke the method I want. The reason the create() and find() methods are not polymorphic is much the same reason constructors are not polymorphic in Java. The derived classes generally do not know or cannot initialize the base class properly. In the case of the finders, the same argument cannot be made. We have in the past loosened restrictions that JavaSoft has made when it was determined that our customers' benefit would outweigh any objections. The issue here is portability: someone may do something that they didn't realize was actually against the specification and think that they can take their EJBean to another EJB server without a problem.
When are ejbActivate() and ejbPassivate() called? For entity beans, when the EJBean goes from the pooled to the ready state, ejbActivate() is called. When it goes from the ready to the pooled state, ejbPassivate() is called. For stateful session beans, ejbPassivate() is called when the cache is full and the EJBean is sent to the backing store, and ejbActivate() is called when the bean returns from the backing store. For stateless session beans, these methods are never called.
How do I reference one EJBean from within another EJBean? Example: myABean and myBBean are two EJBeans: public class myABean implements EntityBean {...} public class myBBean implements EntityBean {...}myABean's interface is myAInterface; myBBean's interface is myBInterface: public interface myAInterface extends EJBObject, Remote {...} public interface myBInterface extends EJBObject, Remote {...}To reference a myBBean from within myABean, reference myBBean directly: public class myABean implements EntityBean { ... myBInterface b; ... }However, you must make sure that myABean's member variable 'b' cannot instantiate and hold an instance of a myBBean. Instead, myABean must do a JNDI lookup of myBBean's home, and then myBBeanHome bHome = // JNDI lookup myBInterface b = bHome.find(); b = bHome.create();To make the myBBean persistent, store the primary key, and then with load(), restore and findByPrimaryKey() the entity bean. An example using a similar technique for non-primitive attributes is shown in a previous question.
Why are re-entrant EJBeans dangerous? According to section 9.6 of the EJB 1.0 specification, it is best to avoid re-entrant calls for entity beans. A re-entrant call is when a method of bean A calls a method of bean B which in turn calls a method of bean A. Such a scenario is considered dangerous because it could lead to a deadlock. WebLogic EJB supports re-entrant calls; however, it is the bean developer's responsibility to avoid any "dangerous" situations.
Can EJB handle transactions across multiple databases? Currently, the transaction manager in EJB does not have logging, which is a requirement for handling transactions across multiple databases. Though it might seem possible to accomplish this with multiple entity EJBeans handling transactions to each database and a single session EJBean to manage a transaction with the entity EJBeans, if any one transaction fails, it is not possible to roll the other transactions back.
How do I use a database for transactions with entity beans? There are two approaches: container-managed persistence, or bean-managed persistence. Each approach is shown in an example included in the WebLogic distribution. In both cases, you should use a connection pool specifically for EJB. With container-managed persistence, you specify the connection pool for your database connectivity, and persistence and transactions will be handled automatically by EJB. With bean-managed persistence, you can specify the connection pool for your database connectivity, but you will be specifying the persistence and transactions yourself.
When I run the deployment descriptor file through DDCreator, it throws the following exception: Exception in file UserInfoDD.txt: java.lang.IllegalArgumentException: Illegal value of transactionAttribute at javax.ejb.deployment.ControlDescriptor. setTransactionAttribute(ControlDescriptor.java:275) at weblogic.ejb.utils.DDCreator.createControlDescriptor (DDCreator.java:627) at weblogic.ejb.utils.DDCreator.createControlDescriptors (DDCreator.java:574) at weblogic.ejb.utils.DDCreator.createDescriptor (DDCreator.java:320) at weblogic.ejb.utils.DDCreator.createDescriptor (DDCreator.java:88) at weblogic.ejb.utils.DDCreator.main(DDCreator.java:41) This is a bug in javax.ejb.deployment.ControlDescriptor. The class defines TX_SUPPORTS. However, when the value is passed to setTransactionAttribute(), the method throws this exception. The error has been reported to Sun. Currently, there is no workaround for this.
How do I use container-managed persistence for non-primitive attributes? First off, the attribute has to be serializable. If it isn't, you can't use it with container-managed persistence. Let's say you have the three attributes you want to persist: public String accountId; // also the primary Key public double balance; public mySerializable sObj;The serializableObject can't be mapped directly, but we can map a byte array: public byte[] ssByteArray;You will then have four attributes in the EJBean. The first three will be mapped to columns in the database: public String accountId; // primary Key public double balance; public byte[] sByteArray; transient private mySerializable sObj;In ejbLoad(), you will convert the byte array sByteArray to the object of type mySerializable. In ejbStore(), you will do the reverse, updating the byte array so that the container will save it in the database as a BLOB, or "RAW" in Oracle databases: public void ejbLoad() throws RemoteException { try { ByteArrayInputStream ba = new ByteArrayInputStream(sByteArray); ObjectInputStream p = new ObjectInputStream(ba); sObj = (mySerializable) p.readObject(); } catch (Exception e) { throw new RemoteException("Exception in ejbLoad: ", e); } } public void ejbStore() throws RemoteException { try { ByteArrayOutputStream ba = new ByteArrayOutputStream(); ObjectOutputStream p = new ObjectOutputStream(ba); p.writeObject(sObj); sByteArray = ba.toByteArray(); } catch (Exception e) { throw new RemoteException("Exception in ejbLoad: ",e); } }
How does WebLogic make use of an object-relational mapping tool such as JavaBlend with EJB? Currently, you have to use bean-managed persistence to use tools such as JavaBlend. We are looking at integrating WebLogic EJB with object-relational tools in a future release.
I'm using JDBC container-managed persistence with a Date type field in my database. What data type attribute should I have in my EJB? The Java Date type doesn't work. You want java.sql.Timestamp instead of Date. See the specific mappings by looking in the appropriate database-specific guide:
Is the jdbc:weblogic:jts driver being used even when only the connection pool is referred to? Yes -- it is implicitly being used for container-managed persistence.
How should I implement findByPrimaryKey() for bean-managed persistence? You will need to implement a method following this pattern: public Object ejbFindByPrimaryKey(Object key) throws FinderException { // Do a database query // If query succeeds return key; // else // throw FinderException }
Do data types of the primary key class and the database table have to match? They must be compatible. See mapping types described in an earlier question.
Does WebLogic EJB require a user-defined class for a primary key when using container-managed persistence? Yes -- check the last rule of section 9.10.7 of the EJB 1.0 specification. The names of the fields in the primary key class must be a subset of the names of the container-managed EJBean. Unless the primary key class is user-defined, there is no way to satisfy this rule. This restriction applies only to container-managed persistence. |
|
Copyright © 2000 BEA Systems, Inc. All rights reserved.
|