| 
 | 1 | +/*  | 
 | 2 | + * Hibernate, Relational Persistence for Idiomatic Java  | 
 | 3 | + *  | 
 | 4 | + * License: GNU Lesser General Public License (LGPL), version 2.1 or later  | 
 | 5 | + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html  | 
 | 6 | + */  | 
 | 7 | +package org.hibernate.orm.test.lob;  | 
 | 8 | + | 
 | 9 | +import jakarta.persistence.Entity;  | 
 | 10 | +import jakarta.persistence.Id;  | 
 | 11 | +import jakarta.persistence.Lob;  | 
 | 12 | +import org.hibernate.engine.jdbc.NonContextualLobCreator;  | 
 | 13 | +import org.hibernate.testing.orm.junit.DomainModel;  | 
 | 14 | +import org.hibernate.testing.orm.junit.JiraKey;  | 
 | 15 | +import org.hibernate.testing.orm.junit.SessionFactory;  | 
 | 16 | +import org.hibernate.testing.orm.junit.SessionFactoryScope;  | 
 | 17 | +import org.junit.jupiter.api.Test;  | 
 | 18 | + | 
 | 19 | +import java.io.ByteArrayInputStream;  | 
 | 20 | +import java.io.ByteArrayOutputStream;  | 
 | 21 | +import java.io.IOException;  | 
 | 22 | +import java.io.InputStream;  | 
 | 23 | +import java.sql.Blob;  | 
 | 24 | +import java.sql.SQLException;  | 
 | 25 | +import java.util.Random;  | 
 | 26 | +import java.util.zip.GZIPInputStream;  | 
 | 27 | +import java.util.zip.GZIPOutputStream;  | 
 | 28 | + | 
 | 29 | +import static org.junit.jupiter.api.Assertions.assertArrayEquals;  | 
 | 30 | +import static org.junit.jupiter.api.Assertions.assertEquals;  | 
 | 31 | + | 
 | 32 | +@DomainModel(annotatedClasses = InflaterInputStreamBlobTest.TestEntity.class)  | 
 | 33 | +@SessionFactory  | 
 | 34 | +@JiraKey("HHH-19464")  | 
 | 35 | +class InflaterInputStreamBlobTest {  | 
 | 36 | + | 
 | 37 | +	private static final int RANDOM_SIZE = 32000;  | 
 | 38 | + | 
 | 39 | +	@Test  | 
 | 40 | +	void hibernate_blob_streaming(SessionFactoryScope scope) throws Exception {  | 
 | 41 | +		final var randomBytes = getRandomBytes();  | 
 | 42 | +		final var outputStream = new ByteArrayOutputStream();  | 
 | 43 | +		try (var zipOutputStream = new GZIPOutputStream( outputStream )) {  | 
 | 44 | +			zipOutputStream.write( randomBytes );  | 
 | 45 | +		}  | 
 | 46 | + | 
 | 47 | +		long size = randomBytes.length;  | 
 | 48 | +		scope.inTransaction( entityManager -> {  | 
 | 49 | +					try {  | 
 | 50 | +						InputStream is = new GZIPInputStream( new ByteArrayInputStream( outputStream.toByteArray() ) );  | 
 | 51 | +						Blob blob = NonContextualLobCreator.INSTANCE.wrap(  | 
 | 52 | +								NonContextualLobCreator.INSTANCE.createBlob( is, size )  | 
 | 53 | +						);  | 
 | 54 | +						TestEntity e = new TestEntity();  | 
 | 55 | +						e.setId( 1L );  | 
 | 56 | +						e.setData( blob );  | 
 | 57 | + | 
 | 58 | +						entityManager.persist( e );  | 
 | 59 | +					}  | 
 | 60 | +					catch (IOException e) {  | 
 | 61 | +						throw new RuntimeException( e );  | 
 | 62 | +					}  | 
 | 63 | +				}  | 
 | 64 | +		);  | 
 | 65 | + | 
 | 66 | +		scope.inStatelessSession( session -> {  | 
 | 67 | +			final var entity = session.get( TestEntity.class, 1L );  | 
 | 68 | +			try {  | 
 | 69 | +				final var blob = entity.getData();  | 
 | 70 | +				assertEquals( size, blob.length() );  | 
 | 71 | +				assertArrayEquals( randomBytes, blob.getBytes( 1L, (int) blob.length() ) );  | 
 | 72 | +			}  | 
 | 73 | +			catch (SQLException e) {  | 
 | 74 | +				throw new RuntimeException( e );  | 
 | 75 | +			}  | 
 | 76 | +		} );  | 
 | 77 | +	}  | 
 | 78 | + | 
 | 79 | +	private static byte[] getRandomBytes() {  | 
 | 80 | +		final var bytes = new byte[RANDOM_SIZE];  | 
 | 81 | +		new Random().nextBytes( bytes );  | 
 | 82 | +		return bytes;  | 
 | 83 | +	}  | 
 | 84 | + | 
 | 85 | +	@Entity  | 
 | 86 | +	public static class TestEntity {  | 
 | 87 | + | 
 | 88 | +		@Id  | 
 | 89 | +		Long id;  | 
 | 90 | + | 
 | 91 | +		@Lob  | 
 | 92 | +		Blob data;  | 
 | 93 | + | 
 | 94 | +		public Long getId() {  | 
 | 95 | +			return id;  | 
 | 96 | +		}  | 
 | 97 | + | 
 | 98 | +		public void setId(Long id) {  | 
 | 99 | +			this.id = id;  | 
 | 100 | +		}  | 
 | 101 | + | 
 | 102 | +		public Blob getData() {  | 
 | 103 | +			return data;  | 
 | 104 | +		}  | 
 | 105 | + | 
 | 106 | +		public InputStream getInputStream() {  | 
 | 107 | +			try {  | 
 | 108 | +				return data.getBinaryStream();  | 
 | 109 | +			}  | 
 | 110 | +			catch (SQLException e) {  | 
 | 111 | +				throw new IllegalArgumentException( "Could not obtain requested input stream", e );  | 
 | 112 | +			}  | 
 | 113 | +		}  | 
 | 114 | + | 
 | 115 | +		public void setData(Blob data) {  | 
 | 116 | +			this.data = data;  | 
 | 117 | +		}  | 
 | 118 | +	}  | 
 | 119 | +}  | 
0 commit comments