About Vlad Mihalcea

Vlad Mihalcea is a software architect passionate about software integration, high scalability and concurrency challenges.

A beginner’s guide to Hibernate Types

The basic mapping concepts

When learning Hibernate many like to jump to parent-child associations without mastering the object relation mapping basics. It’s very important to understand the basic mapping rules for individual Entities before starting modelling Entity associations.

Hibernate types

A Hibernate type is a bridge between an SQL type and a Java primitive/Object type.

 
These are the types Hibernate supports by default:

Hibernate type (org.hibernate.type)JDBC typeJava type
StringTypeVARCHARString
MaterializedClobCLOBString
TextTypeLONGVARCHARString
CharacterTypeCHARchar or Character
BooleanTypeBITboolean or Boolean
NumericBooleanTypeINTEGER (e.g. 0 = false and 1 = true)boolean or Boolean
YesNoTypeCHAR (e.g. ‘N’ or ‘n’ = false and ‘Y’ or ‘y’ = true)boolean or Boolean
TrueFalseTypeCHAR (e.g. ‘F’ or ‘f’ = false and ‘T’ or ‘t’ = true)boolean or Boolean
ByteTypeTINYINTbyte or Byte
ShortTypeSMALLINTshort or Short
IntegerTypeINTEGERint or Integer
LongTypeBIGINTlong or Long
FloatTypeFLOATfloat or Float
DoubleTypeDOUBLEdouble or Double
BigIntegerTypeNUMERICBigInteger
BigDecimalTypeNUMERICBigDecimal
TimestampTypeTIMESTAMPjava.sql.Timestamp or java.util.Date
TimeTypeTIMEjava.sql.Time
DateTypeDATEjava.sql.Date
CalendarTypeTIMESTAMPjava.util.Calendar or java.util.GregorianCalendar
CalendarTypeDATEjava.util.Calendar or java.util.GregorianCalendar
CurrencyTypeVARCHARjava.util.Currency
LocaleTypeVARCHARjava.util.Locale
TimeZoneTypeVARCHARjava.util.TimeZone
UrlTypeVARCHARjava.net.URL
ClassTypeVARCHARjava.lang.Class
BlobTypeBLOBjava.sql.Blob
ClobTypeCLOBjava.sql.Clob
BinaryTypeVARBINARYbyte[] or Byte[]
BinaryTypeBLOBbyte[] or Byte[]
BinaryTypeLONGVARBINARYbyte[] or Byte[]
BinaryTypeLONGVARBINARYbyte[] or Byte[]
CharArrayTypeVARCHARchar[] or Character[]
UUIDBinaryTypeBINARYjava.util.UUID
UUIDBinaryTypeCHAR or VARCHARjava.util.UUID
UUIDBinaryTypePostgreSQL UUIDjava.util.UUID
SerializableTypeVARBINARYSerializable

You can always define your own custom types as we will see in a future article.

Embedded (a.k.a Component) Types

You can group multiple columns to a specific Java type that can be reused throughout your domain model. If the mapped Java object is always dependent on some external Entity you can choose an Embeddable type for such domain model mapping.

An Embeddable object may contain both basic types and association mappings but it can never contain an @Id. The Embeddable object is persisted/removed along with its owning entity.

Assuming we have the following SQL table:

CREATE TABLE entity_event
  (
     id           BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1),
     entity_class VARCHAR(255),
     entity_id    BIGINT,
     message      VARCHAR(255),
     PRIMARY KEY (id)
  );

We could group the entity_class and entity_id to an Embeddable object that we’ll employ in two different owning Entities.

The Embeddable object looks like this:

@Embeddable
public class EntityIdentifier implements Serializable {

    @Column(name = "entity_id", nullable = true)
    private Long entityId;

    @Column(name = "entity_class", nullable = true)
    private Class entityClass;

    public EntityIdentifier() {
    }

    public EntityIdentifier(Class entityClass, Long entityId) {
        this.entityClass = entityClass;
        this.entityId = entityId;
    }

    public Class getEntityClass() { return entityClass; }

    public void setEntityClass(Class entityClass) { this.entityClass = entityClass; }

    public Long getEntityId() { return entityId; }

    public void setEntityId(Long entityId) { this.entityId = entityId; }
}

The associated Entity table will inherit the Embeddable properties associated columns.

Entity

An Entity is the Java equivalent of an SQL table row. The entity must contain an @Id property mapping the associated table Primary Key.

The application logic makes changes to Entities properties and notifies the Persistence Context of Entity state changes (persist, merge, remove). The persistence context will therefore translate all Entity changes to SQL statements.

Assuming we have the following SQL tables:

