Mapping simple properties
Declaring basic property mappings
Every non static non transient property (field or method) of an
entity bean is considered persistent, unless you annotate it as
@Transient. Not having an annotation for your
property is equivalent to the appropriate @Basic
annotation. The @Basic annotation allows you to
declare the fetching strategy for a property:
实体bean中所有的非static非transient的属性都可以被持久化,
除非你将其注解为@Transient。所有没有定义注解的属性等价于在其上面添加了@Basic注解。
通过 @Basic注解可以声明属性的存取策略:
public transient int counter; //transient property
private String firstname; //persistent property
@Transient
String getLengthInMeter() { ... } //transient property
String getName() {... } // persistent property
@Basic
int getLength() { ... } // persistent property
@Basic(fetch = FetchType.LAZY)
String getDetailedComment() { ... } // persistent property
@Temporal(TemporalType.TIME)
java.util.Date getDepartureTime() { ... } // persistent property
@Enumerated(STRING)
Starred getNote() { ... } //enum persisted as String in database
counter, a transient field, and
lengthInMeter, a method annotated as
@Transient, and will be ignored by the entity
manager. name, length, and
firstname 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. Usually you don't need to lazy simple
properties (not to be confused with lazy association fetching).
上面这个例子中,counter是一个transient的字段,
lengthInMeter的getter方法被注解为@Transient,
entity manager将忽略这些字段和属性。
而name,length,firstname
这几个属性则是被定义为可持久化和可抓取的(对于简单属性来说是默认的)。
detailedComment属性值则以延迟的方式从数据库中抓取,
对于实体中延迟类型的属性第一次访问都是以这种方式进行。
通常你不需要对简单属性设置延迟抓取(千万不要和延迟关联抓取混淆了)。
 | note
To enable property level lazy fetching, your classes have to
be instrumented: bytecode is added to the original one to enable
such feature, please refer to the Hibernate reference documentation.
If your classes are not instrumented, property level lazy loading is
silently ignored.
|
 | note
