Hibernate Annotations
EJB3 and Hibernate3 mapping metadata with JDK 5.0 Annotations
Version: 3.0 Preview beta1, 07 04 2005
Please note that this documentation is based on a preview release
of the Hibernate Annotations and implements the Early Draft Release 2 of
EJB 3.0/JSR-220 persistence annotations. However, we expect that this work is already
very close to the final concepts in the new specification. Our goal is to provide
a complete set of ORM annotations, including EJB3 standard annotations as well as
Hibernate3 extensions for cases not covered by the specification. See the
href="#gen37">Compliance and Limitations section for more
information.
1. Introduction
Hibernate, like all other object/relational mapping tools, requires metadata that
governs the transformation of data from one representation to the other (and vice
versa). In Hibernate 2.x, mapping metadata is most of the time declared in XML text
files. Another option is XDoclet, utilizing Javadoc source code annotations and a
preprocessor at compile time. The same kind of annotation support is now available in
the standard JDK, although more powerful and better supported by tools. IntelliJ IDEA,
and Eclipse for example, supports auto-completion and syntax highlighting of JDK 5.0
annotations.
The new revision of the EJB specification (JSR-220) uses JDK 5.0 annotations as the
primary metadata mechanism. Hibernate3 implements the EntityManager of JSR-220
(the persistence API). The Hibernate Annotations package contains the EJB3 and Hibernate3
extension annotations and their internal binding to the Hibernate core.
2. Requirements
Make sure you have JDK 5.0 installed.
You can of course continue using XDoclet and get some of the benefits of
annotation-based metadata with older JDK versions. Note that this document only
describes JDK 5.0 annotations and you have to refer to the XDoclet documentation for
more information.
3. Setup and configuration
First, set up your classpath (after you have created a new project in your favorite IDE):
Hibernate Annotations distribution to your classpath as well.
We also recommend a small wrapper class to startup Hibernate in a static initializer block,
known as HibernateUtil. You might have seen this class in various forms in other
areas of the Hibernate documentation. For Annotation support you have to enhance this
helper class as follows:
|
Interesting here is the use of AnnotationConfiguration and the declaration
of a package and persistent classes.
Alternatively, you can declare your annotated packages and classes in your usual
XML configuration file (usually hibernate.cfg.xml). Here is the equivalent of the
above declaration
|
This kind of declaration is certainly a preferred way. Note that you can mix the the hbm.xml use
and the new annotation one.
There is no other difference in the way you use Hibernate APIs with Annotations, expect for
this change in the startup routine or in the configuration file. You can use your favorite
configuration method for other properties (hibernate.properties, hibernate.cfg.xml, programmatic
APIs, etc). You can even mix annotated persistent classes and classic hbm.cfg.xml
declarations with the same SessionFactory. You can however not declare a class several
times (whether annotated or through hbm.xml). For annotated classes, the classes have to be added
before their subclasses (this limitation will likely be removed soon), e.g.:
|
4. Mapping with EJB3 Annotations
EJB3 entity beans are plain POJOs. Actually they represent the exact same concept as the
Hibernate entities. Their mappings are defined through the JDK 5.0
annotation feature (an XML descriptor syntax hasn't been finalized in the specification).
Annotations come in two categories, the logical mapping annotations (allowing you to
describe the object model, the class associations, etc.) and the physical mapping
annotations (decribing the physical schema, tables, columns, indexes, etc). We will
mix annotations from both categories in the following code examples.
Annotations are in the javax.persistence.* package. IntelliJ is know to work well on it.
4.1 Declaring an entity bean
Every bound persistent POJO class is an entity bean and is declared using the
@Entity annotation (at the class level):
|
For a full example, see Flight.java
of the test suite.
@Entity declares the class as an entity bean (i.e. a persistent POJO class),
@Id declares the identifier property of this entity bean. The other mapping
declarations are implicit. This configuration by exception concept is central to the
new EJB3 specification and a major improvement. The class Flight is mapped to
the Flight table, using the column id as its primary key column.
The @Entity annotation allows you to define whether an entity bean should be
accessed through its getters/setters methods (default) or wheher the entity manager should
access the fields of the object directly:
@Entity(access = AccessType.PROPERTY) |
The EJB3 spec requires that you declare annotations on the artefact
that will be used, i.e. the getter method if you use PROPERTY access, the
field if you use FIELD access.
4.1.1 Defining the table
@Table is set at the class level; it allows you to define the table,
catalog, and schema names for your entity bean mapping. If no @Table is
defined the default values are used: the unqualified class name of the entity.
|
You can also define unique constraints to the table using the @UniqueConstraint annotation
in conjunction with @Table (for a unique constraint bound to a sincle column, refer to @column).
For a full example, see Sky.java
of the test suite.
4.1.2 Versioning for optimistic locking
You can add optimistic locking capability to an entity bean using the
@Version annotation:
|
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).
4.1.3 Entity specific extensions
To empower the EJB3 capabilities, hibernate provides specific annotations that
match hibernate features. The org.hibernate.annotations package contains
all these annotations extensions. Pleaser refer to the
Hibernate Annotations API
for a complete list.
@org.hibernate.annotations.Entity extends @javax.persistence.Entity :
- mutable: whether this entity is mutable or not
- dynamicInsert: allow dynamic SQL for inserts
- dynamicUpdate: allow dynamic SQL for updates
- selectBeforeUpdate: Specifies that Hibernate should never perform an
SQL UPDATE unless it is certain that an object is actually modified. - polymorphism: whether the entity polymorphism is of
PolymorphismType.IMPLICIT (default) or PolymorphismType.IMPLICIT - persister: allow the overriding of the default persister implementation
- optimisticLock: optimistic locking strategy (VERSION, NONE, DIRTY or ALL)
@org.hibernate.annotations.BatchSize allows you to define the batch size when fetching
instances of this entity ( eg. @BatchSize(size=4) )
@org.hibernate.annotations.Proxy defines the lazyness attributes of the entity.
lazy (default to true) define whether the class is lazy or not. proxyClassName
is the interface to use for the lazy initializing proxies.
@org.hibernate.annotations.Where defines an optional SQL WHERE clause used when
instances of this class is retrieved.
@org.hibernate.annotations.Check defines an optional check constraints defined
at the class level.
@org.hibernate.annotations.Cache defines the caching strategy and region of the class.
This annotation is defined at the root entity (not the subentities).
@org.hibernate.annotations.Filter or @Filters define filter(s) to an entity.
A filter is defined by a name() and by a SQL condition()
(with potential parameters).
@org.hibernate.annotations.FilterDef or @FilterDefs define filter
definition(s) used by filter(s) using the same name. A filter definition has a name()
and an array of parameters(). A @ParamDef has a name and a type. A @FilterDef(s)
can be defined at the class or package level.
@Entity |
Please refer to the test suite's
entity package for more
working examples.
4.2 Mapping simple properties
4.2.1 Declaring basic property mappings
By default, every property of an entity bean is mapped persistent, unless you
annotate it as @Transient. Not having an annotation for your property is
equivalent to an appropriate basic annotation (see 4.2.4 for more details).
The @Basic annotation allows
you to declare the fetching strategy for a property:
|
The lengthInMeter property is mapped transient and will be ignored by the
entity manager. The name and the length properties are mapped persistent
and eagerly fetched (the default for simple properties). The detailedComment
property value will be lazily fetched from the database once a lazy property of the entity
is accessed for the first time. The compiled code of your class has to be instrumented for
this feature, please refer to the Hibernate reference documentation. Usually you don't need
lazy simple property fetching (not to be confused with lazy association fetching) and can avoid
any build-time bytecode instrumentation with Hibernate. Hibernate will silently disable lazy
property fetching if you don't instrument the compiled class.
@Serialized indicates that the property should be persisted as a serialized
bytestream.
@Lob indicates that the property should be persisted in a Blob or a Clob depending
the of LobType. java.sql.Clob, Character[], char[] and String
can be persisted in a Clob. java.sql.Blob, Byte[] and byte[]
can be persisted in a Blob.
@Serialized |
4.2.2 Declaring column attributes
The columns use for a property mapping can be defined using the @Column annotation.
Use it to override default values (see the EJB3 specification for more information on the
defaults). You can use this annotation at the property level for properties that are, not annotated
at all, annotated with @Basic, @Version, @Serialized
and @Lob:
|
The name property is mapped to the flight_name column, which is
not nullable, has a length of 50 and is not updatable (making the property immutable).
For more attributes of @Column please refer to the EJB3 spec.
4.2.3 Embedded objects (components)
It is possible to declare an embedded component inside an entity and even override its
column mapping. Component classes (also known as user-defined value types) have to be
annotated at the class level with the @Embeddable annotation. It is
possible to override the column mapping of an embedded object for a particular entity
using the @Embedded annotation in the associated property:
|
|
|
The Person entity bean has two component properties, homeAddress and
bornIn. Note that the homeAddress property has not been annotated.
Hibernate will guess that it is a persistent component after looking for the
@Embeddable in the Address class. We also override the mapping of
a column name (to bornCountryName) with the @Embedded and
@AttributeOverride annotations for each mapped attribute of Country.
As you can see, Country is also nested component of Address, again using
auto-detection by Hibernate and EJB3 defaults. Overriding columns of dependent objects
of dependent objects is currently not supported in the EJB3 spec (user feedbacks are welcome).
4.2.4 Non annotated property
- If the property is of a single type, it is mapped as @Basic
- Otherwise, if the type of the property is annotated as @Embeddable
- Otherwise, if the type of the property is Serializable, it is mapped as
@Serialized - Otherwise, if the type of the property is java.sql.Clob or
java.sql.Blob, it is mapped as @Lob with the appropriate
LobType
4.2.5 Property specific extensions
@org.hibernate.annotations.Type overrides the default hibernate type used: this
is generally not necessary since the type is correctly inferred by Hibernate.
Please refer to the Hibernate reference guide for more informations on the Hibernate types.
@org.hibernate.annotations.TypeDef and @org.hibernate.annotations.TypeDefs
allows you to define type defintions. These annotations are placed at the class or package level.
Note that these definitions will be global for the session factory (even at the class level)
and that type definition has to be defined before any usage.
@TypeDefs( |
4.3 Mapping identifier properties
The @Id annotation lets you define which property is the identifier of your
entity bean. It also allows you to define the identifier generation strategy:
- AUTO - either identity column or sequence depending the underlying DB
- TABLE - table holding the id
- IDENTITY - identity column
- SEQUENCE - sequence
- NONE - the application has the responsability to set the id
The following example shows a sequence generator using the SEQ_STORE
configuration (see below):
|
The next example uses the identity generator:
|
The AUTO generator is the preferred type for portable applications (accross several dB vendors).
The identifier generation configuration can be shared for several @Id mappings
with the generator attribute. There are several configurations available through
@SequenceGenerator, @TableGenerator and @GeneratorTable. The scope
of a generator can be the application or the class. Class-defined generators are not visible outside
the class and can override application level generators. Application level generators are
defined at package level
(see package-info.java):
|
If cfg.addPackage("org.hibernate.test.metadata") is used to initialize the
Hibernate config, EMP_GEN and SEQ_GEN are application level generators.
EMP_GEN defines a table based id generator using the hilo algorithm with a
max_lo of 20 and keeping the hi value in a row of a table defined by the GEN_TABLE
@GeneratorTable. The row has EMP as a primary key value. The table (described by
the @GeneratorTable) is GENERATOR_TABLE, had the column key
(which hold the primary key) and the column hi (which hold the next hi value used).
SEQ_GEN defines a sequence generator using a sequence
named my_sequence. Note that this version of Hibernate Annotations does not
handle initialValue and allocationSize parameters in the SequenceGenerator.
The next example shows the definition of a sequence generator in a class scope:
|
This class will use a sequence named my_sequence and the SEQ_STORE
generator is not visible in other classes. Note that you can Have a look at the Hibernate Annotations
tests in the org.hibernate.test.metadata.id package for more examples.
You can define a composite primary key through several syntaxes:
implementation).
Have a look at Child.java and
Parent.java for some
examples.
4.3 Mapping inheritance
EJB3 supports the three types of inheritance:
- Table per Class Strategy: the <class> element in Hibernate
- Single Table per Class Hierarchy Strategy: the <subclass> element in Hibernate
- Joined Subclass Strategy: the <joined-subclass> element in Hibernate
The chosen strategy is declared at the class level using the @Inheritance annotation.
4.3.1 Table per class
This strategy has many drawbacks (esp. with polymorphic queries and associations)
explained in the EJB3 spec,the Hibernate reference documentation, Hibernate in Action,
and many other places. It is commonly used for the top level of an inheritance
hierarchy:
|
You have to declare inheritance on the leave classes (note: this is an
interpretation of the spec and is subject to change).
4.3.2 Single table per class hierarchy
All properties of all super- and subclasses are mapped to the same table, instances
are distinquished with a special discriminator column:
|
Plane is the superclass, it defines the inheritance strategy
InheritanceType.SINGLE_TABLE, the discriminator type DiscriminatorType.STRING,
and the discriminator value used for planes, "Plane". It also defines the
discriminator column through the @DiscriminatorColumn(name="planetype"). Most of
these atttributes have sensible default values. The default name of the discriminator column
is TYPE, and (for Hibernate) the default discriminator value is the fully qualified
class name. A320 is a subclass; you only have to define discriminatorValue
if you won't accept the default. The strategy and the discriminator type is implicit.
4.3.2 Joined subclasses
This strategy has to be declared on all the subclasses. The @InheritanceJoinColumn
and @InheritanceJoinColumns annotations define the primary key(s) of the joined
subclass table. Note that the current implementation does not support implicit
@InheritanceJoinColumns:
|
Every entity bean declares the JOINED strategy, the Ferry
table is joined with the Boat table using the same primary key names. The
AmericaCupClass table is joined with Boat using the join
condition Boat.id = AmericaCupClass.BOAT_ID.
4.4 Mapping entity bean associations
4.4.1 One-to-one
You can associate entity beans with a one-to-one relationship using @OneToOne.
There are two cases for one-to-one associations: either the associated entities share the
same primary keys values or a foreign key is held by one of the entities (note that this FK
column in the database should be constrained unique to simulate one-to-one multiplicity).
First, we map a real one-to-one association using shared primary keys:
|
|
Unfortunatly, in the current release of Hibernate Annotations, the Heart
identifier value has to be set manually by the application developer. Support for a
Hibernate-style "foreign" identifier generator will be added soon.
In the following example, the associated entities are linked through a foreign key
column :
|
A Customer is linked to a Passport, with a foreign key column named
passport_fk in the Customer table. The join column is declared with the
@JoinColumn annotation which looks like the @Column annotation. It has
one more parameter named referencedColumnName. This parameter declares the column
in the targetted entity that will be used to the join. The current implementation does not
support the referencedColumnName attribute, so Hibernate will join to the primary
key (default value in the specification).
The association may be bidirectional. In a bidirectional relationship, one of the side
has to be the owner : the owner is responsible for the association column(s) update. To
declare a side as non responsible for the relationship, the attribute mappedBy
is used. mappedBy refers the property name of the association on the owner side.
In our case, this is 'passport'. As you can see, you don't have to (must not) declare the
joining column since it is already on the other side.
If no @JoinColumn is declared on the owner side, the defaults apply. A join
column(s) will be created in the owner table and its name will be the concatenation of the
name of the relationship in the owner side, '_' (underscore), and the name of the primary
key column(s) in the owned side. In this example 'passport_id' because the property name is
passport and the column id of Passport is 'id'.
4.4.2 Many-to-one
Many-to-one associations are declared at the property level with the annotation
@ManyToOne; it has a parameter named targetEntity which describes the
target entity name. You usually don't need this parameter since the default value (the
type of the property that stores the association) is good in almost all cases:
|
The @JoinColumn attribute is optional, the default value(s) is like in one to one,
the concatenation of the
name of the relationship in the owner side, '_' (underscore), and the name of the primary
key column in the owned side. In this example 'company_id' because the property name is
company and the column id of Company is 'id'.
In case of a bidirectional, a many to one is always the owner side.
4.4.3 One-to-many
One-to-many associations are declared at the property level with the annotation
@OneToMany. In the current EJB3 specification, you can map Collection
and Set (Map and List are not defined in the spec so far).
Unless the collection is a generic, you'll have to defined targetEntity. One to many
associations may be bidirectional.
4.4.3.1 Bidirectional
Since many to one are always the owner side of a bidirectional relationship in the EJB3 spec,
the one to many association is annotated by @OneToMany( mappedBy=... )
|
Troop has a bidirectional one to many relationship with Soldier
through the 'troop' property. You don't have to (must not) define any physical
mapping in the mappedBy side.
4.4.3.2 Unidirectional
A unidirectional one to many using a foreign key column in the owned entity is not
so common and not really recommanded. We strongly advise you to use a join table
for this kind of association (as explained in the next section). This kind of
association is described through a @JoinColumn
|
Customer describes a unidirectional relationship with Ticket using the
join column 'CUST_ID'.
4.4.3.3 Unidirectional with join table
A unidirectional one to many with join table is much preferred. This association
is described through a @AssociationTable.
|
Trainer describes a unidirectional relationship with Monkey using the
join table 'TrainedMonkeys', with a foreign key 'trainer_id' to Trainer (joinColumns)
and a foreign key 'monkey_id' to Monkey (inversejoinColumns).
4.4.3.4 Default values
Without describing any physical mapping, a unidirectional one to many
with join table is used. The table name is the concatenation of the owner
table name, '_', and the other side table name. The foreign key name(s) referencing
the owner table is the concatenation of the owner table, '_', and the owner
primary key column(s) name. The foreign key name(s) referencing the other side is the
concatenation of the owner property name, '_', and the other side primary key
column(s) name. A unique constraint is added to the foreign key referencing the
other side table to reflect the one to many.
|
Trainer describes a unidirectional relationship with Tiger using the
join table 'Trainer_Tiger', with a foreign key 'trainer_id' to Trainer
(table name, '_', trainer id) and a foreign key 'trainedTigers_id' to Monkey
(property name, '_', Tiger primary column).
4.4.4 Many-to-many
4.4.4.1 description
A many-to-many association is defined logically using the @ManyToMany annotation.
You also have to describe the association table and the join conditions using the
@AssociationTable annotation. If the association is bidirectional, one side has to be
the owner and one side has to be the inverse end (ie. it will be ignored when updating the
relationship values in the association table):
|
|
We've already shown the many declarations and the detailed attributes for associations.
We'll go deeeper in the @AssociationTable description, it defines a @Table,
an array of join columns (an array in annotation is defined using { A, B, C }),
and an array of inverse join columns. The latter ones are the columns of the association
table which refer to the Employee primary key (the "other side"). Note that the current implementation
mandates that you join the entity primary keys, referencedColumnName for
other non pk columns is not supported.
As seen previously, the other side don't have to (must not) describe the physical
mapping: a simple mappedBy argument containing the owner side property name bind
the two.
4.4.4.1 Default values
As any other annotations, most values are guessed in a many to many relationship.
Without describing any physical mapping in a unidirectional many to many
the following rules applied. The table name is the concatenation of the owner
table name, '_' and the other side table name. The foreign key name(s) referencing the owner
table is the concatenation of the owner table name, '_' and the owner primary key
column(s). The foreign key name(s) referencing the other side is the concatenation of
the owner property name, '_', and the other side primary key column(s). These are
the same rules used for a unidirectional one to many relationship.
|
A 'Store_Table' is used as the join table. The 'Store_id' column is a foreign key
to the 'Store' table. The 'implantedIn_id' column is a foreign key to the 'City' table.
Without describing any physical mapping in a bidirectional many to many
the following rules applied. The table name is the concatenation of the owner
table name, '_' and the other side table name. The foreign key name(s) referencing the owner
table is the concatenation of the other side property name, '_', and the owner primary
key column(s). The foreign key name(s) referencing the other side is the concatenation of
the owner property name, '_', and the other side primary key column(s). These are
the same rules used for a unidirectional one to many relationship
|
A 'Store_Customer' is used as the join table. The 'stores_id' column is a foreign key
to the 'Store' table. The 'customers_id' column is a foreign key to the 'City' table.
Check the unit tests contained in the manytomany package,
4.4.5 Transitive persistence with cascading
You probably have noticed the cascade taking an array of CascadeType as a value.
The cascade concept in EJB3 is very is similar to the transitive persistence and cascading
of operations in Hibernate, but with slighty different semantics and cascading types:
- 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.ALL: all of the above
Please refer to the chapter 6.3 of the EJB3 specification for more information on
cascading and and create/merge semantics.
4.4.6 Association fetching
You have the ability to either eagerly or lazily fetch associated entities. The fetch
parameter can be set to FetchType.LAZY or FetchType.EAGER. EAGER will
try to use an outer join select to retrieve the associated object, while LAZY is the
default and will only trigger a select when the associated object is accessed for the first time.
4.4.7 Collection specific extensions
It is possible to set
- the batch size for collections using @BatchSize
- the where clause, using @Where
- the check clause, using @Check
- the caching strategy through the @Cache annotation.
Please refer to the previous descriptions of these annotations
for more informations
4.5 Mapping composite primary and foreign keys
Composite primary keys use a component class as the primary key representation, so you'd use
the @Id and @Embeddable annotations. Alternatively, you can use the
@EmbeddedId annotation. Note that the dependent class has to be
serializable. This implementation only support composite identifiers with component classes.
|
or alternatively
|
@Embeddable can define either a field or a property access strategy for the
component. Composite foreign keys (if not using the default sensitive values) are defined
on associations using the @JoinColumns element, which is basically an array
of @JoinColumns. It is considered a good practice
to express referencedColumnNames explicitely. Otherwise, Hibernate will suppose
that you use the same order of columns as in the primary key declaration.
|
|
|
Note the explicit usage of the referencedColumnName.
A many-to-many association works the same way, you can find an example in
Man.java,
ManPk.java,
Woman.java,
WomanPk.java
4.6 Mapping secondary tables
You can map a single entity bean to several tables using the @SecondaryTable
or @SecondaryTables class level annotations. To express that a column is in
a particular table, use the secondaryTable parameter of @Column or
@JoinColumn. You can find some examples in
Cat.java,
Life.java,
Death.java
5. Mapping Queries
You can map EJBQL/HQL queries using annotations. @NamedQuery and
@NamedQueries can be defined at the class or at the package level.
However their definition is global to the session factory scope.
A named query is defined by its name and the actual query string.
@javax.persistence.NamedQueries( |
5. Compliance and limitations
3.0 Preview beta1 (07-04-2005) based on the EJB3 Early Draft 2
--------------------------------------------------------------
* support parameters in @Type (HBX-197)
* support @TypeDef at package and class level
* HBX-166 support @Lob for Character[],char[], String, byte[] and Byte[] (experimental)
* HBX-159/HBX-140 add @Filter(s) and @FilterDef(s) (Matthew Inger, Magnus Sandberg)
* HBX-44 @OneToOne support composite PK
* @OneToOne is supported except for true bidirectional @OneToOne
* Add @Cache annotation: allow to define caching on root entities and on collections (,eg @Cache(usage=CacheConcurrencyStrategy.TRANSACTIONAL, region="specificCacheRegion") )
* Support @OneToMany default (ie using an association table)
* HBX-164 insertable/updatable of @JoinColumn now work in @ManyToOne processing (Mario Ivankovits, Emmanuel Bernard)
* HBX-153 @Id(generate=GeneratorType.AUTO, generator="my_potential_sequence") now work (Pablo Nussembaum)
* Support @ManyToMany wo @AssociationTable (ie defaults)
* Support @ManyToMany(mappedBy)
* Support @OneToMany(mappedBy) (no JoinColumn needed on the @OneToMany side)
* Appropriate default value when no @JoinColumn is defined in a ManyToOne
* rename @GeneratorTable to @GeneratedIdTable
* rename CREATE to PERSIST, add REFRESH cascade style
* support Mapping Defaults for Non-Relationship Fields or Properties algorithm as defined in the EJB3 spec
* support @Serialized
* support @Lob for java.sql.Clob and java.sql.Blob
* allow embedded object declaration wo @Embeddable (if @Embedded or @EmbeddedId is present in the property)
* support for @EmbeddedId
* rename DependentAttribute to AttributeOverride, Dependent to Embedded and DependentObject to Embeddable
* support @ManyToOne in embedded objects
* support for @NamedQuery and @NamedQueries (EJBQL)
* move javax.ejb.* into javax.persistence.* and update copyright header
3.0alpha3 (28-02-2005)
----------------------
* HBX-116 Support for Where clause in classes and collections @Where(clause="")
* HBX-115 Support for class proxying configuration: @Proxy(lazy=false, proxyClassName="my.Interface")
* HBX-88 Support for hibernate type abstraction through @Type (only on basic properties for now)
* HBX-108 Support @BatchSize(size=n) for entities and collections
* HBX-107 implements @org.hibernate.annotations.Entity
* HBX-103 handle abstract classes
* HBX-83 precision & scale support for column (Bogdan Ghidireac)
3.0alpha2 (25-01-2005)
----------------------
* HBX-61 Support for @UniqueConstraint (except primaryKey=true)
* HBX-60 Support for a proper @TableGenerator (using MultipleHiLoPerTableGenerator)
* HBX-63 Support @GeneratorTable
* HBX-68 Add declarative configuration of annotated classes
* HBX-74 Rollback the HB-1315 fix: dialect no longer have to be set in hibernate.properties
Hibernate-annotations-3.0alpha1 based on the EJB3 Early Draft 1 (6.01.2005)
---------------------------------------------------------------------------
* Support for EJB3 annotations:
- @Transient
- @Column (not primaryKey)
- @JoinColumn (referencedColumnName - only for a reference to a PK, not primaryKey)
- @Version
- @Basic
- @Entity
- @Table (not uniqueConstraints)
- @AccessType
- @Id
- @CascadeType
- @FetchType
- @GeneratorType (NONE, IDENTITY, TABLE, SEQUENCE)
- @TableGenerator (with scope visibility)
- @SequenceGenerator (with scope visibility, does not support initialValue() and allocationSize())
- *not* @GeneratorTable (will have to write a new TableHiloGenerator, but it can wait)
- @ManyToOne (not optional)
- @OneToMany (Set and Collection, generics version or not, JoinColumn not guessed)
- @OneToOne
but not optional
no composite PK/FK
- @ManyToMany
- @AssociationTable (Has to be on both sides)
- @Inheritance
- @InheritanceType (has to be defined on every classes of the hierarchy for JOINED strategy,
not very clear about the TABLE_PER_CLASS strategy)
- @DiscriminatorColumn
- @DiscriminatorType
- @InheritanceJoinColumn
- @InheritanceJoinColumns
this annotation for Composite PK Entities has to be explicit, I do not respect the implicit semantic of the EJB3 spec
- @SecondaryTable (@OneToMany @JoinColumn(secondaryTable="..." does not work yet due to H3 core issue HHH-36
- @SecondaryTables
this annotation for Composite PK Entities has to be explicit, I do not respect the implicit semantic of the EJB3 spec
- @DependentObject
- @Dependent
- @DependentAttribute (only for basic properties as per the spec)
- @Id in conjunction with @DependentObject (composite primary keys)
- @JoinColumns in conjunction with @ManytoOne, @OneToMany, @ManytoMany
- note that the composite FK columns have to be in the same table (no != secondary tables). This is probably a weird case and certainly a not recommanded one.
Still missing or incomplete features compared to the EJB3 spec
--------------------------------------------------------------
- use of referencedColumnName for column other than the PK ones (HX-62)
- better semantic of cascade (HBX-47)
- Support for a true bidirectional one to one relationship (HBX-177)
- inheritance declaration parsing should be more robust (HBX-186)
- annotations inheritance and superclasses (HBX-157) (to be addressed by the next draft)
- appropriate fetching mode on queries (HBX-87)
- implicit join column declaration in inheritance with composite PK (HBX-75)
- @UniqueConstraint(primaryKey=true) (HBX-82)
- support for initialValue and allocationSize in @SequenceGenerator (HBX-59)
- finish support of optional=false (HBX-190)
- @IdClass (HBX-213)
6. Useful links
Hibernate Annotations API
The EJB3 Specification
The EJB3 JBoss tutorial
The Hibernate reference guide
Hibernate In Action