Skip to content

Commit 3f93ec8

Browse files
Narosbeikov
authored andcommitted
HHH-14725 Fix reset handling on BlobProxy
1 parent f469677 commit 3f93ec8

File tree

3 files changed

+149
-1
lines changed

3 files changed

+149
-1
lines changed

hibernate-core/src/main/java/org/hibernate/engine/jdbc/BlobProxy.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ public final class BlobProxy implements Blob, BlobImplementer {
3838
// no longer necessary. The class name could be updated to reflect this but that would break APIs.
3939

4040
private final BinaryStream binaryStream;
41+
private final int markBytes;
42+
private boolean resetAllowed;
4143
private boolean needsReset;
4244

4345
/**
@@ -47,7 +49,9 @@ public final class BlobProxy implements Blob, BlobImplementer {
4749
* @see #generateProxy(byte[])
4850
*/
4951
private BlobProxy(byte[] bytes) {
50-
binaryStream = new BinaryStreamImpl( bytes );
52+
binaryStream = new ArrayBackedBinaryStream( bytes );
53+
markBytes = bytes.length + 1;
54+
setStreamMark();
5155
}
5256

5357
/**
@@ -59,6 +63,18 @@ private BlobProxy(byte[] bytes) {
5963
*/
6064
private BlobProxy(InputStream stream, long length) {
6165
this.binaryStream = new StreamBackedBinaryStream( stream, length );
66+
this.markBytes = (int) length + 1;
67+
setStreamMark();
68+
}
69+
70+
private void setStreamMark() {
71+
if ( binaryStream.getInputStream().markSupported() ) {
72+
binaryStream.getInputStream().mark( markBytes );
73+
resetAllowed = true;
74+
}
75+
else {
76+
resetAllowed = false;
77+
}
6278
}
6379

6480
private InputStream getStream() throws SQLException {
@@ -73,7 +89,12 @@ public BinaryStream getUnderlyingStream() throws SQLException {
7389
private void resetIfNeeded() throws SQLException {
7490
try {
7591
if ( needsReset ) {
92+
if ( !resetAllowed ) {
93+
throw new SQLException( "Underlying stream does not allow reset" );
94+
}
95+
7696
binaryStream.getInputStream().reset();
97+
setStreamMark();
7798
}
7899
}
79100
catch ( IOException ioe) {
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
* SPDX-License-Identifier: LGPL-2.1-or-later
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.orm.test.envers.integration.blob;
6+
7+
import static org.hamcrest.MatcherAssert.assertThat;
8+
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
9+
import static org.junit.Assert.fail;
10+
11+
import java.io.BufferedInputStream;
12+
import java.io.InputStream;
13+
import java.nio.file.Files;
14+
import java.nio.file.Path;
15+
import java.sql.Blob;
16+
17+
import org.hamcrest.Matchers;
18+
import org.hibernate.engine.jdbc.proxy.BlobProxy;
19+
import org.hibernate.envers.Audited;
20+
import org.hibernate.orm.test.envers.BaseEnversJPAFunctionalTestCase;
21+
import org.hibernate.orm.test.envers.Priority;
22+
import org.junit.Test;
23+
24+
import jakarta.persistence.Entity;
25+
import jakarta.persistence.GeneratedValue;
26+
import jakarta.persistence.Id;
27+
28+
/**
29+
* @author Chris Cranford
30+
*/
31+
public class BasicBlobTest extends BaseEnversJPAFunctionalTestCase {
32+
33+
@Override
34+
protected Class<?>[] getAnnotatedClasses() {
35+
return new Class<?>[] { Asset.class };
36+
}
37+
38+
@Test
39+
@Priority(10)
40+
public void initData() {
41+
final Path path = Path.of( getClass().getResource( "./blob.txt" ).getPath() );
42+
doInJPA( this::entityManagerFactory, entityManager -> {
43+
try {
44+
final Asset asset = new Asset();
45+
asset.setFileName( "blob.txt" );
46+
47+
final InputStream stream = new BufferedInputStream( Files.newInputStream( path ) );
48+
assertThat( stream.markSupported(), Matchers.is( true ) );
49+
50+
Blob blob = BlobProxy.generateProxy( stream, Files.size( path ) );
51+
52+
asset.setData( blob );
53+
entityManager.persist( asset );
54+
}
55+
catch (Exception e) {
56+
e.printStackTrace();
57+
fail( "Failed to persist the entity" );
58+
}
59+
} );
60+
}
61+
62+
@Audited
63+
@Entity(name = "Asset")
64+
public static class Asset {
65+
@Id
66+
@GeneratedValue
67+
private Integer id;
68+
private String fileName;
69+
private Blob data;
70+
71+
public Integer getId() {
72+
return id;
73+
}
74+
75+
public void setId(Integer id) {
76+
this.id = id;
77+
}
78+
79+
public String getFileName() {
80+
return fileName;
81+
}
82+
83+
public void setFileName(String fileName) {
84+
this.fileName = fileName;
85+
}
86+
87+
public Blob getData() {
88+
return data;
89+
}
90+
91+
public void setData(Blob data) {
92+
this.data = data;
93+
}
94+
}
95+
96+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?xml version='1.0' encoding='utf-8'?>
2+
<!--
3+
~ SPDX-License-Identifier: LGPL-2.1-or-later
4+
~ Copyright Red Hat Inc. and Hibernate Authors
5+
-->
6+
<!DOCTYPE hibernate-configuration PUBLIC
7+
"-//Hibernate/Hibernate Configuration DTD//EN"
8+
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
9+
10+
<hibernate-configuration>
11+
<session-factory>
12+
<property name="hbm2ddl.auto">create-drop</property>
13+
14+
<property name="show_sql">false</property>
15+
<property name="format_sql">false</property>
16+
17+
<property name="dialect">org.hibernate.dialect.H2Dialect</property>
18+
<property name="connection.url">jdbc:h2:mem:envers</property>
19+
<property name="connection.driver_class">org.h2.Driver</property>
20+
<property name="connection.username">sa</property>
21+
<property name="connection.password"></property>
22+
23+
<!--<property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>-->
24+
<!--<property name="connection.url">jdbc:mysql:///hibernate_tests?useUnicode=true&amp;characterEncoding=UTF-8</property>-->
25+
<!--<property name="connection.driver_class">com.mysql.jdbc.Driver</property>-->
26+
<!--<property name="connection.username">root</property>-->
27+
<!--<property name="connection.password"></property>-->
28+
29+
<!--<property name="hibernate.jdbc.batch_size">100</property>-->
30+
</session-factory>
31+
</hibernate-configuration>

0 commit comments

Comments
 (0)