3 Replies Latest reply on Oct 14, 2004 8:39 AM by scoy

    Initializing a java.sql.Blob cmp field (JBoss 3.2.3/Oracle9.

    gchazalon

      Hi,

      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