How can I get Hibernate to map nvarchar and ntext? - sql-server-2008

I've inherited a project that uses SQLServer 2008 (and maybe 2005). Certain tables use nvarchar(255) and nvarchar(MAX) which Hibernate can't deal with. I've tried these proposed solutions:
How can Hibernate map the SQL data-type nvarchar(max)?
http://blog.cherouvim.com/sql-server-hbm2ddl-unicode-columns/
They don't work with nvarchar(MAX), unfortunately. I get this Exception
Caused by: org.hibernate.HibernateException: Wrong column type in MTP.dbo.Impact
edDetail for column Message. Found: ntext, expected: nvarchar(255)
The remaining problem is getting one of these solutions to work with nvarchar(MAX).
Is there a way to make Hibernate work with these unicode column types? If Hibernate won't work I can switch to another JPA provider that knows how to handle them properly.
Thanks.

I was able to handle nvarchar(MAX) by using the #Lob annotation on the corresponding field in the Entity class while also used the SqlServerNativeDialect class in the link above.

Related

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.

Alternate solution to save as JSON datatype in postgres spring-boot + eclipselink

I am using eclipselink 2.6 with spring-boot JPA for persistance in postgres.
I am persisting a List of objects as a JSON column in database.Acording to this solution: eclipselink + #convert(json) + postgres + list property
I am able to save the data in postgres.
When the column is null, I get this exception:
Caused by: org.postgresql.util.PSQLException: ERROR: column "sample_column" is of type json but expression is of type character varying
Hint: You will need to rewrite or cast the expression.
I can solve this issue by this answer:
Writing to JSON column of Postgres database using Spring / JPA
Q1: Is there an alternate solution other than setting this property stringtype=unspecified int url spring.datasource.url=jdbc:postgresql://localhost:5432/dbnam‌​e?stringtype=unspeci‌​fied
Q2: If not, How can I set stringtype=unspecified in application.prooerties of spring-boot rather than embedding it in the spring.datasource.url
The answer is yes, but is implementation-specific.
For example, in Tomcat, this attribute is called connectionProperties, you would therefore write:
spring.datasource.tomcat.connection-properties: stringtype=unspecified
From the Spring-Boot documentation.
It is also possible to fine-tune implementation-specific settings using their respective prefix (spring.datasource.tomcat., spring.datasource.hikari., spring.datasource.dbcp.* and spring.datasource.dbcp2.*). Refer to the documentation of the connection pool implementation you are using for more details.
If you are using spring-boot 1.4.1 or above,
add a data.sql file in resources folder,
-- IN H2 database, create a column as 'OTHER' data type,
-- if H2 fails to create a column as 'JSON' data type.
CREATE DOMAIN IF NOT EXISTS JSON AS OTHER;
This .sql file will be executed during startup of your application and will create a column with data type others in table for the 'json' data type columns in H2 database.

The data types nvarchar(max) and ntext are incompatible in the equal to operator.

