Upload buffered image to database

I’m trying to upload an image directly to database and why am I getting this “ERROR [com.vaadin.flow.server.DefaultErrorHandler]
(default task-19) : java.lang.NullPointerException
” even the bytes is not empty? Is there a simple way to upload the image directly to database without uploading the actual file to the server? I know how to do the file to database method but I had no luck getting buffer to database.

Here’s my code snippets.

Frontend

MemoryBuffer buffer = new MemoryBuffer();
Upload upload = new Upload(buffer);
upload.addSucceededListener(event -> {
	try {
		Byte[] bytes = IOUtils.toByteArray(buffer.getInputStream());
		ds.ImageUpload(bytes);
	} catch (IOException e) {
		e.printStackTrace();
	}
});

Backend

public void ImageUpload(byte[] bytes) {
	connect();
	try {
		ps = conn.prepareStatement("UPDATE user SET photo = ? WHERE user_id = '1';");
		ps.setBytes(1, bytes);
		ps.executeUpdate();
	} catch (SQLException e) {
		e.printStackTrace();
	}
	disconnect();
}

UPDATE: I just realized that frontend and backend don’t pass data easily without using a Receiver or InputStream on the backend to receive the data but I wasn’t able to find good examples on the internet to solve this.

Not exactly what you’re looking for, but here is an example with working in-memory data handling with Upload: [https://github.com/vaadin/vaadin-form-example/blob/master/src/main/java/org/vaadin/examples/form/ui/components/AvatarField.java]
(https://github.com/vaadin/vaadin-form-example/blob/master/src/main/java/org/vaadin/examples/form/ui/components/AvatarField.java)

Hope that helps :slight_smile:

Thomas Mattsson:
Not exactly what you’re looking for, but here is an example with working in-memory data handling with Upload: [https://github.com/vaadin/vaadin-form-example/blob/master/src/main/java/org/vaadin/examples/form/ui/components/AvatarField.java]
(https://github.com/vaadin/vaadin-form-example/blob/master/src/main/java/org/vaadin/examples/form/ui/components/AvatarField.java)

Hope that helps :slight_smile:

That didn’t help but thanks for trying. I already figured it out and had to use EntityManager to do the job. I’ll add the solutions below.

Here’s the solution for anyone trying to upload image directly to database and updating the image on the console as well. This is probably the simplest solution as a starting point. Keep in mind in setting the correct data types for the image in database otherwise it’ll throw an error if the image is too large. I used BLOB which is limited to 64K. MEDIUMBLOB is 16MB.

You will need to use javax.persistence and mysql API for this to work.

public static final String PERSISTENCE_UNIT_NAME = "mysqldatasource"; 
private EntityManager em;
private EntityManagerFactory emf;
private Query q;
private byte[] bytes;

Public MainView() {
	MemoryBuffer buffer = new MemoryBuffer();
	Upload upload = new Upload(buffer);
	upload.addSucceededListener(event -> {
		try {
			bytes = IOUtils.toByteArray(buffer.getInputStream());
			emf = javax.persistence.Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
			em = emf.createEntityManager();			        
			em.getTransaction().begin();
				
			// Upload image to database to user id = 1
			q = em.createQuery("UPDATE User u SET u.image = :data WHERE u.id = '1'");
			q.setParameter("data", bytes);
			q.executeUpdate();
			em.getTransaction().commit();
				
			// Retrieve image from database from user id = 1
			q = em.createQuery("SELECT u.image FROM User u WHERE u.id = '1'");
			bytes = (byte[]) q.getSingleResult();
			
			// Set the image from database
			image.getElement().setAttribute("src", new StreamResource("",
				() -> new ByteArrayInputStream(bytes)));
			em.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	});
	add(upload);
}

Thanks for posting the example.

IIRC the overhead difference between BLOB, MEDIUMBLOB and so forth is a byte or a couple of bytes. In the grand scheme of things, it will usually not have an impact on your app, unless you have millions of rows, so if in doubt pick the larger BLOB storage type.

Cheers
Martin