CREATE TABLE entity_attribute
  (
     id           BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1),
     entity_class VARCHAR(255),
     entity_id    BIGINT,
     name         VARCHAR(255),
     VALUE        VARCHAR(255),
     PRIMARY KEY (id)
  );
 CREATE TABLE entity_event
  (
     id           BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1),
     entity_class VARCHAR(255),
     entity_id    BIGINT,
     message      VARCHAR(255),
     PRIMARY KEY (id)
  );

We can make use of the EntityIdentifier Embeddable type since both tables contain the entity_class and entity_id columns.

@Entity
@Table(name = "entity_attribute")
public class EntityAttribute {

    @Id
    @GeneratedValue
    private Long id;

    private String name;

    private String value;

    private EntityIdentifier entityIdentifier;

    public Long getId() { return id; }

    public String getName() { return name; }

    public void setName(String name) { this.name = name; }

    public String getValue() { return value; }

    public void setValue(String value) { this.value = value; }

    public EntityIdentifier getEntityIdentifier() { return entityIdentifier; }

    public void setEntityIdentifier(EntityIdentifier entityIdentifier) { this.entityIdentifier = entityIdentifier; }
}

@Entity
@Table(name = "entity_event")
public class EntityEvent {

    @Id
    @GeneratedValue
    private Long id;

    private String message;

    private EntityIdentifier entityIdentifier;

    public Long getId() { return id; }

    public String getMessage() { return message; }

    public void setMessage(String message) { this.message = message; }

    public EntityIdentifier getEntityIdentifier() { return entityIdentifier; }

    public void setEntityIdentifier(EntityIdentifier entityIdentifier) { this.entityIdentifier = entityIdentifier; }
}

Testing time

We will create one EntityEvent and one EntityAttribute for a given Product to see how the Embeddable is being persisted along with the owning entities:

@Test
public void testEntityIdentifier() {
	doInTransaction(new TransactionCallable<Void>() {
		@Override
		public Void execute(Session session) {
			Product product = new Product("LCD");
			session.persist(product);
			EntityEvent productEvent = new EntityEvent();
			productEvent.setMessage(String.format("Product %s added", product.getName()));
			productEvent.setEntityIdentifier(new EntityIdentifier(
					product.getClass(),
					product.getId()
			));
			session.persist(productEvent);
			EntityAttribute productAttribute = new EntityAttribute();
			productAttribute.setName("AD_CAMPAIGN");
			productAttribute.setValue("LCD_Sales");
			productAttribute.setEntityIdentifier(new EntityIdentifier(
					product.getClass(),
					product.getId()
			));
			session.persist(productAttribute);
			assertSame(1, session.createQuery("select ea from EntityAttribute ea where ea.entityIdentifier = :entityIdentifier")
					.setParameter("entityIdentifier", new EntityIdentifier(product.getClass(), product.getId()))
					.list().size());
			return null;
		}
	});
}
Query:{[
INSERT INTO product
            (id,
             name)
VALUES      (DEFAULT,
             ?)  
][LCD]} 

Query:{[
INSERT INTO entity_event
            (id,
             entity_class,
             entity_id,
             message)
VALUES      (DEFAULT,
             ?,
             ?,
             ?)  
][com.vladmihalcea.hibernate.masterclass.laboratory.entityidentifier.Product,1,Product LCD added]} 

Query:{[
INSERT INTO entity_attribute
            (id,
             entity_class,
             entity_id,
             name,
             VALUE)
VALUES      (DEFAULT,
             ?,
             ?,
             ?,
             ?)  
][com.vladmihalcea.hibernate.masterclass.laboratory.entityidentifier.Product,1,AD_CAMPAIGN,LCD_Sales]} 

Query:{[
SELECT entityattr0_.id           AS id1_0_,
       entityattr0_.entity_class AS entity_c2_0_,
       entityattr0_.entity_id    AS entity_i3_0_,
       entityattr0_.name         AS name4_0_,
       entityattr0_.VALUE        AS value5_0_
FROM   entity_attribute entityattr0_
WHERE  entityattr0_.entity_class = ?
       AND entityattr0_.entity_id = ?  
][com.vladmihalcea.hibernate.masterclass.laboratory.entityidentifier.Product,1]}

Conclusion

There are still many concepts we need to cover before getting to understand Entity associations. You should always take your time to understand the basic concepts before jumping to more advanced topics. My next post will be about Entity Identifiers and all the available generator techniques.

Reference: A beginner’s guide to Hibernate Types from our JCG partner Vlad Mihalcea at the Vlad Mihalcea’s Blog blog.
Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

Leave a Reply


five × = 40



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close