Hibernate expected NUMBER got BINARY on null field - java

I can't understand why Hibernate is trying to set this field as a VARBINARY when it is null.
The Java data type is BigDecimal
The Oracle data type is Float
It is being set like this:
entityManager.createNamedQuery("blah").setParameter("target_field", object.sourceValue)
again - sourceValue is a BigDecimal, and when i debug it the value is null.
when it tries to execute this update, I get oracle error:
ORA-00932: inconsistent datatypes: expected NUMBER got BINARY
this is what shows up for this property in the console log:
o.h.type.descriptor.sql.BasicBinder : binding parameter [8] as [VARBINARY] - [null]
IF I do this silly hack in Java before I execute the update:
if (object.sourceValue == null) object.sourceValue = new java.math.BigDecimal(0);
Then it runs fine. So the cause of this error is definitely not anything else than hibernate doing something wrong when the field is null.
How do I fix this so I can set the field to null without hibernate mishandling it?
In the DB, the field is nullable.

It looks the issue has not been resolved yet even with newer version of hibernate 5.2.17.Final with JPA.
The null parameter is being sent as VARBINARY which causes the error
ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] - ERROR: cannot cast type bytea to bigint

One workaround to this is to use the org.hibernate.Query that is wrapped into the org.hibernate.ejb.QueryImpl this way:
QueryImpl q = (QueryImpl) this.entityManager.createNamedQuery("myNamed.query");
q.getHibernateQuery().setParameter("name", value, org.hibernate.Hibernate.BIG_DECIMAL);
q.getResultList();
When value is null, hibernate still can know which type the parameter must be, so it doesn't translate the null to a binary value.

I have solved this problem by adding 2 annotations
#DynamicUpdate(value=true)
#DynamicInsert(value=true)
Also and most important, check mapping on your entity class for getters like (onetomany, manytoone).
All the best.

Related

Getting Unknown object type when trying to set null using TYPES.NULL

I am trying to execute a update statement using JDBC and I am trying to set null values like below.
updateStmt.setNull(j + 1, Types.NULL);
But when ever this statement gets executed I get the below error.
java.sql.SQLException: Unknown object type
at com.informix.util.IfxErrMsg.getSQLException(IfxErrMsg.java:355)
at com.informix.jdbc.IfxValue.createInstanceFromClassName(IfxValue.java:403)
at com.informix.jdbc.IfxValue.makeInstanceFromIfxType(IfxValue.java:635)
at com.informix.jdbc.IfxValue.makeInstanceFromIfxType(IfxValue.java:610)
at com.informix.jdbc.IfxValue.makeInstance(IfxValue.java:390)
at com.informix.jdbc.IfxPreparedStatement.setNull(IfxPreparedStatement.java:396)
What am I doing wrong ? Please help
Not all databases have a dedicated NULL data type, and it seems Informix is one of them.
For best portability use the actual type of the column with a null value.
For example (assuming the column type is VARCHAR, adjust as needed):
updateStmt.setString(j + 1, null);
Or:
updateStmt.setNull(j + 1, Types.VARCHAR);
Don't put Types.NULL. Instead use the Type of the column you want to insert the null into.

Hibernate Query Parameters binding incorrectly

I have been trying to write a hibernate query and have been able to generate the hibernate query through the server, but the parameters in the parameterized query are not getting binded correctly i.e. if 23 is to be binded to parameter 1, but it's getting binded to paramter 3.
Any idea why this would be happening? What should be the points of errors that I should check to get to the root cause of this issue?
EDIT (Why the query is not here?)
The hibernate query is a complex one and it is not possible for me to publish it here. That's why my question is a general one. I just wanted to know, if someone else has also faced this issue, in which hibernate throws no errors and the query is generated successfully, but it's binding incorrect data to incorrect parameter.
I will try to give a rough idea through an example -->
e.g you write:
criteria.createAlias("D.A", "a", CriteriaSpecification.LEFT_JOIN, Restrictions.eq("a.delIndc", false));
criteria.createAlias("A.B", "ab", CriteriaSpecification.LEFT_JOIN,
Restrictions.sqlRestriction("sqlQuery"));
criteria.createAlias("ab.c", "abc", CriteriaSpecification.LEFT_JOIN, Restrictions.eq("c.dataEntry", "Star Wars"));
criteria.createAlias("abc.f", "f", CriteriaSpecification.LEFT_JOIN, Restrictions.eq("f.dataExit", "Star Trek"));
The query is getting generated successfully in the server (no error thrown), but while doing the parameter binding:
2017-12-09 12:09:21,396 TRACE [org.hibernate.jdbc.AbstractBatcher] (pool-14-thread-2) preparing statement
2017-12-09 12:09:21,396 TRACE [org.hibernate.type.BooleanType] (pool-14-thread-2) binding 'false' to parameter: 1
2017-12-09 12:09:21,396 TRACE [org.hibernate.type.BooleanType] (pool-14-thread-2) binding 'Star Trek' to parameter: 2
2017-12-09 12:09:21,396 TRACE [org.hibernate.type.BooleanType] (pool-14-thread-2) binding 'Star Wars' to parameter: 3
So, instead of binding 'Star Wars' to parameter 2, it's getting bind incorrectly to parameter 3.
So, in a nutshell, I want to know, why this might be happening? What are the checks I need to do to get to the root cause of this? And also if you faced this issue, how you found the issue and how you resolved it?
Hope this clarifies my query further. Please help and let me know, if you need any more info in this regard.
You can use 2 ways to bind the parameters in Hibernate - positional parameters, named parameters.
say you have query like:
select name from Emp where id=? and age=?
Here param at 0 position will represent id and param at 1 position will represent age. Here param order is important.
select name from Emp where id=:ID and age=:AGE
Here you can set the params using names ID and AGE, in this case order is not important as you are referring to params using names rather than using their positions.
Provide your code and the values you want to pass in the query.There can be a possibility that you might have modified the name of the property in the pojo/model class

