HSQLDB with Hibernate not saving records after application end - java

I have a sample application which loads 2 records ro database and then fetches all the records from DB and prints info from every record.
My problem is follow: when I run program, it fetches only records which inserted on this running, but not before, Also, when I'm opening DB with SQirrel, there is no such database.
Here is my Hibernate config:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="dialect">org.hibernate.dialect.HSQLDialect</property>
<property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
<property name="connection.url">jdbc:hsqldb:hibertest</property>
<property name="connection.username">sk</property>
<property name="connection.password">0000</property>
<property name="show_sql">true</property>
<property name="current_session_context_class">thread</property>
<property name="hbm2ddl.auto">update</property>
<mapping class="models.Work" />
</session-factory>
</hibernate-configuration>
What I'm doing wrong?

I am not experienced with HSQLDB but try the following URL:
<property name="connection.url">jdbc:hsqldb:file:hibertest;shutdown=true</property>
See: Connection URL documentation.

I believe the default configuration of hsqldb is to not save data on disk for created tables. Please check the hsqldb documentation for how to change this behavior and make tables persistent.
http://hsqldb.org/doc/guide/guide.html#sgc_persist_tables

All the provided answers didn't help me at all.
Currently I use HSQLDB-2.3.2 and hibernate-core-3.5.6 with annotations-3.2.0
In addition to the answer of Tomasz, I needed to manually edit the database script file setting this:
SET WRITE_DELAY 0

You can persist the Data using the HSQL by doing the following,
1.
Connection c = DriverManager.getConnection("jdbc:hsqldb:file:/opt/db/testdb", "SA", "");
"/opt/db/testdb" here is the DB location in the disk.
2. CREATE **TEXT** TABLE <tablename> (<column definition> [<constraint definition>])
3. Assign the source for the Table SET TABLE mytable SOURCE "myfile;fs=|"
Ref: http://hsqldb.org/doc/2.0/guide/texttables-chapt.html
My Github Repository shows the sample https://github.com/Ayyamperumal/HSQL/tree/master/SampleHSQLdb
you can use "Database Development" perspective from Eclipse to see the data. (Supply hsql jar as the driver) Or Execute org.hsqldb.util.DatabaseManager from the hsqldb-*.jar to get the GUI for seeing the data.

Related

How to connect to SQL Server using org.hsqldb.jdbcDriver

There is an application that I only can Update the configuration of this app ( not the code)
This system is using org.hsqldb.jdbcDriver to connect to database scrip in a file like the script below
SET DATABASE UNIQUE NAME HSQLDB3C9CFAE07A
SET DATABASE GC 0
...
CREATE MEMORY TABLE Table1(Field1 BIGINT,Field2 BIGINT,Field3 BIGINT,Field4 VARCHAR(255),Field5 VARCHAR(48))
CREATE MEMORY TABLE Table2(Field1 BIGINT,Field2 BIGINT,Field3 BIGINT,Field4 VARCHAR(255),Field5 VARCHAR(48))
...
INSERT INTO Table1 VALUES(1,10,100,'One','Ten')
INSERT INTO Table1 VALUES(2,20,200,'Two','Twinty')
INSERT INTO Table1 VALUES(3,30,300,'Three','Thirty')
INSERT INTO Table2 VALUES(4,40,400,'Four','Foury')
INSERT INTO Table2 VALUES(5,50,500,'Five','Fifty')
INSERT INTO Table2 VALUES(6,60,600,'Six','Sixty')
I took this script, modified it a little and put it in SQL Server database.
I am trying to change the config file so it can access data in SQL Server instead of the script file
here is what the config file look like
<property key="jdbcDriver" value="org.hsqldb.jdbcDriver"/>
<property key="jdbcUrl" value="jdbc:hsqldb:file:mydata/data/data.script"/>
<property key="jdbcUser" value="sa"/>
<property key="jdbcPass" value=""/>
What shall I put in the jdbcUrl to connect to SQL Server?

Using Hibernate to connect to MS SQL Server

