-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: Newbie Q : howto fetch different db fields per situation ?
PostPosted: Wed Sep 07, 2011 3:51 am 
Newbie

Joined: Wed Sep 07, 2011 3:16 am
Posts: 2
Hello,

I'm new to Hibernate, having currently completed the basics tutorial and currently converting a classic JDBC project to Hibernate.

There is something that I'm trying to do but unfortunately I can't make it work. I hope that anyone can point me to the right direction - here is my issue :

I have a database table called MEDIA, which contains a BLOB column, and many varchar/integer/bigint/timestamp columns. In some situations I need to display a media, in which case I just need to fetch the BLOB, the filename,fileextension,filesize and mimetype.
In other situations (for example when using finders) I need to fetch everything besides the BLOB.

During the previous version of the project (classic JDBC), I had a POJO of class "MediaContent", which had attributes like a byte[], the filename,fileextension,filesize and mimetype. I also had a POJO of class "Media", which extends "MediaContent", and had all the other attributes (height,width,title,group,createtime and many others).
When displaying a media, I was entirely "filling" a MediaContent object, and in the other cases I was "filling" a Media object, keeping it's byte[] null.
The goal of this was just to try to optimize the application, by avoiding to fetch unnecessary data at each retrieval.

So I mapped MediaContent with a MediaContent.hbm.xml file and Media with a Media.hbm.xml file.

Here is the problem : when I now want to display a media, I'm using a query like "from MediaContent where mediaId = :mediaId...." and call the uniqueResult() method on the Query. It was working perfectly in the beginning, when only MediaContent was mapped. But now that Media is also mapped (to the same database table ofcourse), the queries bring me back 2 results each time (thus giving a NonUniqueResultException).
So to find out what was happening (and since my query is using the primary key of the table, there is supposed to always be 0 or 1 result), I used the hbQuery.list() method instead and found out that it contains one MediaContent object (perfect ! what I need !) as well as one Media object (not what I need in this case!).
Those two objects have the same ID and the same values for the common fields : same record but represented by both mappings.

I thought that by using "from MediaContent" in the query I would get a MediaContent object back but I was very wrong :)

I checked out Hibernate's inheritance strategies but I don't think that this is what I need.
I also tried to always use a Media object and forget about the MediaContent object, and to put lazy attributes on some of the fields, but they are always filled even when they are not used (no getter calls).

Can anyone point me to the right direction regarding this ? I can provide my mappings or some code if necessary.

Also, when I will need to retrieve a Media object and fill all the attributes besides the BLOB, what Hibernate mechanism will I have to use ?

During the classic-JDBC days, I could simply make two different queries and use the correct setters for each situation, but now I can't do it like this.
I'm pretty sure that this is very easy to do, but I just can't find out what Hibernate mechanism/property/trick I'm supposed to use to accomplish this task.

Thanks for any info ! I can clarify my explanations if needed :)

Nils

*Edit* : note that always using the Media object (no more MediaContent), and sometimes filling fields ABC, sometimes filling fields XYZ, would make me happy. My goal is just to fetch only the fields that I need for each situation. Also, the BLOB is a non-null field, I hope that it's possible to have it being null in a Java object mapped to the table, though.


Top
 Profile  
 
 Post subject: Re: Newbie Q : howto fetch different db fields per situation ?
PostPosted: Wed Sep 07, 2011 5:22 am 
Newbie

Joined: Wed Sep 07, 2011 3:16 am
Posts: 2
Answering my own question :

the solution is probably to use a single class that contains all the fields, and to simply not use the "from Table where" technique, which does the equivalent of "select * from Table where" but rather use something like "select fieldx,fieldy from Table where".

Myeah that was really stupid and basic, I'll try it this afternoon.


Top
 Profile  
 
 Post subject: Re: Newbie Q : howto fetch different db fields per situation ?
PostPosted: Wed Sep 07, 2011 5:32 am 
Newbie

Joined: Wed Sep 07, 2011 5:15 am
Posts: 1
Thank you very much for all of that great information! I really appreciate it!

_________________
Portland Movers


Top
 Profile  
 
 Post subject: Re: Newbie Q : howto fetch different db fields per situation ?
PostPosted: Wed Sep 07, 2011 9:12 am 
Beginner
Beginner

Joined: Wed Sep 30, 2009 5:29 am
Posts: 29
For what it's worth, here's how I get image data out of a blob column. I found the approach a bit hard to come up with, due to the way Lobs have changed over the years, I ran into a lot of obsolete information.

Code:
@Entity(name="image_blob")
public class ImageBlob {
   @Lob
   @Basic(fetch = FetchType.LAZY)
   @Column(name="image", length=10048576)
   private byte[] image;
   public byte[] getImage() {
      return image;
   }
   public void setImage(byte[] image) {
      this.image = image;
   }

}

.. then when reading the data from an ImageBlob instance, in my case I want to hold it in a BufferedImage object in memory, so I use ImageIO's read() function to process the data from an InputStream:

byte[] buffer = imageBlob.getImage();

ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
BufferedImage img = ImageIO.read(bais);
bais.close();


Obviously the way you actually read data from buffer is up to you, that's just an example.
Your mileage may vary :)

As for the other issue of object modeling, I seem to recall something about composite objects, so you could have:
@Entity
class Media {
@Column
int afield;
@Column
byte[] anotherfield;
}

@Entity
class MediaWithExtra {
@Composite // Not sure about this
Media themedia;
@Column
int yetmorefields;
}

This might be mappable in a way that lets you fetch a MediaWithExtra from the same table as Media, and it'll expose extra fields. I can't find what I'm talking about from a quick look through the reference docs, but I'm sure I recall something about these composite objects, in the context of one-to-one mappings in a parent-child context where the child object is represented in the database as extra columns on the parent entity's table.

Nick


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.