Skip to content
Vadim Lopatin edited this page Jun 19, 2013 · 1 revision

Mark your classes with following User Defined Attributes (Annotations)

Entity level annotations

Annotation Description
@Entity or @Entity() marks class as HibernateD entity. By default, class name is used as entity name.
@Entity(name) marks class as entity, specifying entity name (may be different from class name)
@Table(name) specify table name to store entity (lowercased entity name will be used if there is no @Table annotation)
@Embeddable @Embeddable() - marks class as HibernateD embeddable object - can be used in @Embedded properties to aggregate all fields of @Embeddable object to parent object.

Class should have either @Entity or @Embeddable annotation to be included into metadata.

Property level annotations

Property of entity usually refers to column of table in DB (for simple properties) or relation (aggregate properties).

You can mark field, property or getter/setter pair of entity class to define HibernateD property.

Primitive properties

Property marked with either @Column, @Id, @Generated, @Generator annotation is considered as primitive property (corresponds to single column of table in DB).

Supported primitive types: string, byte, short, int, long, ubyte, ushort, uint, ulong, byte[], ubyte[], DateTime, Date, TimeOfDay, Nullable!byte, Nullable!short, Nullable!int, Nullable!long, Nullable!ubyte, Nullable!ushort, Nullable!uint, Nullable!ulong, Nullable!DateTime, Nullable!Date, Nullable!TimeOfDay.

Nullable! template may be used to support nullability for types which cannot hold nulls.

Annotation Description
@Column or @Column() marks field, property or getter method as entity property, using name of member with first letter lowercased and get/set/is prefixes removed as column name for DB.
@Column(name) marks field, property or getter method as entity property, specifying column name for DB
@Column(name, length) same as previous, but added length of column (e.g. for VARCHAR column).
@Null and @NotNull may be used to specify column's nullability. Otherwise nullability will be deduced from field type.
@UniqueKey can be used to create UNIQUE INDEX for column in DB.
@Id or @Id() mark property as primary key for entity
@Generated mark property as key generated on DB side (e.g. AUTO_INCREMENT)
@Generator(code) specify generator code for key property.

There is a constant for standard GUID generator in hibernated.annotations module:

const string UUID_GENERATOR = "std.uuid.randomUUID().toString()";

@Entity class should have one property marked as primary key (using either @Id, @Generated, or @Generator annotation).

@Embeddable class should not have primary key property (@Id, @Generated, or @Generator annotation).

Sample primitive property annotations on single class:

@Entity
@Table("users")
class User { // entity name will be 'User' - from class name

	@Generated
	int id;

	@Column("name")
	string name;

            @Column
            Nullable!long flags; // nullable long

            @Column
            byte[] data; // blob

            // sample property
            private int _age;
            @Column
            @property short age() { return _age; }
            @property void age(short v) { _age = v; }

            // sample getter/setter
            // column name will be 'married' - from isMarried
            private bool _married;
            @Column
            bool isMarried() { return _married; } 
            void setMarried(byte v) { _married = v; }

            // sample getter/setter
            // column name will be 'children' - from isMarried
            private byte _children;
            @Column
            byte getChildren() { return _children; } 
            void setMarried(byte v) { _children = v; }

}

Aggregate properties

@Embedded

@Embedded - mark field of class with @Embeddable annotation to embed all its properties to parent entity.

Sample code for @Embedded and @Embeddable:

@Embeddable 
class EMName {
    @Column
    string firstName;
    @Column
    string lastName;
}

@Entity 
class EMUser {
    @Id @Generated
    @Column
    int id;
    
    @Embedded 
    EMName userName;
}

@OneToOne relation

Annotation Description
@OneToOne(propertyName) referenced object uses one-to-one relation, propertyName is referenced entity's property to join with current entity's primary key.
@OneToOne or @OneToOne() referenced object uses one-to-one relation, requires additional @JoinColumn annotation to specify foreign key column in current entity to join with current entity's primary key.
@JoinColumn(columnName) specify foreign key column name to join other entity's by its primary key - for @OneToOne relation.
@JoinColumn or @JoinColumn() foreign key column name will be autogenerated from referenced entity name, with _fk suffix.

One of sides of @OneToOne relation should have @JoinColumn annotation. Another (if has back reference) should use @OneToOne(propertyName) parameter to specify name of property with @JoinColumn annotation in first entity.

Type of field should be of class marked with @Entity annotation or template Lazy! with parameter of class marked with @Entity annotation.

