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
And since the release of JDK 8, Hibernate has added a few more time-related types. All to make your life easier. You no longer have to wonder if all these newfangled types are supported. The creators of Hibernate have already added their support for you:
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