Store large binary in database(MySQL, PSQL, etc) using Spring boot - mysql

I want to store large binary files in Databases such as MySQL, PSQL, etc in Spring boot. I have
I am using following type in DAO
#Lob
#Type(type = "org.hibernate.type.BlobType")
#Column(name = "document", nullable = false, length=50000000)
private Blob document;
In PSQL, document column type is stored as oid
In MySQL, document column type is stored as longblob
I am trying to use following code for PSQL. Refer here
LargeObjectManager lobj = conn.unwrap(org.postgresql.PGConnection.class).getLargeObjectAPI();
Is there any equivalent for PGConnection in MySQL?
Also Will MySQL supports oid type. I see it as longblob

Related

Hibernate store YearMonth in MySQL as Blob instead of text

A Spring Boot 2.3.0 Project is Storing Data in MySQL 8.0. (jdk 9)
A JPA Class has Java 8 YearMonth field
#Data
#Entity
public class Version {
...
private YearMonth releaseDate;
private LocalDateTime createdAt;
When I persist an instance of version, it's stored like this:
As You can see LocalDateTime gets stored as text but YearMonth as Blob. Now When I get back the entity it works fine and I do get YearMonth value.
The problem is that I cannot read it through MySQL Workbench. And I know that EclipseLink (official implementation of JPA) does persist YearMonth as Text.
How Can I store it as Text and not BLOB?

Change spring jpa existing table column type

I'm using spring boot and jpa and I have an existing table with attribute as VARCHAR 255:
#Column(name = "description")
private String description;
I tried to change it to longtext with no success:
#Column(name = "description", columnDefinition = "longtext")
private String description;
My configuration in the application.properties file regarding Hibernate ddl is set to update:
spring.jpa.hibernate.ddl-auto = update
Is it possible to change VARCAR 255 to longtext? if it does, How do I do it?
Thanks,
Avi
spring.jpa.hibernate.ddl-auto=update
will not do following changes
Delete a column which is no longer in entity
Modify existing column.
Refer here for more details
spring-data-jpa ddl ‘update’ will not change exist colums,neither update nor delete.
I also faced the same issue
Your current configuration won't update
The best way to do this is through migrations using flyway
Documentation : https://flywaydb.org/documentation/
you can write sql queries in your project and alter the same column in your entity.

JPA Hibernate - Multiple Database Dialects and nvarchar(length) data type

I have to do a project using JPA + Hibernate in which I'm using 3 dialects: MySQL5InnoDBDialect, MSSQL2012Dialect and Oracle12cDialect.
Right now I have a specification which is telling me that for some column from:
Oracle database, I have to use NVARCHAR2(LENGTH) data type
MySql database, I have to use VARCHAR(LENGTH) data type
MSSQL database, I have to use NVARCHAR(LENGTH) data type
... and here is my problem..
If I use:
#Column(name="columnName" length = 255)
private String columnName;
hibernate generates varchar(255) and this is good just for MySQL
If I use:
#Column(name="columnName", columnDefinition="nvarchar2(255)")
private String columnName;
it's not possible in MySQL, i get error because of columnDefinition, but in oracle is okay
I tried to customize MySQL dialect creating
public class CustomMySQL5InnoDBDialect extends MySQL5InnoDBDialect{
public CustomMySQL5InnoDBDialect() {
super();
registerColumnType(Types.NVARCHAR, "nvarchar2($l)");//$l not $1
registerHibernateType(Types.NVARCHAR, StandardBasicTypes.STRING.getName());
}
}
and giving this class in hibernate configuration for MySQL dialect.
I have the same problem in MySQL if I'm using columnDefinition property.
Can you help with this problem please?
The solution is to make use of the feature that the JPA API spec provides you with for just this situation. Define a file orm.xml for each datastore that you need to support, and enable the requisite one when using each database. See this link for details of the file format. That way you don't need to think about hacking the internal features of whichever JPA provider you are using, and you also retain JPA provider portability, as well as database portability
The idea of putting schema specific information info (static) Java annotations is an odd one, even more so when wanting database portability.

JDO Class - convert to varchar or nvarchar based on MySQL or MSSQL

I have a JDO Class. Some of the attributes are as shown below:
#Column(jdbcType = "VARCHAR", length = 200)
String anotherSrcFieldValue;
#Column(jdbcType = "BIGINT")
long tgtFieldId;
#Column(jdbcType = "VARCHAR", length = 200)
String tgtFieldValue;
With MySQL and MSSQL it works fine.
My requirement is, if it is MySQL make it a column of type VARCHAR; and when it is MSSQL, create a column of type NVARCHAR. How can I achieve this?
A second requirement is one entity class to be run on both the databases.
All JDO docs I've seen explain clearly that putting schema specific info in annotations is a bad idea. Consequently you should have 2 files "package-mysql.orm" and "package-mssql.orm" to specify the schema-specific parts of the mapping, and set "datanucleus.Mapping" to be either "mysql" or "mssql" depending on your datastore. As per http://www.datanucleus.org/products/accessplatform_4_2/jdo/orm/metadata_orm.html

Hibernate database specific columnDefinition values

the problem is as follows: We're using hibernate with annotations as O/R Mapper.
Some #Column annotations look like:
#Column(columnDefinition = "longblob", name = "binaryData", nullable = true)
or
#Column(columnDefinition = "mediumtext", name = "remark", nullable = true)
with the columnDefinition attributes being mysql specific
on postgres for example, the columnDefinition values should be "bytea" and "varchar(999999)"
and on oracle probably something else.
Problems arise currently at the time of Schema Export, e.g. when creating the DDL statements.
Possible workarounds that I can think of are
- Hack some JDBC driver that does a text replace (e.g. longblob->bytea) for the DDL statements. That's ugly but will work somehow
- Use hibernate xml configuration instead of annotations. That will probably work but I prefer annotations
Does anybody know any alternatives? Hibernate specific workarounds are ok, e.g. if the columnDefinition attribute can contain dialect specific values like
#Column(columnDefinition = "mysql->mediumtext, postgres->varchar(999999)", name = "remark", nullable = true)
Thanks
Holger
Why don't you use the database-agnostic annotations like:
#Lob (on a byte[] or a String property)
#Column(length=90000) (on a String property)
and see what columns will be generated in the database. They will most likely be of the types you want them to be.
Some ideas:
Use annotation in general, but overload them from Xml in the case where they are specific to your database. Then you can have one configuration file specific to your database.
Use java Constants in your annotations (they have to be compile-time constants, so you are limited). You can have several sets of Java constants, and point toward the one you want to export to. (Beware, when you point toward another constant, you have to recompile everything.)
I have also used the dialect to switch some code in my Configuration class. The configuration class receives all data (from annotations or xml), and can then postprocess it.
For example, I have changed the concatenation symbol from '||' on Oracle to '+' on SqlServer.
This is conveniently done at runtime :-)