Hibernate schema validation error for timestamp column - spring-boot

While converting from joda.time classes to java.time classes in application using Spring Boot 2.7.0, Hibernate 5.2.10.Final, Java 11, I have run into a problem with an error being thrown from Hibernate schema validation phase.
The error is
Caused by: org.hibernate.tool.schema.spi.SchemaManagementException:
Schema-validation: wrong column type encountered in column
[header_date_created] in table [daily_ count]; found [date
(Types#DATE)], but expecting [timestamp (Types#TIMESTAMP)]
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.validateColumnType(AbstractSchemaValidator.java:167)
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.validateTable(AbstractSchemaValidator.java:151)
The postgresql column definition is timestamp.
The column in the #Entity Java class is defined as:
#Column(name = " header_date_created")
private Date headerDateCreated;
I have even tried to use the java.persistence annotations of #Basic and #Temporal to clarify the type. But the same error is triggered. Tried both TemporalType.TIMESTAMP and TemporalType.DATE but it made no difference.
In the database schema all dates are defined as SQL type timestamp. When using joda.time classes the entity used LocalDateTime. Now with the conversion I am using java.util.Date. This worked type works for entities using JPA Auditing with the #CreatedDate and #LastModifedDate annotations but using it for other date members cause the above error.
Other types I have tried are the OffsetDateTime and the LocalDateTime classes but the result is always the same.
Not sure what I am doing wrong. Anyone else run into this problem?

Problem turned out to be a discrepancy in DDL. The column definition ended up being date, not timestamp.

Related

Spring boot #Query ignores #Table on view call

I have a spring boot 2 application that works great with entities that are mapped to a table that is in a MariaDB. I now do a view call and I have mapped that entity to the view using the #Table(name="ViewExpiredAccounts") annotation and now when the method is called the table name is ignored. I have a JpaRepository with this method:
#Query(value = "SELECT v FROM ViewExpiredAccounts v")
List<ViewExpiredAccount> expiredAccounts();
When I call this method I get an error:
Table 'view_expired_accounts' doesn't exist
The query SHOULD! translate the table name so that the eventual SQL query sent to MariaDB is: SELECT * from ViewExpiredAccount however it doesnt do that. Is this a bug in Spring??
did you reset the hibernate naming strategy?
if yes, the following property might help
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

Error when add data by JPA repository [duplicate]

#Column(name="open")
Using sqlserver dialect with hibernate.
[SchemaUpdate] Unsuccessful: create table auth_session (id numeric(19,0) identity not null, active tinyint null, creation_date datetime not null, last_modified datetime not null, maxidle int null, maxlive int null, open tinyint null, sessionid varchar(255) not null, user_id numeric(19,0) not null, primary key (id), unique (sessionid))
[SchemaUpdate] Incorrect syntax near the keyword 'open'.
I would have expected hibernate to use quoted identifier when creating the table.
Any ideas on how to handle this... other than renaming the field?
With Hibernate as JPA 1.0 provider, you can escape a reserved keyword by enclosing it within backticks:
#Column(name="`open`")
This is the syntax inherited from Hiberate Core:
5.4. SQL quoted identifiers
You can force Hibernate to quote an
identifier in the generated SQL by
enclosing the table or column name in
backticks in the mapping document.
Hibernate will use the correct
quotation style for the SQL Dialect.
This is usually double quotes, but the
SQL Server uses brackets and MySQL
uses backticks.
<class name="LineItem" table="`Line Item`">
<id name="id" column="`Item Id`"/><generator class="assigned"/></id>
<property name="itemNumber" column="`Item #`"/>
...
</class>
In JPA 2.0, the syntax is standardized and becomes:
#Column(name="\"open\"")
References
Hibernate reference guide
5.4. SQL quoted identifiers
JPA 2.0 specification
2.13 Naming of Database Objects
Related questions
Hibernate, MySQL and table named “Repeat” - strange behaviour
Automatic reserved word escaping for Hibernate tables and columns
Had the same problem, but with a tablename called Transaction. If you set
hibernate.globally_quoted_identifiers=true
Then all database identifiers will be quoted.
Found my answer here
Special character in table name hibernate giving error
And found all available settings here
https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/appendices/Configurations.html
Could not find better docs for this though.
In my case the setting was in my Spring properties file. As mentioned in the comments, it could also be in other, hibernate related, configuration files.
Manually escaping the reserved keywords
If you are using JPA, you can escape with double quotes:
#Column(name = "\"open\"")
If you're using Hibernate native API, then you can escape them using backticks:
#Column(name = "`open`")
Automatically escaping reserved keywords
If you want to automatically escape reserved keywords, you can set to true the Hibernate-specific hibernate.globally_quoted_identifiers configuration property:
<property
name="hibernate.globally_quoted_identifiers"
value="true"
/>
Yaml format
spring:
jpa:
properties:
hibernate:
globally_quoted_identifiers: true
If you use as shown below it should work
#Column(name="[order]")
private int order;
#Column(name="\"open\"")
This will work for sure, Same problem happened with me, when I was learning hibernate.
There is also another option: hibernate.auto_quote_keyword
which
Specifies whether to automatically quote any names that are deemed keywords.
<property name="hibernate.auto_quote_keyword" value="true" />
Yaml
spring:
jpa:
properties:
hibernate:
auto_quote_keyword: true
No - change the column name.
This is database-specific, and you just can't create such a column. After all hibernate finally sends DDL to the database. If you can't create a valid DDL with this column name, this means hibernate can't as well. I don't think quoting would solve the issue even if you are writing the DDL.
Even if you somehow succeed to escape the name - change it. It will work with this database, but won't work with another.
Some JPA implementations (e.g the one I use, DataNucleus) automatically quote the identifier for you, so you never get this.

ODP.Net OracleBulkCopy 'not a valid month' with a date field

First it is important to note that this error is occuring while importing a set of data using the OracleBulkCopy object in a WPF application with the data stored in a DataTable object.
In this table there is one column which is of type "Date" (oracle) and the corresponding type is DateTime? (nullable) in the WPF application. However when setting up the DataTable for the OracleBulkCopy object I'm setting the data type of that column to DateTime (non-nullable) as nullable types are not permitted in the DataTable's DataColumn objects.
What is happeneing is that the data import works fine when all date values are null but as soon as I try an import with any actual dates I'm getting the error "Not a valid month" from the Oracle server. Normally when something like this happens you can use "to_date" to specify how the date is supposed to be interpreted.
Using OracleBulkCopy this is not possible and should also not be necessary as the dates aren't strings but actual DateTime objects.
I have also tried using the data type Oracle.DataAccess.Types.OracleDate but this had the same result.
I have not been able to find any solution to this so any help would be appreciated.

comparing timestamp and date in Derby

I need to compare a date and a timestamp in a SELECT query. Normally, this is supported by most other DB platforms(MySQL, MSSQL, Oracle, etc.) but in Derby it throws this error:
Caused by: java.sql.SQLSyntaxErrorException: Comparisons between
'DATE' and 'TIMESTAMP' are not supported. Types must be comparable.
String types must also have matching collation. If collation does not
match, a possible solution is to cast operands to force them to the
default collation (e.g. SELECT tablename FROM sys.systables WHERE
CAST(tablename AS VARCHAR(128)) = 'T1')
I don't want to use CASTs because I cannot change the SQL query. Is this a bug from Derby that will get fixed sometime? I'm currently using Derby 10.8.2.2.
Thanks!
If you are connecting from a java program you can get specific parts of a Timestamp using various getxxx() methods (these are actually inherited from Java.util.date)
See the docs http://docs.oracle.com/javase/7/docs/api/java/util/Date.html
and check the getDate(), getDay() getHour().... methods
Perhaps you can define a VIEW on one of the tables, and include the CAST in the VIEW. That way, you don't have to change the actual query; it will go against the view, and thus include the cast in that way.

Unsuccessful creation of table in Oracle

I am creating a domain class in my grails application.This is my domain class
class StatTiming {
Date startTime
Date endTime
Date date
double percentageOnTariff
AutoPosting autoPosting
Status status
static constraints = {
startTime(nullable:false)
endTime(nullable:false)
date(nullable:false)
percentageOnTariff(nullable:false)
autoPosting(nullable:false)
status(nullable:false)
}
enum Status{ACTIVE,INACTIVE}
enum AutoPosting{SERVICE_CHARGE,STAT_CHARGES,BOTH}
}
Its working fine in hsqldb, but when i change database to Oracle its failed to create the table. I need to work in Oracle not hsqldb. An error is generated called "ORA-00904: : invalid identifier". Can anyone please tell me what is the problem here?
The problem is most likely with the field named date. That's a reserved word in Oracle.
(But without seeing the exact query, this is just a guess.)

Resources