Initializing a java.sql.Blob cmp field (JBoss 3.2.3/Oracle9.
gchazalon Oct 8, 2004 8:33 AMHi,
I have experienced different issues when trying to initialize a java.sql.Blob cmp-field mapped on an Oracle BLOB.
Let me explain my case:
I have an entity bean with a cmp-field of type java.sql.Blob mapped on an Oracle BLOB. The BLOB column in the DB is nullable.
I have a session facade in charge of creating the enity bean instance and then updating the BLOB column.
Firs of all, I had to find a way to create a java.sql.Blob, since it's an interface, I needed a class implementing it. I have seen some posts talking about the org.jboss.ejb.plugins.cmp.jdbc.ByteArrayBlob class.
So I tryed to use it for initializing my BLOB field in two different ways, but none of them works.
The first one sets my cmp field with a new ByteArrayBlob initialized with an empty byte array. I then try to write my data stream inside my java.sql.Blob cmp field.
ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { eprXMLData.getAny().write(new OutputStreamWriter(baos, Charset.forName("UTF-8"))); if ((referentLocal.getEprData() == null) || (referentLocal.getEprData().length() < baos.size())) { referentLocal.setEprData(new ByteArrayBlob(new byte[baos.size()])); } //the following line will throw UnsupportedOperationException eprXMLData.getAny().write(new OutputStreamWriter(referentLocal.getEprData().setBinaryStream(0), Charset.forName("UTF-8"))); }
But this throws an UnsupportedOperationException because the ByteArrayBlob is immutable.
13:43:22,681 ERROR [LogInterceptor] TransactionRolledbackLocalException in method: public abstract void adonis2.adp.archivage.ingestion.interfaces.ArchiveCreatorLocal.setReferentEprData(adonis2.adp.archivage.model.interfaces.ReferentLocal,adonis2.adp.xml.bind.signature.DataFileType$XMLDataType) throws adonis2.adp.SystemException, causedBy: java.lang.UnsupportedOperationException: ByteArrayBlob is immutable at org.jboss.ejb.plugins.cmp.jdbc.ByteArrayBlob.setBinaryStream(ByteArrayBlob.java:143) at adonis2.adp.archivage.ingestion.ejb.ArchiveCreatorBean.setReferentEprData(ArchiveCreatorBean.java:323) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ...
Ok, so I tryed it another way. I create a new ByteArrayBlob with a byte array containing the data I want into th BLOB. I then set the cmp field on the bean but I got an exception at commit time.
ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { eprXMLData.getAny().write(new OutputStreamWriter(baos, Charset.forName("UTF-8"))); //now the following will throw java.io.NotSerializableException at transaction commit time referentLocal.setEprData(new ByteArrayBlob(baos.toByteArray())); }
Here is the exception :
13:53:35,332 ERROR [LogInterceptor] TransactionRolledbackException in method: public abstract java.lang.String adonis2.adp.compostage.interfaces.IngestionReferent.ingerer(adonis2.adp.util.ReferentDataFileInfoBean,byte[]) throws adonis2.adp.SystemException,adonis2.adp.compostage.BadCreatorParameterException,adonis2.adp.xml.XMLValidationException,adonis2.adp.ConfigurationException,adonis2.adp.archivage.ingestion.InvalidSIPException,adonis2.adp.archivage.ingestion.InvalidAccordServiceException,adonis2.adp.config.EPRNotFoundException,adonis2.adp.archivage.ingestion.ArchiveNotFoundException,java.rmi.RemoteException, causedBy: org.jboss.tm.JBossRollbackException: Unable to commit, tx=TransactionImpl:XidImpl [FormatId=257, GlobalId=adonis2gr-062//29, BranchQual=] status=STATUS_NO_TRANSACTION; - nested throwable: (javax.ejb.EJBException: Internal error setting parameters for field eprData; CausedByException is: Can't serialize binary object: java.io.NotSerializableException: org.jboss.ejb.plugins.cmp.jdbc.ByteArrayBlob) at org.jboss.tm.TransactionImpl.commit(TransactionImpl.java:413) at org.jboss.ejb.plugins.TxInterceptorCMT.endTransaction(TxInterceptorCMT.java:398) at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:277) at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:128) at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:118) at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:191) at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFinderInterceptor.java:122) at org.jboss.ejb.StatelessSessionContainer.internalInvoke(StatelessSessionContainer.java:331) at org.jboss.ejb.Container.invoke(Container.java:700) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
I find the last one very surprising. How come that the JBoss can't serialize a class intented to handle BLOB ??
Anyway, I'm gonna give a shot with using oracle.sql.BLOB class, but to create an instance of this class, I need a DB connection. Since I do not want any inconsistency in case of a rollback, I guess I have to use the same db connection used by the entity bean instance, right ?
So my second question is:
How do I get the current DB Connection used by the entity bean ? Maybe with a magic JBoss MBean ...
Of course, any help is highly appreciated.
Regards,
Gregory