Storing byte array image using JPA2 in PostgreSQL - java

I am trying to store an image in the database but when I read the value I am getting always null.
I've tried several combinations of following annotations but result is always same:
#Lob
#Basic(fetch = FetchType.EAGER)
#Type(type="org.hibernate.type.BinaryType")
private byte[] image;
persistence.xml:
<persistence-unit name="primary" transaction-type="JTA">
<jta-data-source>java:jboss/datasources/WheelGoDS</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create" />
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
<property name="hibernate.current_session_context_class" value="jta"/>
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.archive.autodetection" value="class" />
<property name="hibernate.connection.useUnicode" value="true" />
<property name="hibernate.connection.characterEncoding" value="UTF-8" />
</properties>
</persistence-unit>
When I use only #Lob I've noticed that using pgAdmin i see numeric value. Otherwise I see binary data. My questions are:
Is there reliable way to store and read binary data using JPA2?
Is there way to read binary data in postgres? Because right now I am not sure if they are even correctly stored.

Related

Exception in JPA Persistance

I have question...I Have two JAR file, which have similar code, and one is in English and second for Deutch...I have two DB (for EN a DE), but I want to have same table names. If I start this, I have two definitions for same table...I want to keep the table same for the JAR, which will change. But it's enough for me to load one of this two. How can I do it? My app is bigger...
I don't want the modification of one table definition to be written to both tables.
Some advice? In persistance you can see some solve? Thanks
<jar-file>FA_DE-MLA-1.0.jar</jar-file>
<jar-file>FA_EN-MLA-1.0.jar</jar-file>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.enable_lazy_load_no_trans" value="true"/>
<property name="javax.persistence.validation.mode" value="none" />
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
<property name="hibernate.show_sql" value="false"/>
<property name="hibernate.format_sql" value="false"/>
<property name="hibernate.create_empty_composites.enabled" value="true"/>
</properties>

JPA Hibernate table doesnt exists

I have a problem that I've been struggling to solve but I'm not getting anywhere.
I'm using JPA Hibernate to create tables, but instead of creating the table, he shows me the error:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table ‘escola.tab_alunos’ doesn’t exist
Here's my persistence.xml:
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version=“2.0”>
<persistence-unit name="banco" transaction-type="RESOURCE_LOCAL">
<description>
Persistence unit for the JPA tutorial of the Hibernate Getting Started Guide
</description>
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>org.halyph.sessiondemo.Event</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/escola" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="0000" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
And here's the class Aluno:
#Entity
#Table(name=“TAB_ALUNOS”)
#SequenceGenerator(name=“TAB_ALUNOS_PK”, sequenceName=“SEQ_ALUNOS_PK”, allocationSize=1)
public class Aluno {
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="TAB_ALUNOS_PK")
private Long id;
#Column(length=10, nullable=false)
private String matricula;
#Column(length=100, nullable=false)
private String nome;
#Column(length=9 ,nullable=false)
private String sexo;
#Column(name="DATA_NASCIMENTO", length=10, nullable=false)
private String dataNascimento;
#Column(length=30, columnDefinition="DEFAULT 'Ativo'")
private String situacao;
// ....
}
Any idea on how can I solve this problem?
Just for the record, the first time I started the project, it worked just fine, but due to a mistake I've made, I had to drop the table, after that hibernate stopped creating the table and now I can't do anything
Modify
<property name="hibernate.hbm2ddl.auto" value="update" />
to
<property name="hibernate.hbm2ddl.auto" value="create" />
The value="update" modifies the existing table while value="create" creates a table, but if the table already exists, it drops the table with the data and creates a table again.
Change <property name="hibernate.hbm2ddl.auto" value="create" />
Refer here for all possible values of hbm2ddl.auto
Hibernate hbm2ddl.auto possible values and what they do?
The error shows up because your persistance.xml has been configured to update tables. During the first run, there are no tables that have been created, and thus nothing to update.
On the first run, set <property name="hibernate.hbm2ddl.auto" value="create" /> so that a table can be created from your pojo. Then, set it back to <property name="hibernate.hbm2ddl.auto" value="update" /> so that your tables can be updated instead of being created at each run
Provide schema as well along with table name e.g.
#Table(name=“TAB_ALUNOS”, schema = "dbo")
I tried changing it to:
<property name="hibernate.hbm2ddl.auto" value="create" />
and i have also tried changing to:
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
Neither one of those two worked.

How to qualify sequence names in Hibernate?

