Hibernate JPA Core features
Using Session is hibernate specific, using EntityManager is much better as you stick to the JPA specification instead of hibernate.
First level caching is context based and it uses the Session
Second level cache are for the entities that doesn't change between use cases
Query Cache: to cache query result set hibernate.cache.use_query_cache="true"
Enabling second level cache for the entities by setting the following parameter in the persistence.xml
ENABLE_SELECTIVE (Default and recommended value): entities are not cached unless explicitly marked as cacheable.
DISABLE_SELECTIVE: entities are cached unless explicitly marked as not cacheable.
cache concurrency strategy
(NONE, READ_ONLY, NONSTRICT_READ_WRITE, READ_WRITE, TRANSACTIONAL)
@Entity @Cacheable @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) public class Forest { ... }
Transactional: Use this strategy for read-mostly data where it is critical to prevent stale data in concurrent transactions,in the rare case of an update.
Read-write: Again use this strategy for read-mostly data where it is critical to prevent stale data in concurrent transactions,in the rare case of an update.
Nonstrict-read-write: This strategy makes no guarantee of consistency between the cache and the database. Use this strategy if data hardly ever changes and a small likelihood of stale data is not of critical concern.
Read-only: A concurrency strategy suitable for data which never changes. Use it for reference data only.
flush() is used to synchronize the object with database and evict() is used to delete it from cache.
contains() used to find whether the object belongs to the cache or not.
Session.clear() used to delete all objects from the cache .
Suppose the query wants to force a refresh of its query cache region, we should callQuery.setCacheMode(CacheMode.REFRESH).
<property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.SingletonEhCacheProvider" /> <property name="hibernate.cache.provider_configuration" value="/ehcache.xml" /> <property name="hibernate.cache.use_second_level_cache" value="true" />
EHCache has its own configuration file,ehcache.xml, which should be in the CLASSPATH of the application
<diskStore path="java.io.tmpdir"/> <defaultCache maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" /> <cache name="Employee" maxElementsInMemory="500" eternal="true" timeToIdleSeconds="0" timeToLiveSeconds="0" overflowToDisk="false" />
Every non static non transient property (field or method depending on the access type) of an entity is considered persistent, unless you annotate it as @Transient.
@Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_STORE")
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
Eager Fetch and Lazy Fetch:
Default is eagerly fetched. It is equivalent to not defining any annotation.
@Basic int getLength() { ... } // persistent property
@Basic(fetch = FetchType.LAZY) String getDetailedComment() { ... } // persistent property
To enable property level lazy fetching, your classes have to be instrumented: bytecode is added to the original class to enable such feature
@Lob indicates that the property should be persisted in a Blob or a Clob depending on the property type: java.sql.Clob, Character[], char[] and java.lang.String will be persisted in a Clob. java.sql.Blob, Byte[],byte[] and serializable type will be persisted in a Blob.
@Entity public class User { private Long id; @Id public Long getId() { return id; } public void setId(Long id) { this.id = id; } private Address address; @Embedded public Address getAddress() { return address; } public void setAddress() { this.address = address; } } @Embeddable @Access(AcessType.PROPERTY) public class Address { private String street1; public String getStreet1() { return street1; }
Attribute Overrides while using Embeddable:
@Entity public class Person implements Serializable { // Persistent component using defaults Address homeAddress; @Embedded @AttributeOverrides( { @AttributeOverride(name="iso2", column = @Column(name="bornIso2") ), @AttributeOverride(name="name", column = @Column(name="bornCountryName") ) } ) Country bornIn; ... }
@MapsId @OneToOne @JoinColumn(name = "patient_id") Person patient;
@MapsId("userId") @JoinColumns({ @JoinColumn(name="userfirstname_fk", referencedColumnName="firstName"), @JoinColumn(name="userlastname_fk", referencedColumnName="lastName") }) @OneToOne User user;
@ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
@JoinColumn(name="COMP_ID") public Company getCompany() { return company; }
@OrderColumn(name"orders_index") public List<Order> getOrders() { return orders; }
Persistence with Cascading:
CascadeType.PERSIST: cascades the persist (create) operation to associated entities persist() is called or if the entity is managed
CascadeType.MERGE: cascades the merge operation to associated entities if merge() is called or if the entity is managed
CascadeType.REMOVE: cascades the remove operation to associated entities if delete() is called
CascadeType.REFRESH: cascades the refresh operation to associated entities if refresh() is called
CascadeType.DETACH: cascades the detach operation to associated entities if detach() is called
CascadeType.ALL: all of the above
Hibernate Search Configuration in Spring:
<!-- HSearch settings --> <property name="hibernate.search.default.indexBase" value="${hibernateIndexDir}" /> <property name="hibernate.search.default.directory_provider" value="${hibernateDirectoryProvider}" />
@Indexed(index = "myentity") @Table(name = "entity_table")
@Field(index = Index.TOKENIZED, store = Store.YES) private String myString;
Versioning for optimistic locking
The version property will be mapped to the OPTLOCK column, and the entity manager will use it to detect conflicting updates (preventing lost updates you might otherwise see with the last-commit-wins strategy).
@Entity public class Flight implements Serializable { ... @Version @Column(name="OPTLOCK") public Integer getVersion() { ... } }