Hibernate 3.1 提供了多種附加的注解,這些注解可以與EJB3的實體混合/匹配使用。
他們被設計成EJB3注解的自然擴展。
To empower the EJB3 capabilities, hibernate provides specific
annotations that match hibernate features. The
org.hibernate.annotations package contains all
these annotations extensions.
為了強化EJB3的能力,Hibernate提供了與其自身特性相吻合的特殊注解。
org.hibernate.annotations包已包含了所有的這些注解擴展。
Entity
You can fine tune some of the actions done by Hibernate on
entities beyond what the EJB3 spec offers.
你可以在EJB3規范所能提供的能力之外,就Hibernate對實體所作的一些操作進行優化。
@org.hibernate.annotations.Entity adds
additional metadata that may be needed beyond what is defined in the
standard @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.EXPLICIT
persister: allow the overriding of the default persister implementation
optimisticLock: optimistic locking strategy (OptimisticLockType.VERSION, OptimisticLockType.NONE, OptimisticLockType.DIRTY or OptimisticLockType.ALL)
@org.hibernate.annotations.Entity
追加了可能需要的額外的元數據,
而這些元數據超出了標準@Entity 中所定義的元數據。
mutable: 此實體是否為可變的
dynamicInsert: 用動態SQL新增
dynamicUpdate: 用動態SQL更新
selectBeforeUpdate: 指明Hibernate從不運行SQL UPDATE除非能確定對象的確已被修改
polymorphism: (指出)實體多態是PolymorphismType.IMPLICIT(默認)還是PolymorphismType.EXPLICIT
persister: allow the overriding of the default persister implementation
允許對默認持久實現(persister implementation)的覆蓋
optimisticLock: 樂觀鎖策略(OptimisticLockType.VERSION, OptimisticLockType.NONE, OptimisticLockType.DIRTY 或 OptimisticLockType.ALL)
note
@javax.persistence.Entity is still mandatory,
@org.hibernate.annotations.Entity is not a replacement.
note
@javax.persistence.Entity仍是必選的(mandatory),
@org.hibernate.annotations.Entity不是取代品。
Here are some additional Hibernate annotation extensions
以下是一些附加的Hibernate注解擴展:
@org.hibernate.annotations.BatchSize allows you
to define the batch size when fetching instances of this entity ( eg.
@BatchSize(size=4) ). When loading a given entity,
Hibernate will then load all the uninitialized entities of the same type
in the persistence context up to the batch size.
@org.hibernate.annotations.BatchSize 允許你定義批量抓取該實體的實例數量(如:@BatchSize(size=4))。
當加載一特定的實體時,Hibernate將加載在持久上下文中未經初始化的同類型實體,直至批量數量(上限)。
@org.hibernate.annotations.Proxy defines the
laziness attributes of the entity. lazy (default to true) define whether
the class is lazy or not. proxyClassName is the interface used to
generate the proxy (default is the class itself).
@org.hibernate.annotations.Proxy
定義了實體的延遲屬性。Lazy(默認為true)定義了類是否為延遲(加載)。
proxyClassName是用來生成代理的接口(默認為該類本身)。
@org.hibernate.annotations.Where defines an
optional SQL WHERE clause used when instances of this class is
retrieved.
@org.hibernate.annotations.Where定義了當獲取類實例時所用的SQL WHERE子句(該SQL WHERE子句為可選)。
@org.hibernate.annotations.Check defines an
optional check constraints defined in the DDL statetement.
@org.hibernate.annotations.Check
定義了在DDL語句中定義的合法性檢查約束(該約束為可選)。
@OnDelete(action=OnDeleteAction.CASCADE) on
joined subclasses: use a SQL cascade delete on deletion instead of the
regular Hibernate mechanism.
@OnDelete(action=OnDeleteAction.CASCADE)
定義于被連接(joined)的子類:在刪除時使用SQL級連刪除,而非通常的Hibernate刪除機制。
@Table(name="tableName", indexes = {
@Index(name="index1", columnNames={"column1", "column2"} ) } )
creates the defined indexes on the columns of table tableName. This can
be applied on the primary table or any secondary table. The
@Tables annotation allows your to apply indexes on
different tables. This annotation is expected where
@javax.persistence.Table or
@javax.persistence.SecondaryTable(s) occurs.
@org.hibernate.annotations.Table is a complement, not
a replacement to @javax.persistence.Table
@Table(name="tableName", indexes = {
@Index(name="index1", columnNames={"column1", "column2"} ) } )在tableName表的字段上創建定義好的索引。該注解可以被應用于關鍵表或者是其他次要的表。
@Tables 注解允許你在不同的表上應用索引。
此注解預期在使用
@javax.persistence.Table或
@javax.persistence.SecondaryTable的地方中出現.
@org.hibernate.annotations.Table 是對
@javax.persistence.Table的補充而不是它的替代品。
programlisting
@Entity
@BatchSize(size=5)
@org.hibernate.annotations.Entity(
selectBeforeUpdate = true,
dynamicInsert = true, dynamicUpdate = true,
optimisticLock = OptimisticLockType.ALL,
polymorphism = PolymorphismType.EXPLICIT)
@Where(clause="1=1")
@org.hibernate.annotations.Table(name="Forest", indexes = { @Index(name="idx", columnNames = { "name", "length" } ) } )
public class Forest { ... }
programlisting
@Entity
@Inheritance(
strategy=InheritanceType.JOINED
)
public class Vegetable { ... }
@Entity
@OnDelete(action=OnDeleteAction.CASCADE)
public class Carrot extends Vegetable { ... }
Identifier
@org.hibernate.annotations.GenericGenerator
allows you to define an Hibernate specific id
generator.
@org.hibernate.annotations.GenericGenerator
允許你定義一個Hibernate特定的id生成器。
programlisting
@Id @GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid", strategy = "uuid")
public String getId() {
@Id @GeneratedValue(generator="hibseq")
@GenericGenerator(name="hibseq", strategy = "seqhilo",
parameters = {
@Parameter(name="max_lo", value = "5"),
@Parameter(name="sequence", value="heybabyhey")
}
)
public Integer getId() {
strategy is the short name of an Hibernate3
generator strategy or the fully qualified class name of an
IdentifierGenerator implementation. You can add
some parameters through the parameters
attribute
strategy可以是Hibernate3生成器策略的簡稱,或者是一個IdentifierGenerator實現的(帶包路徑的)全限定類名。
你可以通過parameters屬性增加一些參數。
Property
Access type
The access type is guessed from the position of
@Id or @EmbeddedId in the entity
hierarchy. Sub-entities, embedded objects and mapped superclass
inherit the access type from the root entity.
訪問類型是根據@Id或@EmbeddedId在實體繼承層次中所處的位置推演而得的。子實體(Sub-entities),內嵌對象和被映射的父類均從根實體(root entity)繼承訪問類型。
In Hibernate, you can override the access type to:
在Hibernate中,你可以把訪問類型覆蓋成:
use a custom access type strategy
fine tune the access type at the class level or at the
property level
使用定制的訪問類型策略
優化類級別或屬性級別的訪問類型
An @AccessType annotation has been introduced to support this
behavior. You can define the access type on
為支持這種行為,Hibernate引入了@AccessType注解。你可以對以下元素定義訪問類型:
an entity
a superclass
an embeddable object
a property
實體
父類
可內嵌的對象
屬性
The access type is overriden for the annotated element, if
overriden on a class, all the properties of the given class inherit
the access type. For root entities, the access type is considered to
be the default one for the whole hierarchy (overridable at class or
property level).
被注解元素的訪問類型會被覆蓋,若覆蓋是在類級別上,則所有的屬性繼承訪問類型。
對于根實體,其訪問類型會被認為是整個繼承層次中的缺省設置(可在類或屬性一級覆蓋)。
If the access type is marked as "property", the getters are
scanned for annotations, if the access type is marked as "field", the
fields are scanned for annotations. Otherwise the elements marked with
@Id or @embeddedId are scanned.
若訪問類型被標以"property",則Hibernate會掃描getter方法的注解,若訪問類型被標以"field",則掃描字段的注解。否則,掃描標為@Id或@embeddedId的元素。
You can override an access type for a property, but the element
to annotate will not be influenced: for example an entity having
access type field, can annotate a field with
@AccessType("property"), the access type will then
be property for this attribute, the the annotations still have to be
carried on the field.
你可以覆蓋某個屬性(property)的訪問類型,但是受注解的元素將不受影響:例如一個具有field訪問類型的實體,(我們)可以將某個字段標注為 @AccessType("property"),則該字段的訪問類型隨之將成為property,但是其他字段上依然需要攜帶注解。
If a superclass or an embeddable object is not annotated, the
root entity access type is used (even if an access type has been
define on an intermediate superclass or embeddable object). The
russian doll principle does not apply.
若父類或可內嵌的對象沒有被注解,則使用根實體的訪問類型(即使已經在非直系父類或可內嵌對象上定義了訪問類型)。此時俄羅斯套娃(Russian doll)原理就不再適用。(譯注:俄羅斯套娃(матрёшка或 матрешка)是俄羅斯特產木制玩具,一般由多個一樣圖案的空心木娃娃一個套一個組成,最多可達十多個,通常為圓柱形,底部平坦可以直立。)
programlisting
@Entity
public class Person implements Serializable {
@Id @GeneratedValue //access type field
Integer id;
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "iso2", column = @Column(name = "bornIso2")),
@AttributeOverride(name = "name", column = @Column(name = "bornCountryName"))
})
Country bornIn;
}
@Embeddable
@AccessType("property") //override access type for all properties in Country
public class Country implements Serializable {
private String iso2;
private String name;
public String getIso2() {
return iso2;
}
public void setIso2(String iso2) {
this.iso2 = iso2;
}
@Column(name = "countryName")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Formula
Sometimes, you want the Database to do some computation for you
rather than in the JVM, you might also create some kind of virtual
column. You can use a SQL fragment (aka formula) instead of mapping a
property into a column. This kind of property is read only (its value
is calculated by your formula fragment).
Sometimes, you want the Database to do some computation for you
rather than in the JVM, you might also create some kind of virtual
column. You can use a SQL fragment (aka formula) instead of mapping a
property into a column. This kind of property is read only (its value
is calculated by your formula fragment).
有時候,你想讓數據庫,而非JVM,來替你完成一些計算,也可能想創建某種虛擬字段(譯注:即數據庫視圖)。你可以使用一段SQL(亦稱為公式),而不是將屬性映射到(物理)字段。 這種屬性是只讀的(屬性值由公求得)。
programlisting
@Formula("obj_length * obj_height * obj_width")
public long getObjectVolume()
The SQL fragment can be as complex as you want avec even include
subselects.
SQL片段可以是任意復雜的,甚至可包含子查詢。
Type
@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.Type
覆蓋了Hibernate所用的默認類型:這通常不是必須的,因為類型可以由Hibernate正確推得。
關于Hibernate類型的詳細信息,請參考Hibernate使用手冊。
@org.hibernate.annotations.TypeDef and
@org.hibernate.annotations.TypeDefs allows you to
declare type definitions. 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.
@org.hibernate.annotations.TypeDef 和
@org.hibernate.annotations.TypeDefs允許你來聲明類型定義。
這些注解被置于類或包一級。注意,對session factory來說,
這些定義將是全局的(即使定義于類一級),并且類型定義必須先于任何使用。
programlisting
@TypeDefs(
{
@TypeDef(
name="caster",
typeClass = CasterStringType.class,
parameters = {
@Parameter(name="cast", value="lower")
}
)
}
)
package org.hibernate.test.annotations.entity;
...
public class Forest {
@Type(type="caster")
public String getSmallText() {
...
}
When using composite user type, you will have to express column
definitions. The @Columns has been introduced for
that purpose.
當使用組合的用戶自定義類型時,你必須自己來表達字段定義。
@Columns就是為了此目的而引入的。
programlisting
@Type(type="org.hibernate.test.annotations.entity.MonetaryAmountUserType")
@Columns(columns = {
@Column(name="r_amount"),
@Column(name="r_currency")
})
public MonetaryAmount getAmount() {
return amount;
}
public class MonetaryAmount implements Serializable {
private BigDecimal amount;
private Currency currency;
...
}
Index
You can define an index on a particular column using the
@Index annotation on a one column property, the
columnNames attribute will then be ignored
通過在字段屬性(property)上使用@Index注解,
可以在特定字段上定義索引,columnNames屬性(attribute)將隨之被忽略。
programlisting
@Column(secondaryTable="Cat1")
@Index(name="story1index")
public String getStoryPart1() {
return storyPart1;
}
Inheritance
SINGLE_TABLE is a very powerful strategy but sometimes, and
especially for legacy systems, you cannot add an additional
discriminator column. For that purpose Hibernate has introduced the
notion of discriminator formula:
@DiscriminatorFormula is a replacement of
@DiscriminatorColumn and use a SQL fragment as a
formula for discriminator resolution (no need to have a dedicated
column).
SINGLE_TABLE 是個功能強大的策略,但有時,特別對遺留系統而言,
是無法加入一個額外的識別符字段(discriminator column)。
由此,Hibernate引入了識別符公式(discriminator formula)的概念:
@DiscriminatorFormula是@DiscriminatorColumn的替代品,
它使用SQL片段作為識別符解決方案的公式( 不需要有一個專門的字段)。
programlisting
@Entity
@DiscriminatorForumla("case when forest_type is null then 0 else forest_type end")
public class Forest { ... }
Association related annotations
By default, when Hibernate cannot resolve the association because
the expected associated element is not in database (wrong id on the
association column), an exception is raised by Hibernate. This might be
inconvenient for lecacy and badly maintained schemas. You can ask
Hibernate to ignore such elements instead of raising an exception using
the @NotFound annotation. This annotation can be used
on a @OneToOne (with FK),
@ManyToOne, @OneToMany or
@ManyToMany association.
默認情況下,當預期的被關聯元素不在數據庫中(關乎關聯字段的id錯誤),致使Hiberante無法解決關聯性問題時,Hibernate就會拋出異常。
這對遺留schema和歷經拙劣維護的schema而言,這或有許多不便。
此時,你可用 @NotFound 注解讓Hibernate略過這樣的元素而不是拋出異常。
該注解可用于 @OneToOne (有外鍵)、 @ManyToOne 、
@OneToMany 或 @ManyToMany 關聯。
programlisting
@Entity
public class Child {
...
@ManyToOne
@NotFound(action=NotFoundAction.IGNORE)
public Parent getParent() { ... }
...
}
Collection related annotations
Parameter annotations
It is possible to set
the batch size for collections using @BatchSize
the where clause, using @Where
the check clause, using @Check
the SQL order by clause, using @OrderBy
the delete cascade strategy through @OnDelete(action=OnDeleteAction.CASCADE)
以下是可能的設置方式
用@BatchSizebatch設置集合的batch大小
用@Where注解設置Where子句
用注解@Check來設置check子句
用注解@OrderBy來設置SQL的order by子句
利用@OnDelete(action=OnDeleteAction.CASCADE) 注解設置級連刪除策略
You can also declare a sort comparator. Use the
@Sort annotation. Expressing the comparator type
you want between unsorted, natural or custom comparator. If you want
to use your own comparator implementation, you'll also have to express
the implementation class using the comparator
attribute.
你也可以利用@Sort注解定義一個排序比較器(sort comparator),表明希望的比較器類型,無序、自然順序或自定義排序,三者擇一。若你想用你自己實現的comparator,
你還需要利用comparator屬性(attribute)指明實現類。
programlisting
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name="CUST_ID")
@Sort(type = SortType.COMPARATOR, comparator = TicketComparator.class)
@Where(clause="1=1")
@OnDelete(action=OnDeleteAction.CASCADE)
public SortedSet<Ticket> getTickets() {
return tickets;
}
他們被設計成EJB3注解的自然擴展。
To empower the EJB3 capabilities, hibernate provides specific
annotations that match hibernate features. The
org.hibernate.annotations package contains all
these annotations extensions.
為了強化EJB3的能力,Hibernate提供了與其自身特性相吻合的特殊注解。
org.hibernate.annotations包已包含了所有的這些注解擴展。
Entity
You can fine tune some of the actions done by Hibernate on
entities beyond what the EJB3 spec offers.
你可以在EJB3規范所能提供的能力之外,就Hibernate對實體所作的一些操作進行優化。
@org.hibernate.annotations.Entity adds
additional metadata that may be needed beyond what is defined in the
standard @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.EXPLICIT
persister: allow the overriding of the default persister implementation
optimisticLock: optimistic locking strategy (OptimisticLockType.VERSION, OptimisticLockType.NONE, OptimisticLockType.DIRTY or OptimisticLockType.ALL)
@org.hibernate.annotations.Entity
追加了可能需要的額外的元數據,
而這些元數據超出了標準@Entity 中所定義的元數據。
mutable: 此實體是否為可變的
dynamicInsert: 用動態SQL新增
dynamicUpdate: 用動態SQL更新
selectBeforeUpdate: 指明Hibernate從不運行SQL UPDATE除非能確定對象的確已被修改
polymorphism: (指出)實體多態是PolymorphismType.IMPLICIT(默認)還是PolymorphismType.EXPLICIT
persister: allow the overriding of the default persister implementation
允許對默認持久實現(persister implementation)的覆蓋
optimisticLock: 樂觀鎖策略(OptimisticLockType.VERSION, OptimisticLockType.NONE, OptimisticLockType.DIRTY 或 OptimisticLockType.ALL)
note
@javax.persistence.Entity is still mandatory,
@org.hibernate.annotations.Entity is not a replacement.
note
@javax.persistence.Entity仍是必選的(mandatory),
@org.hibernate.annotations.Entity不是取代品。
Here are some additional Hibernate annotation extensions
以下是一些附加的Hibernate注解擴展:
@org.hibernate.annotations.BatchSize allows you
to define the batch size when fetching instances of this entity ( eg.
@BatchSize(size=4) ). When loading a given entity,
Hibernate will then load all the uninitialized entities of the same type
in the persistence context up to the batch size.
@org.hibernate.annotations.BatchSize 允許你定義批量抓取該實體的實例數量(如:@BatchSize(size=4))。
當加載一特定的實體時,Hibernate將加載在持久上下文中未經初始化的同類型實體,直至批量數量(上限)。
@org.hibernate.annotations.Proxy defines the
laziness attributes of the entity. lazy (default to true) define whether
the class is lazy or not. proxyClassName is the interface used to
generate the proxy (default is the class itself).
@org.hibernate.annotations.Proxy
定義了實體的延遲屬性。Lazy(默認為true)定義了類是否為延遲(加載)。
proxyClassName是用來生成代理的接口(默認為該類本身)。
@org.hibernate.annotations.Where defines an
optional SQL WHERE clause used when instances of this class is
retrieved.
@org.hibernate.annotations.Where定義了當獲取類實例時所用的SQL WHERE子句(該SQL WHERE子句為可選)。
@org.hibernate.annotations.Check defines an
optional check constraints defined in the DDL statetement.
@org.hibernate.annotations.Check
定義了在DDL語句中定義的合法性檢查約束(該約束為可選)。
@OnDelete(action=OnDeleteAction.CASCADE) on
joined subclasses: use a SQL cascade delete on deletion instead of the
regular Hibernate mechanism.
@OnDelete(action=OnDeleteAction.CASCADE)
定義于被連接(joined)的子類:在刪除時使用SQL級連刪除,而非通常的Hibernate刪除機制。
@Table(name="tableName", indexes = {
@Index(name="index1", columnNames={"column1", "column2"} ) } )
creates the defined indexes on the columns of table tableName. This can
be applied on the primary table or any secondary table. The
@Tables annotation allows your to apply indexes on
different tables. This annotation is expected where
@javax.persistence.Table or
@javax.persistence.SecondaryTable(s) occurs.
@org.hibernate.annotations.Table is a complement, not
a replacement to @javax.persistence.Table
@Table(name="tableName", indexes = {
@Index(name="index1", columnNames={"column1", "column2"} ) } )在tableName表的字段上創建定義好的索引。該注解可以被應用于關鍵表或者是其他次要的表。
@Tables 注解允許你在不同的表上應用索引。
此注解預期在使用
@javax.persistence.Table或
@javax.persistence.SecondaryTable的地方中出現.
@org.hibernate.annotations.Table 是對
@javax.persistence.Table的補充而不是它的替代品。
programlisting
@Entity
@BatchSize(size=5)
@org.hibernate.annotations.Entity(
selectBeforeUpdate = true,
dynamicInsert = true, dynamicUpdate = true,
optimisticLock = OptimisticLockType.ALL,
polymorphism = PolymorphismType.EXPLICIT)
@Where(clause="1=1")
@org.hibernate.annotations.Table(name="Forest", indexes = { @Index(name="idx", columnNames = { "name", "length" } ) } )
public class Forest { ... }
programlisting
@Entity
@Inheritance(
strategy=InheritanceType.JOINED
)
public class Vegetable { ... }
@Entity
@OnDelete(action=OnDeleteAction.CASCADE)
public class Carrot extends Vegetable { ... }
Identifier
@org.hibernate.annotations.GenericGenerator
allows you to define an Hibernate specific id
generator.
@org.hibernate.annotations.GenericGenerator
允許你定義一個Hibernate特定的id生成器。
programlisting
@Id @GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid", strategy = "uuid")
public String getId() {
@Id @GeneratedValue(generator="hibseq")
@GenericGenerator(name="hibseq", strategy = "seqhilo",
parameters = {
@Parameter(name="max_lo", value = "5"),
@Parameter(name="sequence", value="heybabyhey")
}
)
public Integer getId() {
strategy is the short name of an Hibernate3
generator strategy or the fully qualified class name of an
IdentifierGenerator implementation. You can add
some parameters through the parameters
attribute
strategy可以是Hibernate3生成器策略的簡稱,或者是一個IdentifierGenerator實現的(帶包路徑的)全限定類名。
你可以通過parameters屬性增加一些參數。
Property
Access type
The access type is guessed from the position of
@Id or @EmbeddedId in the entity
hierarchy. Sub-entities, embedded objects and mapped superclass
inherit the access type from the root entity.
訪問類型是根據@Id或@EmbeddedId在實體繼承層次中所處的位置推演而得的。子實體(Sub-entities),內嵌對象和被映射的父類均從根實體(root entity)繼承訪問類型。
In Hibernate, you can override the access type to:
在Hibernate中,你可以把訪問類型覆蓋成:
use a custom access type strategy
fine tune the access type at the class level or at the
property level
使用定制的訪問類型策略
優化類級別或屬性級別的訪問類型
An @AccessType annotation has been introduced to support this
behavior. You can define the access type on
為支持這種行為,Hibernate引入了@AccessType注解。你可以對以下元素定義訪問類型:
an entity
a superclass
an embeddable object
a property
實體
父類
可內嵌的對象
屬性
The access type is overriden for the annotated element, if
overriden on a class, all the properties of the given class inherit
the access type. For root entities, the access type is considered to
be the default one for the whole hierarchy (overridable at class or
property level).
被注解元素的訪問類型會被覆蓋,若覆蓋是在類級別上,則所有的屬性繼承訪問類型。
對于根實體,其訪問類型會被認為是整個繼承層次中的缺省設置(可在類或屬性一級覆蓋)。
If the access type is marked as "property", the getters are
scanned for annotations, if the access type is marked as "field", the
fields are scanned for annotations. Otherwise the elements marked with
@Id or @embeddedId are scanned.
若訪問類型被標以"property",則Hibernate會掃描getter方法的注解,若訪問類型被標以"field",則掃描字段的注解。否則,掃描標為@Id或@embeddedId的元素。
You can override an access type for a property, but the element
to annotate will not be influenced: for example an entity having
access type field, can annotate a field with
@AccessType("property"), the access type will then
be property for this attribute, the the annotations still have to be
carried on the field.
你可以覆蓋某個屬性(property)的訪問類型,但是受注解的元素將不受影響:例如一個具有field訪問類型的實體,(我們)可以將某個字段標注為 @AccessType("property"),則該字段的訪問類型隨之將成為property,但是其他字段上依然需要攜帶注解。
If a superclass or an embeddable object is not annotated, the
root entity access type is used (even if an access type has been
define on an intermediate superclass or embeddable object). The
russian doll principle does not apply.
若父類或可內嵌的對象沒有被注解,則使用根實體的訪問類型(即使已經在非直系父類或可內嵌對象上定義了訪問類型)。此時俄羅斯套娃(Russian doll)原理就不再適用。(譯注:俄羅斯套娃(матрёшка或 матрешка)是俄羅斯特產木制玩具,一般由多個一樣圖案的空心木娃娃一個套一個組成,最多可達十多個,通常為圓柱形,底部平坦可以直立。)
programlisting
@Entity
public class Person implements Serializable {
@Id @GeneratedValue //access type field
Integer id;
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "iso2", column = @Column(name = "bornIso2")),
@AttributeOverride(name = "name", column = @Column(name = "bornCountryName"))
})
Country bornIn;
}
@Embeddable
@AccessType("property") //override access type for all properties in Country
public class Country implements Serializable {
private String iso2;
private String name;
public String getIso2() {
return iso2;
}
public void setIso2(String iso2) {
this.iso2 = iso2;
}
@Column(name = "countryName")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Formula
Sometimes, you want the Database to do some computation for you
rather than in the JVM, you might also create some kind of virtual
column. You can use a SQL fragment (aka formula) instead of mapping a
property into a column. This kind of property is read only (its value
is calculated by your formula fragment).
Sometimes, you want the Database to do some computation for you
rather than in the JVM, you might also create some kind of virtual
column. You can use a SQL fragment (aka formula) instead of mapping a
property into a column. This kind of property is read only (its value
is calculated by your formula fragment).
有時候,你想讓數據庫,而非JVM,來替你完成一些計算,也可能想創建某種虛擬字段(譯注:即數據庫視圖)。你可以使用一段SQL(亦稱為公式),而不是將屬性映射到(物理)字段。 這種屬性是只讀的(屬性值由公求得)。
programlisting
@Formula("obj_length * obj_height * obj_width")
public long getObjectVolume()
The SQL fragment can be as complex as you want avec even include
subselects.
SQL片段可以是任意復雜的,甚至可包含子查詢。
Type
@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.Type
覆蓋了Hibernate所用的默認類型:這通常不是必須的,因為類型可以由Hibernate正確推得。
關于Hibernate類型的詳細信息,請參考Hibernate使用手冊。
@org.hibernate.annotations.TypeDef and
@org.hibernate.annotations.TypeDefs allows you to
declare type definitions. 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.
@org.hibernate.annotations.TypeDef 和
@org.hibernate.annotations.TypeDefs允許你來聲明類型定義。
這些注解被置于類或包一級。注意,對session factory來說,
這些定義將是全局的(即使定義于類一級),并且類型定義必須先于任何使用。
programlisting
@TypeDefs(
{
@TypeDef(
name="caster",
typeClass = CasterStringType.class,
parameters = {
@Parameter(name="cast", value="lower")
}
)
}
)
package org.hibernate.test.annotations.entity;
...
public class Forest {
@Type(type="caster")
public String getSmallText() {
...
}
When using composite user type, you will have to express column
definitions. The @Columns has been introduced for
that purpose.
當使用組合的用戶自定義類型時,你必須自己來表達字段定義。
@Columns就是為了此目的而引入的。
programlisting
@Type(type="org.hibernate.test.annotations.entity.MonetaryAmountUserType")
@Columns(columns = {
@Column(name="r_amount"),
@Column(name="r_currency")
})
public MonetaryAmount getAmount() {
return amount;
}
public class MonetaryAmount implements Serializable {
private BigDecimal amount;
private Currency currency;
...
}
Index
You can define an index on a particular column using the
@Index annotation on a one column property, the
columnNames attribute will then be ignored
通過在字段屬性(property)上使用@Index注解,
可以在特定字段上定義索引,columnNames屬性(attribute)將隨之被忽略。
programlisting
@Column(secondaryTable="Cat1")
@Index(name="story1index")
public String getStoryPart1() {
return storyPart1;
}
Inheritance
SINGLE_TABLE is a very powerful strategy but sometimes, and
especially for legacy systems, you cannot add an additional
discriminator column. For that purpose Hibernate has introduced the
notion of discriminator formula:
@DiscriminatorFormula is a replacement of
@DiscriminatorColumn and use a SQL fragment as a
formula for discriminator resolution (no need to have a dedicated
column).
SINGLE_TABLE 是個功能強大的策略,但有時,特別對遺留系統而言,
是無法加入一個額外的識別符字段(discriminator column)。
由此,Hibernate引入了識別符公式(discriminator formula)的概念:
@DiscriminatorFormula是@DiscriminatorColumn的替代品,
它使用SQL片段作為識別符解決方案的公式( 不需要有一個專門的字段)。
programlisting
@Entity
@DiscriminatorForumla("case when forest_type is null then 0 else forest_type end")
public class Forest { ... }
Association related annotations
By default, when Hibernate cannot resolve the association because
the expected associated element is not in database (wrong id on the
association column), an exception is raised by Hibernate. This might be
inconvenient for lecacy and badly maintained schemas. You can ask
Hibernate to ignore such elements instead of raising an exception using
the @NotFound annotation. This annotation can be used
on a @OneToOne (with FK),
@ManyToOne, @OneToMany or
@ManyToMany association.
默認情況下,當預期的被關聯元素不在數據庫中(關乎關聯字段的id錯誤),致使Hiberante無法解決關聯性問題時,Hibernate就會拋出異常。
這對遺留schema和歷經拙劣維護的schema而言,這或有許多不便。
此時,你可用 @NotFound 注解讓Hibernate略過這樣的元素而不是拋出異常。
該注解可用于 @OneToOne (有外鍵)、 @ManyToOne 、
@OneToMany 或 @ManyToMany 關聯。
programlisting
@Entity
public class Child {
...
@ManyToOne
@NotFound(action=NotFoundAction.IGNORE)
public Parent getParent() { ... }
...
}
Collection related annotations
Parameter annotations
It is possible to set
the batch size for collections using @BatchSize
the where clause, using @Where
the check clause, using @Check
the SQL order by clause, using @OrderBy
the delete cascade strategy through @OnDelete(action=OnDeleteAction.CASCADE)
以下是可能的設置方式
用@BatchSizebatch設置集合的batch大小
用@Where注解設置Where子句
用注解@Check來設置check子句
用注解@OrderBy來設置SQL的order by子句
利用@OnDelete(action=OnDeleteAction.CASCADE) 注解設置級連刪除策略
You can also declare a sort comparator. Use the
@Sort annotation. Expressing the comparator type
you want between unsorted, natural or custom comparator. If you want
to use your own comparator implementation, you'll also have to express
the implementation class using the comparator
attribute.
你也可以利用@Sort注解定義一個排序比較器(sort comparator),表明希望的比較器類型,無序、自然順序或自定義排序,三者擇一。若你想用你自己實現的comparator,
你還需要利用comparator屬性(attribute)指明實現類。
programlisting
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name="CUST_ID")
@Sort(type = SortType.COMPARATOR, comparator = TicketComparator.class)
@Where(clause="1=1")
@OnDelete(action=OnDeleteAction.CASCADE)
public SortedSet<Ticket> getTickets() {
return tickets;
}