I am new to hibernate.
I have a scenario where i am using Xstream frame work to export the tables into XML format and importing another instance of DB tables, where i have my application with Hibernate & spring.
One instance where one column of a table is nvarchar(max) in the db.
while i am inserting into the table from xml, it is failinging giving below error.
Caused by:
java.sql.SQLException: The data types nvarchar(max) and ntext are incompatible in the equal to operator.
at net.sourceforge.jtds.jdbc.SQLDiagnostic.addDiagnostic(SQLDiagnostic.java:368)
at net.sourceforge.jtds.jdbc.TdsCore.tdsErrorToken(TdsCore.java:2820)
at net.sourceforge.jtds.jdbc.TdsCore.nextToken(TdsCore.java:2258)
at net.sourceforge.jtds.jdbc.TdsCore.getMoreResults(TdsCore.java:632)
at net.sourceforge.jtds.jdbc.JtdsStatement.executeSQLQuery(JtdsStatement.java:477)
at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.executeQuery (JtdsPreparedStatement.java:778)
at org.jboss.resource.adapter.jdbc.WrappedPreparedStatement.executeQuery (WrappedPreparedStatement.java:342)
at org.hibernate.persister.entity.AbstractEntityPersister.getDatabaseSnapshot(AbstractEntityPersister.java:1021)
at org.hibernate.engine.StatefulPersistenceContext.getDatabaseSnapshot(StatefulPersistenceContext.java:246)
at org.hibernate.engine.ForeignKeys.isTransient(ForeignKeys.java:189)
at org.hibernate.event.def.AbstractSaveEventListener.getEntityState(AbstractSaveEventListener.java:512)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:80)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:507)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:499)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:495)
at org.springframework.orm.hibernate3.HibernateTemplate$18.doInHibernate(HibernateTemplate.java:772)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:419)
I used the above mentioned provided solutions ...but none is of help for me.
i am using SQL 2008 server as DB and hibernate 3 jars.
It is working fine upto 4000 chars, but column exceeds it is not working.
and giving above exception
Please do advice how to solve this problem.

Automatically generated Entities from mysql database in Netbeans always fail to deploy

I am new to Java EE (and to Netbeans). I have am trying to automatically generate entity classes from my mysql database... For simple relationships it works, but for the following it always fails:
i get the following error:
Internal Exception: Exception [EclipseLink-7220] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The #JoinColumns on the annotated element [field tblExpandituresTranx] from the entity class [class entities.restaurant.TblContents] is incomplete. When the source entity class uses a composite primary key, a #JoinColumn must be specified for each join column using the #JoinColumns. Both the name and the referencedColumnName elements must be specified in each such #JoinColumn.. Please see server.log for more details.
I think... I have some error in my database or perhaps EclipseLink JPA tool is kaput!
please help!
Could be that your schema is upside down.
Or you could actually read the exception you're getting and figure out what it's telling you:
The #JoinColumns on the annotated element [field tblExpandituresTranx] from the entity class [class entities.restaurant.TblContents] is incomplete. When the source entity class uses a composite primary key, a #JoinColumn must be specified for each join column using the #JoinColumns. Both the name and the referencedColumnName elements must be specified in each such #JoinColumn
Looks like you've got an incomplete specification for the JOIN.
I solved the problem myself...
Apparently JPA has a problem with multiple primary keys in bridge tables. So, instead of having foreign keys as primaries I just converted them to unique indexed and everything worked just fine!! wuhu!!

MySql Connector 6.5.4 - Stored Procedure Return Entity with a boolean field - Entity Framework

Searching, reading forums and all suggestion of SO before writing. (1 day already investigating the issue).
Im using: MySql Server 5.5 with Entity Framework 4.3 with Connector 6.5.4
(I was using connector 6.3.6 and everything worked perfectly, updated and problem occurs)
I have a SP that returns an List of an Entity Object. That Entity have a bool (tinyint(1)) field BUT when using the SP it returns it as string.
I created a temporary table and return that but the same problems occurs. The error is:
System.InvalidOperationException: The 'isDeleted' property on 'Container' could not be
set to a 'String' value. You must set this property to a non-null value of type
'Boolean'. at
System.Data.Common.Internal.Materialization.Shaper.ErrorHandlingValueReader`1.
GetValue(DbDataReader reader, Int32 ordinal)
Problem is, since it's a Entity object, i cannot Convert.ToBoolean() [also i dont want to].
I think the problem is that i don't have the ability to cast the SP field as bool or the connector has a bug (most likely).
As I said, it worked with no problem with connector 6.3.6
Thanks.
The bug is there but I found a workaround. The problem happend when the order of the fields aren't the same.
This BUG: http://bugs.mysql.com/bug.php?id=53166 helped me to understand and try making the select order of fileds the same the table.
Example:
If table is :
field_a, field_b, field_c
and your stored procedures returns: field_b, field_a, field_c won't work.
Changed my SP to return field_a, field_b, field_c