1

I got two <o:graphicImage> to display the stored image and a dummy image if there is no image. Actually, the size of the stored images can be zero. If so, the first <o:graphicImage is rendered, but the image is empty and not rendered properly.

<o:graphicImage id="image" alt="Image"
        lastModified="#{userProfile.user.lastModified}"
        rendered="#{not empty images.getImage(userProfile.user.id)}"
        value="#{images.getImage(userProfile.user.id)}"

<o:graphicImage name="images/profile.png" width="125"
        rendered="#{empty images.getImage(userProfile.user.id)}" />

How can I display the dummy image if the user image is empty or has the length/size 0?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
alexander
  • 1,191
  • 2
  • 20
  • 40

1 Answers1

2

You'd really better not call that image streamer method in a rendered attribute. It's invoked multiple times during the JSF lifecycle, hereby inefficiently getting the image bytes from the DB every time.

The model also doesn't look right in first place. I suggest to change the model. Make the image ID a FK of the User or perhaps UserProfile table and entity.

@Column(name="image_id")
private Long imageId;

Then, when an user uploads/sets an image, save the image ID there. This way you can use it as below:

<o:graphicImage 
    value="#{images.getImage(userProfile.user.imageId)}" 
    rendered="#{not empty userProfile.user.imageId}" />

<h:graphicImage
    name="images/profile.png" 
    rendered="#{empty userProfile.user.imageId}" />

Don't forget to alter the image streamer to get image by its own ID instead of user ID.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • How should I save the stored image ID? Just create a new (auto generated) value after uploading the image? Is storing the image as byte array and access it via a `ApplicationScoped` bean just fine? – alexander May 26 '15 at 20:12
  • Just use a PK (every entity table should have one). The bean shouldn't hold request based variables, it should be stateless. – BalusC May 27 '15 at 05:50
  • Well, you said `FK` in the user table/entity. So, I am a bit confused now. Should I store the images in a new table? The `ApplicationScoped` bean is because ``. Is that wrong, too? – alexander May 27 '15 at 06:30
  • Perhaps you're new to SQL/DB/modelling too? Every table should have a PK (in JPA terms, `@Id`). Every relationship between two tables is represented by a FK in one table referring the PK of the other table (in JPA terms, `@OneToOne` or `@ManyToOne`). The bean's scope is fine. It should be application scoped. It should be stateless. It should not hold request scoped variables. The `` also validates the bean scope in order to force the developers to think twice. Common sense should already tell you that you can't store request scoped data in an application scoped bean. – BalusC May 27 '15 at 06:36
  • Well, a bit yes. :) My user entity has simple ID with `@Id` annotated. So, your attempt is to use the image id as primary key here? The image bean should be stateless,too? – alexander May 27 '15 at 06:47
  • Image entity should have `@Id` too. When you persist a new image entity, JPA should already have set the ID for you. You just copy this ID to new field in User entity (as stated in answer) and then update it. As commented twice before, yes, the image bean should be stateless (as you asked this thrice, didn't you actually want to ask "What does stateless mean?" ? well, it means that the class doesn't have any instance variables which are sensitive to changes induced by multiple threads, i.e. it doesn't have any "state"). – BalusC May 27 '15 at 06:54
  • Thanks for your explanation! I have no image entity, so that was a misunderstanding. Actually I am holding the profile photo in the user entity as byte array. So your idea is to have a seperate image entity? – alexander May 27 '15 at 07:09
  • Oh? You're carrying a `byte[]` around with every `User`? That would have been quite memory inefficient if it's eagerly loaded. If you don't want to denormalize the image into its own table, then you'd better lazily load it and add a (`@Transient`?) boolean property indicating whether the image is present or not and then hook the `rendered` attribute on that instead. – BalusC May 27 '15 at 07:14
  • Well, I have to hold the image as byte[] in the user entity. Your suggestion and idea is great. It works like a charm. Thank you so much! BTW: Did you upvote my question? :) – alexander May 28 '15 at 10:05
  • You're welcome. Yes I did. It wasn't asked before and is clear cut, so I upvoted it. – BalusC May 28 '15 at 10:07