为了启用属性级的延迟抓取,你的类必须被自动构建:
字节码将被织入原始类中来实现延迟抓取功能,
详情参考Hibernate参考文档。如果不对类文件进行字节码构建,
那么属性级的延迟抓取将被默认忽略。
|
The recommended alternative is to use the projection capability
of EJB-QL or Criteria queries.
推荐的替代方案是使用EJB-QL或者Criteria查询的投影(projection)功能。
EJB3 support property mapping of all basic types supported by
Hibernate (all basic Java types , their respective wrappers and
serializable classes). Hibernate Annotations support out of the box
Enum type mapping either into a ordinal column (saving the enum
ordinal) or a string based column (saving the enum string
representation): the persistence representation, defaulted to ordinal,
can be overriden through the @Enumerated annotation
as shown in the note property example.
Hibernate支持EJB3中所有基本类型的属性映射(所有的Java基本类型,及其wrapper类和serializable类)。
Hibernate Annotations还支持将内置的enum类型映射到ordinal字段(保存了enum的ordinal值)
或一个字符类型的字段(保存enum的string值)。默认是保存enum的ordinal值,
但是可以通过修改@Enumerated注解的note属性来进行调整。
In core Java APIs, the temporal precision is not defined. When
dealing with temporal data you might want to describe the expected
precision in database. Temporal data can have DATE,
TIME, or TIMESTAMP precision (ie
the actual date, only the time, or both). Use the
@Temporal annotation to fine tune that.
在核心的Java API中并没有定义时间精度。
因此处理时间类型数据时需要定义将其存储在数据库中所预期的精度。
时间类型的数据有DATE, TIME, or TIMESTAMP三种精度(即单纯的日期,时间,或者两者兼备)。
可使用@Temporal注解来调整精度。
@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.
@Lob注解表示属性将被持久化为Blob或者Clob类型的字段,
具体取决于属性的类型,
java.sql.Clob,
Character[],
char[] and
java.lang.String这些类型的属性都被持久化为Clob字段,
而java.sql.Blob,
Byte[],
byte[] 和
serializable类型则被持久化为Blob字段。
@Lob
public String getFullText() {
return fullText;
}
@Lob
public byte[] getFullCode() {
return fullCode;
}
If the property type implements
java.io.Serializable and is not a basic type,
and if the property is not annotated with @Lob,
then the Hibernate serializable type is
used.
如果某个属性实现了java.io.Serializable同时也不是基本类型,
并且没有在该属性上使用@Lob注解,
那么Hibernate将使用自带的serializable类型。
Declaring column attributes
The column(s) used 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:
使用 @Column 注解可将属性映射到字段。
使用该注解来覆盖默认值(关于默认值请参考EJB3规范)。
在属性级使用该注解的方式如下:
not annotated at all
annotated with @Basic
annotated with @Version
annotated with @Lob
annotated with 睝Temporal
annotated with
@org.hibernate.annotations.CollectionOfElements
(for Hibernate only)
不进行注解
和 @Basic一起使用
和 @Version一起使用
和 @Lob一起使用
和 睝Temporal一起使用
和
@org.hibernate.annotations.CollectionOfElements一起使用
(只针对Hibernate )
@Entity
public class Flight implements Serializable {
...
@Column(updatable = false, name = "flight_name", nullable = false, length=50)
public String getName() { ... }
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).
在上面这个例子中,name属性映射到flight_name字段,
且不允许为空,长度为50,并且是不可更新的(也就是属性值是不变的).
This annotation can be applied to regular properties as well as
@Id or @Version
properties.
上面这些注解可以被应用到正规属性上例如@Id 或@Version属性。
@Column(
name="columnName";
boolean unique() default false;
boolean nullable() default true;
boolean insertable() default true;
boolean updatable() default true;
String columnDefinition() default "";
String table() default "";
int length() default 255;
int precision() default 0; // decimal precision
int scale() default 0; // decimal scale
name (optional): the column name
(default to the property name)
unique (optional): set a unique
constraint on this column or not (default false)
nullable (optional): set the column as
nullable (default false).
insertable (optional): whether or not
the column will be part of the insert statement (default
true)
updatable (optional): whether or not
the column will be part of the update statement (default
true)
columnDefinition (optional): override
the sql DDL fragment for this particular column (non
portable)
table (optional): define the targeted
table (default primary table)
length (optional):
column length (default 255)
precision
(optional): column decimal precision (default 0)
scale (optional):
column decimal scale if useful (default 0)
@Column(
name="columnName";
boolean unique() default false;
boolean nullable() default true;
boolean insertable() default true;
boolean updatable() default true;
String columnDefinition() default "";
String table() default "";
int length() default 255;
int precision() default 0; // decimal precision
int scale() default 0; // decimal scale
name 可选,字段名(默认值是属性名)
unique 可选,是否在该字段上设置唯一约束(默认值false)
nullable 可选,是否设置该字段的值可以为空(默认值false)
insertable 可选,该字段是否作为生成的insert语句中的一个字段(默认值true)
updatable 可选,该字段是否作为生成的update语句中的一个字段(默认值true)
columnDefinition 可选: 为这个特定字段覆盖sql DDL片段 (这可能导致无法在不同数据库间移植)
table 可选,定义对应的表(默认为主表)
length 可选,字段长度(默认值255)
precision
可选,字段数字精精度(默认值0)
scale 可选,如果字段数字刻度可用,在此设置(默认值0)
Embedded objects (aka components)
It is possible to declare an embedded component inside an entity
and even override its column mapping. Component classes 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 and @AttributeOverride
annotation in the associated property:
在实体中可以定义一个嵌入式组件(Component),
甚至覆盖该实体中原有的字段映射.
组件(Component)类必须在类一级定义@Embeddable注解.
在特定的实体的关联属性上使用@Embedded和
@AttributeOverride注解可以覆盖该属性对应的嵌入式对象的字段映射:
@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;
...
}
@Embeddable
public class Address implements Serializable {
String city;
Country nationality; //no overriding here
}
@Embeddable
public class Country implements Serializable {
private String iso2;
@Column(name="countryName") private String name;
public String getIso2() { return iso2; }
public void setIso2(String iso2) { this.iso2 = iso2; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
...
}
A embeddable object inherit the access type of its owning entity
(note that you can override that using the Hibernate specific
@AccessType annotations (see ).
嵌入式对象继承其所属实体中定义的访问类型
(注意:这可以通过使用Hibernate提供的@AccessType注解来覆盖原有值)(请参考 ).
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 by looking for
the @Embeddable annotation 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 a nested component of Address,
again using auto-detection by Hibernate and EJB3 defaults. Overriding
columns of embedded objects of embedded objects is currently not
supported in the EJB3 spec, however, Hibernate Annotations supports it
through dotted expressions.
在上面的例子中,实体bean Person 有两个组件属性,
分别是homeAddress和bornIn.
我们可以看到homeAddress 属性并没有注解.
但是Hibernate自动检测其对应的Address类中的@Embeddable注解,
并将其看作一个持久化组件.对于Country中已映射的属性,
则使用@Embedded和@AttributeOverride
注解来覆盖原来的字段映射值。
正如你所看到的, Address对象中还内嵌了Country对象,
这里和homeAddress一样使用了Hibernate和EJB3自动检测机制.
目前EJB3规范还不支持覆盖多层嵌套(即嵌入式对象中还包括其他嵌入式对象)的字段映射.
不过Hibernate通过在表达式中使用"."提供了对此特征的支持.
@Embedded
@AttributeOverrides( {
@AttributeOverride(name="city", column = @Column(name="fld_city") )
@AttributeOverride(name="nationality.iso2", column = @Column(name="nat_Iso2") ),
@AttributeOverride(name="nationality.name", column = @Column(name="nat_CountryName") )
//nationality columns in homeAddress are overridden
} )
Address homeAddress;
Hibernate Annotations supports one
more feature that is not explicitly supported by the EJB3
specification. You can annotate a embedded object with the
@MappedSuperclass annotation to make the superclass
properties persistent (see
@MappedSuperclass for
more informations).
@Embedded
@AttributeOverrides( {
@AttributeOverride(name="city", column = @Column(name="fld_city") )
@AttributeOverride(name="nationality.iso2", column = @Column(name="nat_Iso2") ),
@AttributeOverride(name="nationality.name", column = @Column(name="nat_CountryName") )
//nationality columns in homeAddress are overridden
} )
Address homeAddress;
Hibernate注解支持很多EJB3规范中没有明确定义的特性.
例如,可以在嵌入式对象上添加 @MappedSuperclass注解,
这样可以将其父类的属性持久(详情请查阅@MappedSuperclass).
You cannot use association annotations in an embeddable object
(ie no @*ToOne nor @*ToMany).
This is disallowed by the spec, and not yet supported in Hibernate
Annotations.
在嵌入式对象中不能使用关联注解(如@*ToOne和@*ToMany).
这在在EJB3规范中是禁止的,同样Hibernate Annotations也不支持.
If you want to have the same embeddable object type twice in the
same entity, the column name defaulting will not work: at least one of
the columns will have to be explicit. Hibernate goes beyond the EJB3
spec and allows you to enhance the defaulting mechanism through the
NamingStrategy.
DefaultComponentSafeNamingStrategy is a small
improvement over the default EJB3NamingStrategy that allows embedded
objects to be defaulted even if used twice in the same entity.
在同一个实体中使用两个同类型的嵌入对象,
其默认字段名是无效的:至少要对其中一个进行明确声明.
Hibernate在这方面走在了EJB3规范的前面,
Hibernate提供了NamingStrategy,
通过NamingStrategy可以对默认的机制进行扩展.
DefaultComponentSafeNamingStrategy
在默认的EJB3NamingStrategy上进行了小小的提升,
允许在同一实体中使用两个同类型的嵌入对象..
Non-annotated property defaults
If a property is not annotated, the following rules
apply:
如果某属性没有注解,该属性将遵守下面的规则:
If the property is of a single type, it is mapped as @Basic
Otherwise, if the type of the property is annotated as @Embeddable, it is mapped as @Embedded
Otherwise, if the type of the property is Serializable, it is mapped as @Basic in a column holding the object in its serialized version
Otherwise, if the type of the property is java.sql.Clob or java.sql.Blob, it is mapped as @Lob with the appropriate LobType
如果属性为单一类型,则映射为@Basic
否则,如果属性对应的类型定义了@Embeddable注解,则映射为@Embedded
否则,如果属性对应的类型实现了Serializable,
则属性被映射为@Basic并在一个字段中保存该对象的serialized版本
否则,如果该属性的类型为java.sql.Clob 或 java.sql.Blob,则作为@Lob并映射到适当的LobType。
二审后的建议
1。 counter, a transient field, and lengthInMeter, a method annotated as @Transient, and will be ignored by the entity manager.
上面这个例子中,counter是一个transient的属性,lengthInMeter的getter方法被注解为@Transient,entity manager将忽略这些属性。
修改原因: 我不知道'field'的标准翻译是不是'字段'。我觉得翻译成'属性'可能更合适一些。另外一个经常出现的词是'property', 我也翻译成'属性',不知道会不会造成混淆。我觉得一个基本的java类就是由属性(field or property)和方法(method)组成的。
2。name,length, and firstname properties are mapped persistent and eagerly fetched (the default for simple properties).
而name,length,firstname 这几个属性则是被定义为可持久化和可抓取的。
对于简单属性来说,默认的抓取方式是主动抓取(early fetched)。当一个实体Bean的实例被创建时,Hibernate会将这些属性的值从数据库中提取出来,存到Bean的属性里。
修改原因:原来的翻译没有译出 eagerly fetched, 我自己给了一个定义,不知道合不合适。
3。 The detailedCommentproperty value will be lazily fetched from the database once a lazy property of the entity is accessed for the first time.
与主动抓取相对应的是延迟抓取(lazily fetched)。如果一个属性的抓取方式是延迟抓取(比如上面例子中的detailedComment属性),Hibernate在创建一个实体Bean的实例时,不会主动将这个属性的值从数据库中读出。只有在该实体Bean的这个属性第一次被调用时,Hibernate才会去抓取。
修改原因:同上
4. To enable property level lazy fetching, your classes have to be instrumented: bytecode is added to the original one to enable such feature
为了对某些属性进行延迟抓取,你的类必须被自动构建(instrumented):字节码将被织入类文件中来实现延迟抓取功能,
修改原因: 原来的翻译("属性一级")有点拗口。另外,我也不太清楚 'instrumented'的标准翻译是不是'自动构建'。
5。 If your classes are not instrumented, property level lazy loading is silently ignored.
如果不对类文件进行字节码构建,那么属性级的延迟抓取将被Hibernate忽略。
修改原因:原来译文中的'默认'不太适当。英文版本也没有ignore by default这个意思。
6. EJB3 support property mapping of all basic types supported by Hibernate (all basic Java types , their respective wrappers and
serializable classes).
Hibernate和EJB3都支持基本类型的属性映射。在Hibernate中,这些基本类型包括所有的Java基本类型,及其wrapper类和serializable类。
修改原因:原来的译文好像是说Hibernate支持所有EJB3所支持的基本类型,这根英文的愿意正好相反。
7. The persistence representation, defaulted to ordinal, can be overriden through the @Enumerated annotation as shown in the note property example.
默认是保存enum的ordinal值,但是你可以通过 @Enumerated注解来进行调整(见上面例子中的'note'属性)。
修改原因:让句子更通顺一些。
8。 When dealing with temporal data you might want to describe the expected precision in database.
因此处理时间类型数据时,你需要定义将其存储在数据库中所预期的精度。
修改原因:让句子更通顺一些。
9。Temporal data can have DATE, TIME, or TIMESTAMP precision
在数据库中,时间类型的数据有DATE,TIME, 和TIMESTAMP三种精度
修改原因:让句子更通顺一些。'or'没有翻译。
10。java.sql.Clob, Character[],char[] and java.lang.Stringwill be persisted in a Clob.
java.sql.Clob, Character[],char[] 和 java.lang.String这些类型的属性都被持久化为Clob字段,
修改原因:'and'没有翻译。
11. The <literal>name</literal> property is mapped to the <literal>flight_name</literal> column, which is not nullable, has a length of 50 and is not updatable (making the property immutable).
在上面这个例子中,<literal>name</literal>属性映射到< literal>flight_name</literal>字段,
且不允许为空,长度为50,并且是不可更新的(也就是属性值是不变的)修改原因:让句子更通顺一些。
12. (optional): column decimal precision (default 0)
可选,字段数字精度(decimal precision)(默认值0)
修改原因:我不确信'数字精度' 是公认的翻译,所以把英文标注出来。
13. (optional): column decimal scale if useful (default 0)
可选,如果字段数字刻度(decimal scale)可用,在此设置(默认值0)
修改原因:同上。
14. Hibernate goes beyond the EJB3 spec and allows you to enhance the defaulting mechanism through the <classname>NamingStrategy</classname>.
Hibernate在这方面走在了EJB3规范的前面, 在使用Hibernate时, 通过<classname>NamingStrategy</classname>你可以对默认的机制进行扩展.
修改原因:让句子更通顺一些。
15。 <classname>DefaultComponentSafeNamingStrategy</classname> is a small improvement over the default EJB3NamingStrategy that allows embedded objects to be defaulted even if used twice in the same entity.
<classname>DefaultComponentSafeNamingStrategy</classname> 在默认的EJB3NamingStrategy上进行了小小的提升, 允许在同一实体中使用两个同类型的嵌入对象.
这一句翻译的不准确。难道EJB3NamingStrategy不允许在同一个实体中使用两个同类型的嵌入对象?我的理解是DefaultComponentSafeNamingStrategy允许其中一个嵌入对象使用默认的字段名,而其他的同类型嵌入对象必须明确声明。
16。
Hibernate Annotations support out of the box Enum type mapping either into a ordinal column (saving the enum
ordinal)
我觉得这句中的 'ordinal'要翻译出来,可我不知道相应的中文术语。