Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [eclipselink-users] Blob and PostgreSQL

Hi Andreas,

I am attaching an example that I am hoping will get you started. There are a couple of parts that are a little hacky, so we still should add an enhancement request to make this work more smoothly.

  Some key points about the example:

- The BlobWrapper class is used as a placeholder from the Blob you are trying to read/write. It subclasses BigInteger to get around some of the restrictions we have about what can be mapped as a Basic. You could add to it as needed.

- In BlobDescriptorCustomizer I am using the SQL Type OTHER as an indicator that we expect a LOB back. If you have other data that would by of Type OTHER, you may have to pick a different type

- The BlobWrapperPostGreSQLPlatform has most of the PostGres-specific code

Let me know if it helps,
Tom


On 25/06/2013 3:46 PM, Tom Ware wrote:
Hi Andreas,

   I think it would be a good idea to enter an enhancement request about this
issue so we can make the solution easier.

   Based on what you have said, I wonder if you want to Map your BLOB object, or
just have a utility that accesses it.  Do you make any use of the LOB object
aside from during a read or a write in a transaction?

   Currently, by default, when reading EclipseLink will read all the data in the
BLOB by default - the reason is because after we are done with the connection,
we will not have that option anymore.  We implement a way of making fields
mapped to LOBs LAZY, to avoid loading them when they are not needed, but that
does not avoid loading them all at once when they are loaded.  To workaround
that issue, you just need to tell EclipseLink they are something other than a
BLOB.   A Customizer like this should workaround the Read issue:

public class MyCustomizer implements
org.eclipse.persistence.config.SessionCustomizer {
     public void customize(Session session) {
         session.getEventManager().addListener(new SessionEventAdapter() {
             public void postLogin(SessionEvent event) {
                 ClassDescriptor desc =
event.getSession().getDescriptor(MyEntity.class);
                 DatabaseMapping mapping =
desc.getMappingForAttributeName("myLobAttributeName");
                 mapping.getField().setSqlType(Types.OTHER);
             }
         });
     }
}

This code should also gets us quite close to being able to write.  The only
issue that gets in the way is the fact the PostGres will not let us do a
createBLOB.  I am still looking in to the best way to get around that issue.

-Tom

On 24/06/2013 4:12 PM, Andreas Joseph Krogh wrote:
På mandag 24. juni 2013 kl. 21:57:22, skrev Tom Ware <tom.ware@xxxxxxxxxx
<mailto:tom.ware@xxxxxxxxxx>>:

    Lets say you get a LOB using an OID.  Does the connection you initially
read it
    with need to stay open in order to get the stream?  (If so, that will be a
    challenge given the constraints of the JPA world).  If not, what code
would you
    write to get the stream?  Do you keep the stream open for a long period of
time?
       Do you need a connection for the duration of the time that you use it?

What I need is large files (not fit in RAM) to be part of a transaction when
writing data. The streams won't be open for any longer than the time it takes to
read/write the data.
I come from the Hibernate world and I'm heading for porting our app to EL as
Hibernate gives us  way too much trouble. But in order to do this I have a
sample-app where I test stuff so that I'm sure stuff works the way I want before
porting the app (~190K JAVA code and 90K Scala-code).
When it comes to handelign LOBs I need something like this:
For retreival:
doInTransaction{
MyEntity e = myRepository.find(PK)
StreamUtils.copy(e.getBlob.getBinaryStream, outputStream)
}
For creation (Hibernate pseudo-code):
doInTransaction{
             LobHelper lobHelper = session.getLobHelper
             Blob blob = lobHelper.createBlob(f.fileStream, f.length)
             myEntity.setBlob(blob)
}
PG's jdbc-driver doesn't implement Connection.createBlob so Hibernate uses a
BlobProxy (org.hibernate.engine.jdbc.BlobProxy) which does goes around this.
Are there any examples around using PG with Blobs, using streams (not byte[]) ?
--
Andreas Joseph Krogh <andreak@xxxxxxxxxxxx>      mob: +47 909 56 963
Senior Software Developer / CTO - OfficeNet AS - http://www.officenet.no
Public key: http://home.officenet.no/~andreak/public_key.asc


_______________________________________________
eclipselink-users mailing list
eclipselink-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/eclipselink-users

Attachment: PostGresBlobExample.jar
Description: application/java-archive


Back to the top