I'm trying to connect to an SQL Server database using Hibernate in Java. My hibernate.cfg.xml file looks like this:
<hibernate-configuration>   
<session-factory>  
<property name = "hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
<property name = "hibernate.connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
<property name = "hibernate.connection.url">jdbc:sqlserver://*******.database.windows.net:1433;databaseName=*******;</property>
<property name = "hibernate.connection.username">*******#******</property>
<property name = "hibernate.connection.password">**********</property>
<property name = "hibernate.show_sql">true</property>
</session-factory>
</hibernate-configuration>
After trying to run the app, I get the following error:
Exception in thread "AWT-EventQueue-0" org.hibernate.internal.util.config.ConfigurationException: Unable to perform unmarshalling at line number 9 and column 23 in RESOURCE hibernate.cfg.xml. Message: cvc-complex-type.2.3: Element 'session-factory' cannot have character [children], because the type's content type is element-only.
Without using an ORM, I tried using the following connection string, and everything worked just fine:
"jdbc:sqlserver://*******.database.windows.net:1433;" +
"database=*****;" +
"user=*****#*******;" +
"password=********;" +
"encrypt=true;" +
"trustServerCertificate=false;" +
"hostNameInCertificate=*.database.windows.net;" +
"loginTimeout=30;"
The database is on MS Azure. Could someone help me with hibernate configuration?
Is it possible to configure hibernate using a connection string, without the configuration file?

Can't persist emojis with mysql and hibernate

I have actually found this problem multiple times on Stackoverflow, but the solutions would not help me.
I have a chat module in my android app and want to persist the messages in my server db, which works fine until special characters like emojis appear.
ERROR: Incorrect string value: '\xF0\x9F\x98\x81' for column 'message' at row 1
...
...
Caused by: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x81' for column 'message' at row 1
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1084)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4232)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4164)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2615)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2776)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2838)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2082)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2334)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2262)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2246)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:187)
... 23 more
My environment is:
-Mysql 5.6
-Tomcat 8.0.8
-Hibernate 4.3.5
-JDK 1.8.0_05
This is the used table with the column in question, 'message':
These are my properties in the persistence.xml (version 2.1):
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/gamedb?useUnicode=true&characterEncoding=UTF-8" />
<property name="javax.persistence.jdbc.user" value="*********" />
<property name="javax.persistence.jdbc.password" value="**************" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
<property name="hibernate.connection.useUnicode" value="true" />
<property name="hibernate.connection.characterEncoding" value="utf8" />
Now I tried the following solutions without effect:
-Change datatype of 'message' from varchar to longtext
-Change collation of 'message' to utf8mb4
-Change collation of table to utf8mb4
-Append url with "?useUnicode=true&characterEncoding=UTF-8"
-Set character-set-server of mysql to utf8mb4
I think the emoji is correctly transmitted to the server, before it persists the message it broadcasts it back to the app and it gets correctly displayed.
I once had the same problem. I don't know a pretty solution but this had worked for me.
After I created the Session object I changed the connection collation by hand:
s.doReturningWork(new ReturningWork<Object>() {
#Override
public Object execute(Connection conn) throws SQLException
{
try(Statement stmt = conn.createStatement()) {
stmt.executeQuery("SET NAMES utf8mb4");
}
return null;
}
});
if you are using hibernate with c3p0, you can use c3p0 config connectionCustomizerClassName whitch you can set to a class doing work with connections c3p0 got.
example:
hibernate.cfg.xml
<property name="hibernate.c3p0.connectionCustomizerClassName">com.hzmoyan.newlyappserver.db.C3p0UseUtf8mb4</property>
C3p0UseUtf8mb4 class
public class C3p0UseUtf8mb4 extends AbstractConnectionCustomizer{
#Override
public void onAcquire(Connection c, String parentDataSourceIdentityToken)
throws Exception {
super.onAcquire(c, parentDataSourceIdentityToken);
try(Statement stmt = c.createStatement()) {
stmt.executeQuery("SET NAMES utf8mb4");
}
}
}
The solution is to use utf8mb4 rather than utf8 in MySQL. The blog post I linked to explains how to do just that.
I just found a nice little hack to get this to work without having to add any code. If you set the validation query to be SET NAMES utf8mb4 then it will execute this when it gets the connection, therefore setting the parameter each time a new connection is retrieved. You also need test on borrow to make this work.
Note I have found that this can sometimes take a few seconds to work after a restart so could have failures if you have records waiting to be processed on startup
So in your application.properties you would add something like
datasource.test-on-borrow=true
datasource.validation-query=SET NAMES utf8mb4
I was able to fix the issue by providing the following in my connection URL;
useUnicode=true&characterEncoding=UTF-8
Example;
jdbc:mysql://localhost/database?useUnicode=true&characterEncoding=UTF-8
Maybe you need to modify hibernate configuration as
<property name="hibernate.connection.characterEncoding" value="utf8mb4" />
If your datasource is org.apache.commons.dbcp.BasicDataSource you can set connectionInitSqls parameter
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.databaseurl}"
p:username="${jdbc.username}"
p:password="${jdbc.password}"
p:testOnBorrow="true"
p:maxActive="1000"
p:testWhileIdle="true"
p:validationQuery="SELECT 1"
p:validationQueryTimeout="5">
<property name="connectionInitSqls">
<list>
<value>SET NAMES 'utf8mb4' COLLATE 'utf8mb4_unicode_ci'</value>
</list>
</property>
</bean>
After not receiving further answers to my comments I found an alternative solution: Base64.
Instead of teaching my DB to understand utf8mb4 I encode all critical messages to Base64 before storing them and decode them when retrieving them from the database.
Pro:
- Works great
- Libraries are already given for java and android
Contra:
- Base64 strings take up more space than the pure utf8mb4 strings (33%-36% more)
- May cost some performance encoding and decoding