I'm having troubles when generating sequences for an oracle databese running under the same instance than other one, with the same data structure. Here is a fragment of my persistence.xml where I define different schemas according to the persistence unit:
<persistence-unit name="oracle_development" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.archive.autodetection" value="class" />
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy" />
<property name="hibernate.connection.charSet" value="UTF-8" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="false" />
<property name="hibernate.connection.autocommit" value="false" />
<property name="hibernate.ejb.entitymanager_factory_name"
value="o11g" />
<property name="hibernate.default_schema" value="devdatabase"/>
</properties>
</persistence-unit>
<persistence-unit name="oracle_production" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.archive.autodetection" value="class" />
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy" />
<property name="hibernate.connection.charSet" value="UTF-8" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="false" />
<property name="hibernate.connection.autocommit" value="false" />
<property name="hibernate.ejb.entitymanager_factory_name"
value="o11g" />
<property name="hibernate.default_schema" value="proddatabase"/>
</properties>
</persistence-unit>
Well, the tables are generated perfectly, once the table names in creating commands include the default schema as qualifier. But sequences are not generated in the 'proddatabase' if they're already created on 'devdatabase', in example... Any help?
The hibernate.hbm2ddl.auto=”update” is convenient but less flexible if you plan on adding functions or executing some custom scripts.
So, the most flexible approach is to generate the DDL scripts with "org.hibernate.tool.ant.HibernateToolTask" and then use a component to execute the scripts on context startup. The destroy scripts are called when the Spring context is closed.
The second approach is much more flexible, especially if you want to mix JPA Entity Model with jOOQ Table Model.
Needless to say that this is only an Integration testing concern since for the production environment we use Flyway. So, you shouldn't rely on Hibernate for managing your database schema, because it's riskier, less flexible and it doesn't play well with CI and CD.

Best way to create schema in embedded HSQL database

I'm currently using the following setup to create a schema in an embedded database before running my tests against it
In my application context
<jdbc:embedded-database id="dataSource" type="HSQL">
<jdbc:script location="classpath:createSchema.sql" />
</jdbc:embedded-database>
createSchema.sql
create schema ST_TEST AUTHORIZATION DBA;
hibernate properties
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
<property name="hibernate.default_schema" value="ST_TEST"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.use_sql_comments" value="true" />
<property name="hibernate.cache.use_second_level_cache" value="false" />
</properties>
My question is is this the best way to do this. Or can i use a different schema name in my properties? or set the schema name in the jdbc:embedded-database element
By default HSQL creates a schema called PUBLIC. source: HSQL documentation
Seeing as the schema name is never seen in the tests (named queries/entity manager to do the interactions) you can change the hibernate properties to use this PUBLIC schema
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
<property name="hibernate.default_schema" value="PUBLIC"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
</properties>
OR
just leave out the default_schema from the properties list and it uses PUBLIC anyway
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
</properties>
You can use this code in your Base Testing class, and call it using #BeforeClass annotation (for Junit). I do it like this.
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
builder = builder.setType(EmbeddedDatabaseType.HSQL).addScript(
"createSchema.sql");
builder.setName("MyDatabase");
EmbeddedDatabase db = builder.build();

name attribute doesn't seem to work in Field

As I am trying to map Entity to tables using JPA (Hibernate implementation) I found something confusing
when i use annotation on getter, things are OK
#Column(name = "main_battery_voltage", precision = 2)
public float getMainBatteryVoltage() {
return mainBatteryVoltage;
}
but When I try the same thing on field, field name is used and attribute
#Column(name = "main_battery_voltage", precision = 2)
private float mainBatteryVoltage;
System ignores name attribute, runs with column name mainBatteryVoltage in DB and consequently failed task.
I am using MySQL and this is the persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="SolarPersistenceUnit">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.cs.solar.db.entity.User</class>
<class>com.cs.solar.db.entity.Lamp</class>
<class>com.cs.solar.db.entity.Project</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
<!--<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>-->
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/SOLAR"/>
<property name="hibernate.connection.username" value="root" />
<property name="hibernate.connection.password" value="admin" />
<property name="hibernate.connection.autocommit" value="false"/>
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.max_fetch_depth" value="3"/>
</properties>
</persistence-unit>
<persistence-unit name="TestSolar" />
</persistence>
Although it works now, I am curious what cause this problem, thank
You can find a short explanation here:
Hibernate Annotation Placement Question
The point is:
"the access type used by Hibernate will be field or property. The EJB3 spec requires that you declare annotations on the element type that will be accessed, i.e. the getter method if you use property access, the field if you use field access. Mixing EJB3 annotations in both fields and methods should be avoided. Hibernate will guess the access type..."

Categories