Sample code:

@Entity("Person")
class Person {
    @Generated
    int id;
    
    @Column @NotNull
    string firstName;
    
    @Column @NotNull
    string lastName;
    
    @OneToOne @NotNull
    @JoinColumn("more_info_fk")
    MoreInfo moreInfo;
}

@Entity("More")
@Table("person_info")
class MoreInfo {
    @Generated
    int id;
    @Column 
    long flags;
    @OneToOne("moreInfo")
    Person person;
}

Non-lazy OneToOne relations will be loaded in single query using JOINs by default.

Same with Lazy! loading

@Entity("Person")
class Person {
    @Generated
    int id;
    
    @Column @NotNull
    string firstName;
    
    @Column @NotNull
    string lastName;
    
    @OneToOne @NotNull
    @JoinColumn("more_info_fk")
    Lazy!MoreInfo moreInfo;
}

@Entity("More")
@Table("person_info")
class MoreInfo {
    @Generated
    int id;
    @Column 
    long flags;
    @OneToOne("moreInfo")
    Lazy!Person person;
}

Lazy! relation of read entity will not be loaded until you will try to get its value.

If session used to load entity is closed, you will get exception.

@ManyToOne relation

Similar to OneToOne, but from other side of relation is non symmetric: back reference property will have @OneToMany type.

Type of field should be of class marked with @Entity annotation or template Lazy! with parameter of class marked with @Entity annotation.

Annotation Description
@ManyToOne or @ManyToOne() referenced object uses many-to-one relation, requires additional @JoinColumn annotation to specify foreign key column in current entity to join with current entity's primary key.
@JoinColumn(columnName) specify foreign key column name to join other entity's by its primary key - for @OneToOne relation.
@JoinColumn or @JoinColumn() foreign key column name will be autogenerated from referenced entity name, with _fk suffix.

Table which has @ManyToOne property will use foreign key column to join related table.

To specify backward relation on other side, you need to use @OneToMany annotation.

LazyCollection! relation of read entity will not be loaded until you will try to get its value.

If session used to load entity is closed, you will get exception.

See sample code in @OneToMany section.

@OneToMany relation

Opposite to @ManyToOne. Unlike @OneToMany, property of @ManyToOne type holds collection of entities instead of single entity. Requires paired @ManyToOne property in referenced entity.

Type of field should be of array of class marked with @Entity annotation or template LazyCollection! with parameter of class marked with @Entity annotation.

Annotation Description
@OneToMany(referencedProperty) referenced objects use one-to-many relation, requires property name from target entity which has specified foreign key column (@JoinColumn) and @ManyToOne to join with current entity's primary key.

Foreign key column in referenced table (defined using @ManyToOne and @JoinColumn) will be used to join with this entity table.

Sample code:

@Entity
@Table("users")
class User {
    
    @Generated
    long id;
    
    @Column
    string name;
    
    @ManyToOne
    @JoinColumn("customer_fk")
    Customer customer;
}

@Entity
@Table("customers")
class Customer {
    @Generated
    int id;
    @Column
    string name;
    
    @OneToMany("customer")
    User[] users;
}

@ManyToMany relation

ManyToMany relation property contains collection of other entities.

Like in OneToMany, type of field should be of array of class marked with @Entity annotation or template LazyCollection! with parameter of class marked with @Entity annotation.

Annotation Description
@ManyToMany(joinTableName, joinColumn1, joinColumn2) referenced objects use many-to-many relation via additional join table, requires additional parameters to specify join table to implement relation, and fk columns to referene this and related entities.
@ManyToMany or @ManyToMany() referenced objects use many-to-many relation via additional join table, will autogenerate join table name to implement relation, and fk column names to referene this and related entities.

Separate cross-reference DB table (Join Table) will be used to store relation in DB. It has two columns, one is foreign key reference to this entity, and another is foreign key of referenced entity.

Having back reference on in referenced entity is not required (one-sided relation is allowed).

LazyCollection! relation of read entity will not be loaded until you will try to get its value.

If session used to load entity is closed, you will get exception.

Sample code:

@Entity
@Table("users")
class User {
    
    @Generated
    long id;
    
    @Column
    string name;
    
    @ManyToMany
    LazyCollection!Role roles;
}

@Entity 
class Role {
    @Generated
    int id;

    @Column
    string name;

    @ManyToMany
    LazyCollection!User users;
}