0

I am trying to save a byte[] field to local filesystem instead of the database.

I have tried the JPA annotation @Transient

@Entity
@Table(name = "screenshot")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Screenshot implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
    @SequenceGenerator(name = "sequenceGenerator")
    private Long id;

    @Lob
    @Transient
    @Column(name = "image", nullable = false)
    private byte[] image;

    @Column(name = "otherField", nullable = false)
    private String otherField;

    @Column(name = "otherField2", nullable = false)
    private String otherField2;
}

But after I persist the entity, for e.g. The returnedEntity image property will not be returned due to @Transient annotation.

Screenshot returnedEntity = screenshotRepository.save(entity);

But I need to persist it in the database first in-order to get an unique ID and use this ID as part of the file path to persist only the image(binary) field in my local filesystem.

I run into a situation that before I save the entity into the database, I do not have an unique ID. But after I save the entity, I lost the binary byte[] data to save the file in the local filesystem.

Can't seems to figure a good way to link the saved ID to the binary byte[].

Gavin
  • 2,484
  • 5
  • 33
  • 68
  • What do you mean you lost image data? Was it saved or not into database? If it was, who stops you from getting it back from the table you stored it into? Why did you mark image as @Id? What is screenshotRepository.save? (show its implementation) – CrazySabbath Jul 11 '17 at 14:03
  • The `@id` was a typo, edited it away. No, I do not want to persist it in the database, but in my local filesystem. – Gavin Jul 11 '17 at 14:05
  • That's funny, because you said `I run into a situation that before I save the entity into the database, I do not have an unique ID. But after I save the entity`. If you do not want to persist the entity, why are you using JPA? Show your table and it's data. – CrazySabbath Jul 11 '17 at 14:13
  • Possible duplicate of [JPA - Returning an auto generated id after persist()](https://stackoverflow.com/questions/9732453/jpa-returning-an-auto-generated-id-after-persist) – Kh.Taheri Jul 11 '17 at 14:17
  • This answer https://stackoverflow.com/a/9734002/3025545 will help you to resolve your problem. As JPA can return the entire entity instance with the database-generated ID. – Kh.Taheri Jul 11 '17 at 14:18
  • 1
    I do want to persist the entity in the database except for the property `image` which I will persist in local filesystem instead. Hence the annotation `@Transient` on that field. @Kh.Taheri Since the `image` field annotated with `@Transient` will be gone after its entity. I will not be able to know which ID belongs to which `image`, considering if I had a list to save. Is there a way to sort of 'reserve' an ID but without actual persisting it? Updated my question anyway. – Gavin Jul 12 '17 at 02:03

1 Answers1

0

Your problem is that you want the field to be Transiented and Included (serialized) at the sametime. Some people suggest to use @JsonInclude annotation, like what is mentioned here.

However, from my point of view, the idea is in the logic of your app and its not related to JPA. So, I would copy the object before presisting it, or at least copy the image field alone. After presistance, assigning the ID of the presisted object to the ID of the copied object.

Or, another solution, you can add a string field to your database that will hold a path to your image; You start by writing the image to the 'heart content' or wherever, and then assign the path of the image to the entity and persist that path in the database.

Or, another solution, you can add another data model layer to your system above the entity layer, which contains the JSON classes, so you dont need to have a transient fields in your entity nor JSON annotations.

Kh.Taheri
  • 896
  • 1
  • 10
  • 25
  • `@JsonInclude` annotation is not really required. The field is still being parsed as JSON. I ended up persisting the `blob`field in a temp folder on my local filesystem, created a new `filepath` field and assigned it before persisting the entity to my DB. Now I have a relationship between the blob in my local filesystem and entry in the DB and can improve the actual file structure by shifting the temp filepath to my hearts content – Gavin Jul 12 '17 at 07:55