Reputation: 2991
I'm trying to store a SHA256 hash as a numerical value, which seems like the optimal way to do it from a space and indexing POV. I'm using JPA with a simple field definition:
@NonNull
private BigInteger mybiginteger;
However, it refuses to insert the value.
I'm using a H2 database during unit tests, and now that I've added a BigInteger value in JPA it fails
Caused by: org.h2.jdbc.JdbcSQLDataException: Value too long for column "MYBIGINTEGER DECIMAL(19, 2)": "-12804752987762098394035772686106585063470084017442529046078187006797464553387.00 (79)"; SQL statement:
Skipping the test cases and trying it with Postgres it also fails with
Caused by: org.postgresql.util.PSQLException: ERROR: numeric field overflow
Detail: A field with precision 19, scale 2 must round to an absolute value less than 10^17.
JPA has created this as a numeric(19,2) field according to the DB tools. I can manually change the column definition and it works, but not how to set it to be portable between H2 and PSQL.
How can I correctly store BigInteger in a H2/PSQL database using JPA? Also, why is it allowing two decimal places for a BigInteger type?
Upvotes: 1
Views: 3344
Reputation: 59
I solved this issue by adding the following annotation on the property.
@Column(columnDefinition = "BIGINT")
Upvotes: 2
Reputation: 3743
I would disagree that BigInteger is the right type for a Hash. Do you want to do arithmetic with your hash? I don't think so.
Java's MessageDigest
for example, will give you a byte[]
array with the hash. You can map a byte array efficiently as a binary/BLOB column.
Another portable way is to store it as a base64 encoded string.
@Lob
byte[] hash;
Assuming Postgresql, you can check the space requirements here: https://www.postgresql.org/docs/current/datatype.html
A 'bytea' column type would require up to 32 + 4 bytes. You can create indizes etc. on that column type.
Upvotes: 0
Reputation: 2991
I forced the column type with
@Column(precision = 100, scale = 0)
Precision 100 is probably way too high, but I'll calculate the correct value later.
Upvotes: 1