IncorrectResultSizeDataAccessException when no entity is found. First returned when multiple are found

I'm trying to find the reason for one strange behavior. Lets say I have Spring data repository which contains a few methods. One of them has a signature like this:
public Entity findByEntityKeyAndValidToDateAfterAndCorrectionDateAfter(BigInteger entityKey, Timestamp validToDate, Timestamp correctionDate);
I receive an issue with stacktrace with the following error:
org.springframework.dao.IncorrectResultSizeDataAccessException
I decided to add two records which have to be returned when I execute this query.
After calling this method instead of throwing the exception the query returns only one of the results. This was strange to my that is why I copy the query from the log and execute it on my SQL developer with the same parameters. The query return both results. I try to change the method signature to return list of entities:
public List<Entity> findByEntityKeyAndValidToDateAfterAndCorrectionDateAfter(BigInteger entityKey, Timestamp validToDate, Timestamp correctionDate);
In this case, the query returns two results.
Any idea why this may happen? And why this query does not throw this exception?
Spring data version is 1.10.1.RELEASE
When using a find method returning a singular type, the following semantics should apply:
0 elements found => return null or Optional.empty if applicable.
1 element found => return that element.
more than 1 element found => exception should be thrown.
Since this is not what you seem to see please upgrade to at least the current minor version (1.10.11), but preferably to the current GA release(1.11.7). If the problem still persists please create an issue at https://jira.spring.io/browse/DATAJPA/?selectedTab=com.atlassian.jira.jira-projects-plugin:summary-panel

JOOQ insert with type

I'm using jOOQ 3.8.4 and PostgreSQL 9.5 in a Spring 4 application. I have the following table and type definition
CREATE DOMAIN shop.money_amount AS numeric(6,2) DEFAULT 0 NOT NULL CHECK (value > 0::numeric);
CREATE TYPE shop.money AS (
m_amount shop.money_amount,
m_currency shop.currency,
m_country shop.site_country
);
CREATE TYPE shop.money_mapping AS (
mm_moneys shop.money []
);
CREATE TABLE shop.article
(
a_id bigserial NOT NULL,
a_price shop.money_mapping NOT NULL,
CONSTRAINT a_pk_id PRIMARY KEY (a_id)
);
Then I tried an insert using jOOQ, i.e.:
MoneyMappingRecord priceMoneyMapping = new MoneyMappingRecord();
priceMoneyMapping.setMoneys(new MoneyRecord[]{
new MoneyRecord().setAmount(new BigDecimal("11")).setCountry(SiteCountry.US).setCurrency(Currency.USD),
new MoneyRecord().setAmount(new BigDecimal("14")).setCountry(SiteCountry.DE).setCurrency(Currency.EUR)
});
dsl.insertInto(ARTICLE)
.set(ARTICLE.A_PRICE, priceMoneyMapping)
.returning(ARTICLE.A_ID).fetchOne().getId();
Then I get:
Caused by: org.springframework.jdbc.BadSqlGrammarException: jOOQ;
bad SQL grammar [insert into "shop"."article" ("a_price") values
(row(?::money[])) returning "shop"."article"."a_id"]; nested
exception is org.postgresql.util.PSQLException:
ERROR: cannot cast type record to shop.money_mapping
Detail: Cannot cast type money[] to shop.money[] in column 1.
What am I doing wrong?
UPDATE
I tried to rename the shop.money type as suggested by Lukas (from shop.money to shop.localized_money), but I believe that the problem is related to the schema. See the updated error.
Caused by: org.springframework.jdbc.BadSqlGrammarException:
jOOQ; bad SQL grammar [insert into "shop"."article" ("a_price")
values (row(?::localized_money[])) returning "shop"."article"."a_id"]; nested exception is
org.postgresql.util.PSQLException: ERROR: type "localized_money[]" does not exist
Maybe the type in type is an issue!
There seems to be a problem related to casting of nested array of types in jOOQ 3.8. I've created an issue for this: https://github.com/jOOQ/jOOQ/issues/5571
The problem is that your custom type array type needs to be fully qualified when bound as a bind variable. If it isn't fully qualified, then the type isn't found by PostgreSQL. One possible workaround is described in this question: Permanently Set Postgresql Schema Path
You can add the shop schema on your user's search path:
ALTER ROLE <your_login_role> SET search_path TO shop;
... which means that elements inside of the shop schema no longer need to be fully qualified. Which can also be a bad thing, so be careful! :)

database.com JPQL query exception when searching for NULL date fields

I'm trying to convert an old database system to Salesforce and have decided to try out the Database.com Java SDK.
I have recently hit problem that I can't seem to find a work around related to a JPQL Query when searching for NULL or empty dates.
E.g.
select t from table where t.expiryDate is NULL or t.expiryDate = :today
This causes the following exception:
Caused by: [InvalidFieldFault [ApiQueryFault [ApiFault exceptionCode='INVALID_FIELD' exceptionMessage='
from Table__c p where (( p.Expiry_Date__c = 'NULL' ) OR (
^
ERROR at Row:1:Column:158
value of filter criterion for field 'Expiry_Date__c' must be of type date and should not be enclosed in quotes'
]
row='1'
column='158'
]
]
I'm assuming this is a bug in a beta release of the SDK as I don't believe it should be converting the NULL to a string, but please let me know otherwise and/or does anyone know a work around?

Categories