Supported data types
During the previous three levels, we got a little familiar with Hibernate. It's time for the second round. Now we will begin to study the same thing, only deeper. And we will start by mapping the fields of the Entity class to the columns of the tables in the database.
As you already know, mapping a field in an Entity class to a column is done using the @Column annotation . And now the question is: what types of fields can be mapped with such an annotation?
All data types in Java can be divided into three groups:
- The type is quite simple and easy to store in a database .
- The type is complex and you need to write a special converter for it .
- The type is very complex and needs a separate table to store its values .
Simple types that Hibernate knows how to store include:
Types in Java | package | Class examples |
---|---|---|
Primitive Java Types | boolean , int , double , etc. | |
Wrappers over primitives | java.lang | Boolean , Integer , Double , etc. |
Strings | java.lang | String |
"Advanced" numbers | java.math | BigInteger and BigDecimal |
date and time | java.time | LocalDate , LocalTime , LocalDateTime , OffsetTime , OffsetDateTime , Instant |
Various date and time variations | java.util | date and calendar |
Old date and time formats | java.sql | Date , Time , Timestamp |
Array of bytes or characters | byte[] or Byte[] , char[] or Character[] | |
Enums | Any enum | |
Serializable objects | Any implementation of java.io.Serializable |
All of these types have their counterparts in the SQL language, so Hibernate knows how to store and load them from the database.
Example:
@Entity
@Table(name="user")
class User
{
@Column(name="id")
public Integer id;
@Column(name="name")
public String name;
@Column(name="level")
public Integer level;
@Column(name="created_date")
public Date createdDate;
}
Manual type assignments - @Type annotation
Sometimes you may want to tamper with Hibernate's policy and explicitly tell it what type to store data in the database. For example, you have a field in your Entity class of type Integer, but in the base there is a column for it with type VARCHAR.
There is a special annotation for this - @Type . It looks very simple:
@Type(type="type-name")
Let's, for example, ask Hibernate to make the fieldcreatedDateof our User class was stored in the database as a string:
@Entity
@Table(name="user")
class User
{
@Column(name="id")
public Integer id;
@Column(name="created_date")
@Type(type="org.hibernate.type.StringType")
public Date createdDate;
}
If Hibernate figured out how to convert the Date type to your new type, then it would just do it. If it does not understand, then you will need to specify a special type converter. But more on that later.
List of Hibernate types for databases
By the way, did you notice that we specified the type org.hibernate.type.StringType , not String . This is because we have chosen one of the types supported by the DBMS and not by the Java language. They each have their own type system. It's just that the Hibernate developers came up with convenient Java-style names instead of these VARCHARs.
By the way, this list is not so small. I'll give part of it here:
Hibernate type (org.hibernate.type package) | JDBC type | Java type | BasicTypeRegistry key(s) |
---|---|---|---|
StringType | VARCHAR | java.lang.string | string, java.lang.string |
materialized clob | CLOB | java.lang.string | materialized_clob |
Text Type | LONGVARCHAR | java.lang.string | text |
character type | CHAR | char, java.lang.Character | char, java.lang.Character |
BooleanType | bit | boolean, java.lang.Boolean | boolean, java.lang.Boolean |
NumericBooleanType | INTEGER, 0 is false, 1 is true | boolean, java.lang.Boolean | numeric_boolean |
YesNoType | CHAR, 'N'/'n' is false, 'Y'/'y' is true. The uppercase value is written to the database. | boolean, java.lang.Boolean | yes_no |
TrueFalseType | CHAR, 'F'/'f' is false, 'T'/'t' is true. The uppercase value is written to the database. | boolean, java.lang.Boolean | true_false |
ByteType | TINYINT | byte, java.lang.Byte | byte, java.lang.Byte |
short type | SMALLINT | short, java.lang.Short | short, java.lang.Short |
IntegerTypes | INTEGER | int, java.lang.Integer | int, java.lang.Integer |
long type | BIGINT | long, java.lang.Long | long, java.lang.Long |
float type | FLOAT | float, java.lang.Float | float, java.lang.Float |
double type | DOUBLE | double, java.lang.Double | double, java.lang.Double |
BigIntegerType | NUMERIC | java.math.BigInteger | big_integer, java.math.BigInteger |
BigDecimalType | NUMERIC | java.math.BigDecimal | big_decimal, java.math.bigDecimal |
TimestampType | TIMESTAMP | java.sql.timestamp | timestamp, java.sql.timestamp |
TimeType | TIME | java.sql.Time | time, java.sql.Time |
date type | DATE | java.sql.date | date, java.sql.date |
CalendarType | TIMESTAMP | java.util.Calendar | calendar, java.util.Calendar |
CalendarDateType | DATE | java.util.Calendar | calendar_date |
CurrencyType | java.util.Currency | VARCHAR | currency, java.util.Currency |
LocaleType | VARCHAR | java.util.locale | locale, java.utility.locale |
TimeZoneType | VARCHAR, using the TimeZone ID | java.util.TimeZone | timezone, java.util.TimeZone |
UrlType | VARCHAR | java.net.URL | url, java.net.URL |
class type | VARCHAR(class FQN) | java.lang.Class | class, java.lang.Class |
The table, of course, is large, but very useful. For example, it is clear from it that the Boolean type can be stored in the database in at least six different ways. Don't you need that much? And who said that you choose the way to save?
There is no Boolean type in SQL and it is often stored like this:
- 1 or 0
- 'F' or 'T'
- 'Y' or 'N'
Therefore, it is very good when Hibernate understands all these troubles. Or, for example, let's take the storage of data arrays in the database. There are a bunch of different options, and Hibernate knows how to work with them all:
Hibernate type (org.hibernate.type package) | JDBC type | Java type | BasicTypeRegistr |
---|---|---|---|
blob type | BLOB | java.sql.blob | blog, java.sql.blob |
clobtype | CLOB | java.sql.clob | clob, java.sql.clob |
BinaryType | VARBINARY | byte[] | binary, byte[] |
MaterializedBlobType | BLOB | byte[] | materized_blob |
Image Type | LONGVARBINARY | byte[] | image |
WrapperBinaryType | VARBINARY | java.lang.Byte[] | wrapper-binary, Byte[], java.lang.Byte[] |
CharArrayType | VARCHAR | char[] | characters, char[] |
CharacterArrayType | VARCHAR | java.lang.Character[] | wrapper-characters, Character[], java.lang.Character[] |
UUIDBinaryType | BINARY | java.util.UUID | uuid-binary, java.util.UUID |
UUIDCharType | CHAR, can also read VARCHAR | java.util.UUID | uuid-char |
PostgreSQLUUIDType | PostgreSQL UUID, through Types#OTHER, which complies to the PostgreSQL JDBC driver definition | java.util.UUID | pg-uuid |
Hibernate type (org.hibernate.type package) | JDBC type | Java type | BasicTypeRegistr |
---|---|---|---|
DurationType | BIGINT | java.time.Duration | Duration, java.time.Duration |
instant type | TIMESTAMP | java.time.Instant | Instant, java.time.Instant |
LocalDateTimeType | TIMESTAMP | java.time.LocalDateTime | LocalDateTime, java.time.LocalDateTime |
LocalDateType | DATE | java.time.LocalDate | LocalDate, java.time.LocalDate |
LocalTimeType | TIME | java.time.LocalTime | LocalTime, java.time.LocalTime |
OffsetDateTimeType | TIMESTAMP | java.time.OffsetDateTime | OffsetDateTime, java.time.OffsetDateTime |
OffsetTimeType | TIME | java.time.OffsetTime | OffsetTime, java.time.OffsetTime |
OffsetTimeType | TIMESTAMP | java.time.ZonedDateTime | ZonedDateTime, java.time.ZonedDateTime |
GO TO FULL VERSION