Hibernate is an ORM framework that implements Java Persistence API (JPA).
For Hibernate to work we need 3 things:
- Hibernate configuration (hibernate.properties or hibernate.cfg.xml)
- Mapping metadata (XML or annotation-based) – info for instructing Hibernate on how the entities have to be mapped to DB tables. Mapping metadata contains persistence unit info. Persistence unit – per database mapping configuration + some other configs. Alternatives for mapping definitions (instead of annotations):
- JPA mapping file – orm.xml
- Hibernate mapping file – hbm.xml
- Session from SessionFactory for being able to invoke persistence methods
Hibernate is accessible from:
- Maven repo
- Hibernate website
- as part of JBoss Application server
Data Model – a table in DB that usually maps to an entity.
Object Model – the entity that will be mapped to the database.
Preferred annotations to be used are the JPA annotations as this will allow for easy switching implementations of JPA (some different framework instead of Hibernate) in future if required.
Every persistent class should have at least 2 annotations: @Entity and @Id. If no annotations are used than a mapping xml file should be created (JPA or Hibernate specific – orm.xml or hbm.xml)
Important annotations:
- @Entity – class level; defines class as being an entity
- @Table – class level; optional; specifies the table that the entity will be saved to. May have the name attribute for explicitly specifying the table name: @Table(name=”SOME_TABLE_NAME”)
- @Id – field level; field that corresponds to the primary key
- @GeneratedValue – field level combined with @Id; defines the way of obtaining the value of the primary key. We must define the strategy attribute if we want to override the default one that is GenerationType.AUTO – ex.: @GeneratedValue(strategy=GenerationType.IDENTITY). There are 4 types of GenerationType: AUTO, SEQUENCE, TABLE, IDENTITY.
- @SequenceGenerator shall be combined with @GeneratedValue in case you use GenerationType.SEQUENCE (Oracle uses sequences for generating ids). It has name and sequenceName attributes that must be specified and also the generator attribute of the @GeneratedValue.
@Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="my_generator") @SequenceGenerator(name="my_generator", sequenceName="SOME_SEQ") private Long id;
- @TableGenerator is to be used if your GenerationType is set to TABLE. A dedicated table is used for storing next available id for each table that used that table.
@Id @GeneratedValue(strategy=GenerationType.TABLE, generator="my_table_generator") @TableGenerator(name="my_table_generator", table="ids_table", pkColumnName="NAME", valueColumnName="VALUE") private Long id;
- @SequenceGenerator shall be combined with @GeneratedValue in case you use GenerationType.SEQUENCE (Oracle uses sequences for generating ids). It has name and sequenceName attributes that must be specified and also the generator attribute of the @GeneratedValue.
- @Column – field level; optional – by default Hibernate will try to find current field name as column name in the table that corresponds to the entity; if field name does not correspond to the column name you have to use the name attribute: @Column(name=”SOME_COLUMN_NAME”)
- insertable attribute – will be passed when insert is performed or not
- updatable attribute – will be passed when update is performed or not
- nullable attribute – nullable at Java label – if you pass a null value it will throw a Hibernate exception at runtime (@Column annotation retention policy is runtime) rather than some DB-specific exception
- @Access – class level; specifies the access type – field or property. There is a value attribute to be set: @Access(value=AccessType.PROPERTY)
- @Transient – field level; skips some column while persisting
- @Temporal – indicates on a temporal field and using attributes helps ensure correct persistence of the time in required format. It is important to set it for any java.util.Date and Calendar classes. Must have value indicated, which can be one of the following:
- TemporalType.DATE
- TemporalType.TIME
- TemporalType.TIMESTAMP
@Temporal(TemporalType.TIME) //or @Temporal(value=TemporalType.TIME) private Date time; //will persist time only
- @Formula – field level; the resulting value will be available only on SELECT (not at INSERT or UPDATE). You need to refresh the entity with the persistence context for getting an accurate value. If you change a property that is also a member of the calculation, your @Formula annotated column will be out of synch, because you did not run the SELECT.
Hibernate can work in 2 ways:
- field access (direct)
- property access (using getter/setter) – if we use this approach you place annotations on the getter. Used when some additional logic is required (like validation).
Key types:
- Surrogate – keys without real meaning – used to identify a record; prefered type.
- Natural – keys with some business meaning
Hibernate types:
- Entity Types – in Java annotated with an @Entity annotation. Corresponds to a row in DB.
- Value Types – they don’t have a table in DB. Are owned by some entity.
- Basic
- Composite – aggregated types
- Collection – hold other value or entity types
@Entity public class Man{ @Id private Long manId; // Basic private Date birthdate; //Basic private Address address; // Composite private List<Man> children; //Collection entity } public Address{ //not an entity private String line1; private String line2; }