I have a PostgreSQL database schema. And I am trying to generate JPA entities from that schema in IntelliJ with the integrated persistence tool. Everything works fine, except the mapping of timestamps.
The persistence tool is trying to map the PostgreSQL TIMESTAMP data type to java.lang.Object or java.io.Serializable. I can't change the mapping to LocalDateTime, String or anything else.
Is there any way to set the correct mapping types?
UPDATE:
I get the following exception:
SchemaManagementException: Schema-validation: wrong column type encountered in column [timestamp] in table [ProcessEvent]; found [timestamptz (Types#TIMESTAMP)], but expecting [bytea (Types#VARBINARY)]
Have you used the proper annotation for the attribute?
#Entity
public class Employee {
...
#Basic
#Temporal(DATE)
private Calendar startDate;
...
}
Please see: https://en.wikibooks.org/wiki/Java_Persistence/Basic_Attributes#Temporal.2C_Dates.2C_Times.2C_Timestamps_and_Calendars
Related
I have a PostgresSQL production database, but I'm trying to run some of my automated tests against H2 in-memory. I'm trying to persist JSON formatted data to a table but while I'm able to write the data with no complaints, I get conversion exceptions when I read them back. I have no problem doing this in the production Postgres database.
The object I'm persisting is structured similar to the following:
#Entity
public class Record {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(columnDefinition = "jsonb")
#Convert(converter = PersonalInfoConverter.class)
private PersonalInfo personalInfo;
public Record() {}
public Record(PersonalInfo personalInfo) {
this.personalInfo = personalInfo;
}
}
The PersonalInfoConverter just uses a Jackson ObjectMapper to de/serialise the object from/to a String (pretty standard stuff with writeValueAsString, and readValue). To get jsonb to work with H2, I used this trick, which basically sets jsonb as an alias for H2's JSON.
I kept running into conversion errors when reading records from the database, until I stumbled upon this question, which linked to a further discussion on Github about inserting JSON formatted strings into H2 tables. It sounds like to be able to get this to work properly, I need to specifically annotate the string inserted into the H2 database. I assumed that, if this were the case, then Hibernate should have handled this properly itself, but it didn't seem like it works out of the box. How do I configure my code to get this to work?
In the meantime, I'm working around this issue by using jsonb as an alias to H2's text type instead:
CREATE TYPE "JSONB" as text;
I've created a project to demonstrate the issue.
Hibernate does not know about the "JSON" SQL data type and how it needs to be handled. Just use text like you do now, that's totally fine. AFAIU the JSON data type in H2 is just like a domain type with validation i.e. you could replace it with TEXT CHECK is_json(..), so there is not much value in using that particular data type. You could tell hibernate to use #ColumnTransformer to append this FORMAT JSON, but then you'd have issues with PostgreSQL again. Overall, this cross database testing with proprietary features that Hibernate does not abstract over is simply a mess. I would suggest you simply drop H2 and use PostgreSQL with fsync=off for testing which is quite fast already.
I have an Entity CustomEntity with a data member updateDate of type OffsetDateTime.
I have defined a Repository for this Entity which has a simple method to retrieve list of records matching updateDate as
List<CustomEntity> findByUpdateDate(OffsetDateTime updateDate);
Now, when this method is called from Controller/Service bean, I can see no matching record is retrieved; however, when I execute the generated SQL in the DB, I can see matching rows available.
I can retrieve the records based on other data members of the entity; its just an issue with OffsetDateTime and LocalDateTime
I got to understand that java.time package support was not in JPA 2.1; however I am using JPA 2.3.1. Do I need to use Converters (as suggested for JPA 2.1?
Any help is much appreciable.
EDIT :-
Below is the code for Entity
#Entity
#Table(name = "SAMPLE_TABLE")
public class CustomEntity {
#Id
#GeneratedValue
private Long id;
#Column
private OffsetDateTime updateDate;
//Getters & Setters
}
I am using Microsoft SQL Server and the generated SQL query (hibernate generated) looks something like below
select sample0_.id as id1_10, sample0_.updateDate as update2_10 from sample_table sample0_ where sample0_.updateDate=?
binding parameter [1] as [TIMESTAMP] - [2021-07-27T17:22:34.597Z]
I want to have tables located in different database schemas. But unfortunately, I can't achieve this with Spring Boot. Here steps to reproduce it.
Create a new Spring Boot project on http://start.spring.io version 2.0.5 (with derby and PostgreSQL dependencies)
Create simple entity
#Entity
#Table(name = "my_table")
public class MyTable {
#Id Integer id;
}
Add only next property to the application.properties with value 'update' or 'create' (if you try 'create-drop' then you get another error described here: https://github.com/spring-projects/spring-boot/issues/7706#issuecomment-268798059). Now Derby datasource will be used by default.
spring.jpa.hibernate.ddl-auto=create
Run a generated test or main class. Be sure all works fine.
Modify the entity, add attribute schema to the #Table annotation. Now the entity looks like:
#Entity
#Table(name = "my_table", schema = "my_schema")
public class MyTable {
#Id Integer id;
}
Run a test (or main class). This time I get an error while Spring Boot initialization process "java.sql.SQLSyntaxErrorException: Schema 'MY_SCHEMA' does not exist":
Full log listing is available here: https://gist.github.com/asaushkin/8d767c92b2e7025dd359f7be43eefdd6
Check on PostgreSQL. This error reproduces on a PostgreSQL instance too. Without the 'schema' attribute Spring Boot app runs perfect, but as soon as this attribute appears on the #Table annotation the exceptions are thrown.
Full log is here: https://gist.github.com/asaushkin/dd0d677964556bf943c4f013d4785372
My question is: why are schemas not created by Spring Boot?
These options can't resolve this issue too:
spring.jpa.properties.javax.persistence.schema-generation.create-database-schemas=true
spring.jpa.properties.hibernate.hbm2dll.create_namespaces=true
Links
https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#configurations-hbmddl
https://docs.spring.io/spring-boot/docs/current/reference/html/howto-data-access.html#howto-configure-jpa-properties
Update (11 March 2019):
I've just check the current behavior of the issue. I wonder, but currently with Derby driver all works fine and the table is created with the specified schema. But in PostgreSQL an error continues exists.
Generated SQL (for PostgreSQL) is:
create table my_schema.my_table (id int4 not null, primary key (id))
Check that are you specifying the database dialect in the application.properties file or not for more check this thread.
Unable to get spring boot to automatically create database schema
I had the same problem with PostgreSQL and JPA (ERROR o.h.e.jdbc.spi.SqlExceptionHelper - ERROR: relation "schema.table" does not exist) and I figured out this solution.
In your entities classes, add escape characters \", between database element´s name. For instance:
Use this form:
#Table(name = "\"USUARIO\"", schema="\"INVENTARIODB\"")
Rather than a typical way
#Table(name = "USUARIO", schema="INVENTARIODB")
The same applies for columns names
#Column(name = "\"ID\"", nullable = false, updatable = false)
private Long id;
Rather than
#Column(name = "ID", nullable = false, updatable = false)
private Long id;
UPDATE:
I discovered the reason that was causing the problem. I used Valentina Studio to create my DB, if I use capital letters (MYTABLE), instead lower-case letters (mytable) to create my tables, I had to use double quotes inside SQL statements. This is because PostgreSQL is case sensitive. If you can´t change your database then use my last solution. Also is a good idea to enable spring.jpa.show-sql=true property, so you can see hibernate´s queries and know what´s going on.
Rename spring.jpa.properties.javax.persistence.schema-generation.create-database-schemas to spring.jpa.properties.javax.persistence.create-database-schemas. In other words, remove '.schema-generation'.
I just had the same problem not with PostgreSQL but H2 - schemas weren't being created. But, as I've discovered, the problem is not with H2 (or, likely, PostgreSQL) but, rather, Hibernate (it deviates from the standard, regarding that nomenclature). That likely means that this solution will work for you too.
I'm using Spring Boot with Spring Data JPA to map an Entity to a table in a SQL Server database for which I've created an #Embeddable composite key. There's a column I'd like to use as part of the key and according to SQuirreL its type name is datetime and the class name is java.sql.Timestamp. The key class looks like this:
#Embeddable
public class MyEntityIdentifier implements Serializable {
#Column(name = "LastUpdateDateTime")
private Timestamp lastUpdateDateTime;
...but the lastUpdateDateTime property always resolves to null without error. I've checked and there are no null fields for this column. I've also tried resolving to java.util.Date without success. Is there another type I should be using or something I'm doing wrong?
Hibernate will internally convert to a native Java type (i.e. java.util.Date as opposed to java.sql.Timestamp) by adding the #Temporal annotation.
#Column(name = "LastUpdateDateTime")
#Temporal(TemporalType.DATE)
private Date lastUpdateDateTime;
I'm working on a project in which I have a class with this attribute:
#Column(name="XMLDATA", columnDefinition="CLOB NOT NULL") #Lob #Basic(fetch=FetchType.LAZY)
#Getter #Setter private String _xmlData;
In the database, the column type for that attribute is CLOB.
I'm running the application on weblogic 11gR1 (10.3.5), using Oracle database (11gR2), JPA and eclipselink as JPA Provider. The problem I have is that everytime I save a registry on the database, the clob is the only field that is not saved.
But if I don't put the #lob annotation, then it works fine.
In the logs, I can see that first it uses an "insert" sentence to insert all the data except for the clob, and then it uses a "select for update" sentence to insert the clob data, I don't know if this may be part of the problem.
Thank you.
For the proper management of the blobs (JPA + Oracle) you must specify the following properties of eclipselink :
property name="eclipselink.target-database"
value= "org.eclipse.persistence.platform.database.oracle.Oracle11Platform"
It seems that JPA sometimes cannot detect the correct version of Oracle Database platform
I've searched a lot for this answer, until I realized that if you are using EclipseLink, at least 2.5.2 version, you don't have to use "#Column(name="XMLDATA", columnDefinition="CLOB NOT NULL") #Lob #Basic(fetch=FetchType.LAZY)". Just do this:
#Column(name = "XML_DATA")
private String _xmlData;
EclipseLink will know how to handle the CLOB column.