Why am I receiving a SqlMapException when inserting data?

I'm trying to use iBatis to insert some data that get sent by a user in a contact us form.
I'm using a Liferay/Spring MVC/iBatis/MySQL setup but I think the problem is caused by the iBatis configuration. Whenever I try to insert data I see an exception in the logs:
com.ibatis.sqlmap.client.SqlMapException: There is no statement named contactus.ibatorgenerated_insert in this SqlMap.
at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.getMappedStatement(SqlMapExecutorDelegate.java:231)
at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.insert(SqlMapExecutorDelegate.java:367)
at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.insert(SqlMapSessionImpl.java:82)
at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.insert(SqlMapClientImpl.java:58)
The ibator generated sql map does contain an insert query with id "ibatorgenerated_insert" with namespace "contact_us"
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMapConfig>
<sqlMap namespace="contactus">
<insert id="ibatorgenerated_insert" parameterClass="contactUs.dao.ContactUs">
<!--
WARNING - This element is automatically generated by Apache iBATIS ibator, do not modify.
This element was generated on Thu Apr 07 15:17:57 BST 2011.
-->
insert into contactus (email_address, first_name, last_name, company, timestamp,
status, message)
values (#emailAddress:VARCHAR#, #firstName:VARCHAR#, #lastName:VARCHAR#, #company:VARCHAR#,
#timestamp:TIMESTAMP#, #status:VARCHAR#, #message:LONGVARCHAR#)
<selectKey resultClass="java.lang.Integer" keyProperty="contactusId">
SELECT LAST_INSERT_ID()
</selectKey>
</insert>
</sqlMap>
</sqlMapConfig>
What can be causing iBatis not to find the statement in the XML file? I assume that it's finding the file since it doesn't report any other kind of error.
I hope that you have specified the contactus.xml file which contains insert statement in the SqlMapConfig.xml as below
<sqlMapConfig>
<properties resource="Connection.properties"/>
<!-- Configure a built-in transaction manager. If you're using an app server, you probably want to use its transaction manager and a managed datasource -->
<settings cacheModelsEnabled="false" enhancementEnabled="true"
lazyLoadingEnabled="true" maxRequests="32" maxSessions="1"
useStatementNamespaces="false" />
<transactionManager type="JDBC">
<dataSource type="JNDI">
<property name="DataSource" value="${connection.datasource}"/>
</dataSource>
</transactionManager>
<!-- List the SQL Map XML files. They can be loaded from the classpath, as they are here (com.domain.data...) -->
<sqlMap resource="contactus.xml"/>
</sqlMapConfig>
Call without namespace.Something like below
sqlMapper.insert("ibatorgenerated_insert",params);
Try adding the following to your <sqlMapConfig> element:
<settings useStatementNamespaces="true"/>

Basic HQL statement always fails

I've recently started trying to use Hibernate, but am doing so in Netbeans. This has left me having to use this example project to try and get me up and running.
Unfortunately, at the step "Enumerating Film Titles and Retrieving Actors Using an HQL Query" my HQL queries do not give results and instead fail, with the exception:
org.hibernate.exception.SQLGrammarException: could not execute query
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'from limit 100' at line 1
It seems that the HQL isn't generating proper MySQL statements but I can't seem to see why, as I've followed the example to the letter thus far.
I am attempting to connect to a local MySQL database named 'sakila', with the following details:
jdbc:mysql://localhost:3306/sakila
which seems to work correctly as I am able to browse the tables from within Netbeans no problem.
My hibernate.cfg.xml is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/sakila</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.show_sql">true</property>
<property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</property>
<mapping resource="dvdrental/Language.hbm.xml"/>
<mapping resource="dvdrental/FilmActor.hbm.xml"/>
<mapping resource="dvdrental/FilmCategory.hbm.xml"/>
<mapping resource="dvdrental/Category.hbm.xml"/>
<mapping resource="dvdrental/Film.hbm.xml"/>
<mapping resource="dvdrental/Actor.hbm.xml"/>
</session-factory>
</hibernate-configuration>
When I'm using the HQL Query window, the SQL it seems to generate only ever says 'select from ' which is obviously wrong, but I can't see why this is being caused?
Edit 1: The HQL Query tab showing my input
Completely stupid reason- I hadn't even thought about the fact I hadn't built the project, so the example code from the bottom of the example ran properly (cause it came pre-compiled). Works no problem now.
I think the main cause of the error is as stated earlier from User, the U in User should be uppercase/capitalized as hibernate uses the POJO. I tried recompiling the code and it works correctly for the sample Swing application: https://netbeans.org/kb/docs/java/hibernate-java-se.html.
However the HQL Query editor still gives this error. It is strange but seems like this editor is not reliable.
The error message 'from limit 100' from your posted exception tells me, that you forgot to add Film after from. Please provide the HQL query that throws the exception.
BTW: the examples in the example project are bad practice. You should never use inline arguments in HQL queries:
from Film as film where film.filmId between '"+startID+"' and '"+endID+"'
You should use query parameters:
Query q = session.createQuery("from Film as film where film.filmId between :startID and :endID");
q.setParameter("startID", startID);
q.setParameter("endID", endID);
When I'm using the HQL Query window, the SQL it seems to generate only ever says 'select from ' which is obviously wrong, but I can't see why this is being caused?
A simple
from Film
is valid HQL and should work. Could you try without the following line:
<property name="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</property>
Not sure this will solve the problem but there is no reason to use the "old" parser anyway.
That replaces the problem with a new one I'm afraid. Now the SQL tab of the HQL pane reports 'Invalid Query', and if I run the query I get org.hibernate.hql.ast.QuerySyntaxException. Any further pointers?
As I said, I was not sure this would solve the problem. What I would do is write a "simple" JUnit test to validate the setup is working. But an obvious bug like this in NetBeans HQL Query window is unlikely, IMO.
Completely stupid reason- I hadn't even thought about the fact I hadn't built the project, so the example code from the bottom of the example ran properly (cause it came pre-compiled). Works no problem now.
I experienced exactly the same problem but I think your stated solution is not correct. Even your project is not compiled HQL will show you results.
One should be careful of Table name in hibernate.cfg.xml file
as it should be same in query (case sensitive) also for example in your case it has table name as "Actor" so
from Actor will work, not from actor

Categories