1. Overview
1.概述
In this tutorial, we’ll show how to use @AttributeOverride to change a column mapping. We’ll explain how to use it when extending or embedding an entity, and we’ll cover single and collection embedding.
在本教程中,我们将展示如何使用@AttributeOverride来改变一个列的映射。我们将解释在扩展或嵌入实体时如何使用它,我们还将介绍单一和集合嵌入。
2. @AttributeOverride‘s Attributes
2.@AttributeOverride的属性
The annotation contains two mandatory attributes:
该注释包含两个强制性的属性。
- name – field name of an included entity
- column – column definition which overrides the one defined in the original object
3. Use With @MappedSuperclass
3.与@MappedSuperclass一起使用
Let’s define a Vehicle class:
让我们定义一个车辆类:。
@MappedSuperclass
public class Vehicle {
@Id
@GeneratedValue
private Integer id;
private String identifier;
private Integer numberOfWheels;
// standard getters and setters
}
The @MappedSuperclass annotation indicates that it’s a base class for other entities.
@MappedSuperclass注解表明它是其他实体的基类。
Let’s next define class Car, which extends Vehicle. It demonstrates how to extend an entity and store a car’s information in a single table. Note that the annotation goes on the class:
接下来让我们定义Car类,它扩展了Vehicle. 它演示了如何扩展一个实体并在一个表中存储汽车的信息。请注意,注释在类上:
@Entity
@AttributeOverride(name = "identifier", column = @Column(name = "VIN"))
public class Car extends Vehicle {
private String model;
private String name;
// standard getters and setters
}
As a result, we have one table with all car details together with vehicle details. The thing is that for a car, we want to store an identifier in column VIN. We achieve it with @AttributeOverride. The annotation defines that field identifier is stored in the VIN column.
因此,我们有一个表,里面有所有的汽车细节和车辆细节。问题是,对于一辆车,我们想在列VIN中存储一个标识符。我们通过@AttributeOverride来实现。该注解定义了字段标识符被存储在VIN列中。
4. Use With an Embedded Class
4.与一个嵌入式班级一起使用
Let’s now add more details to our vehicle with two embeddable classes.
现在让我们用两个可嵌入的类为我们的车辆添加更多细节。
Let’s first define basic address information:
首先让我们定义一下基本的地址信息。
@Embeddable
public class Address {
private String name;
private String city;
// standard getters and setters
}
Let’s also create a class with car manufacturer information:
让我们也创建一个带有汽车制造商信息的类。
@Embeddable
public class Brand {
private String name;
private LocalDate foundationDate;
@Embedded
private Address address;
// standard getters and setters
}
The Brand class contains an embedded class with address details. We’ll use it to demonstrate how to use @AttributeOverride with multiple levels of embedding.
品牌类包含一个嵌入的类,其中有地址的详细信息。我们将用它来演示如何使用@AttributeOverride 与多层次的嵌入。
Let’s extend our Car with Brand details:
让我们扩展我们的汽车与品牌的细节。
@Entity
@AttributeOverride(name = "identifier", column = @Column(name = "VIN"))
public class Car extends Vehicle {
// existing fields
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "name", column = @Column(name = "BRAND_NAME", length = 5)),
@AttributeOverride(name = "address.name", column = @Column(name = "ADDRESS_NAME"))
})
private Brand brand;
// standard getters and setters
}
First of all, the @AttributeOverrides annotation allows us to modify more than one attribute. We’ve overridden the name column definition from the Brand class because the same column exists in the Car class. As a result, the brand name is stored in column BRAND_NAME.
首先,@AttributeOverrides注解允许我们修改一个以上的属性。我们从品牌类中覆盖了名称列的定义,因为同一列存在于汽车类中。因此,品牌名称被存储在列BRAND_NAME中。
Furthermore, we’ve defined column length to show that not only a column name can be overridden. Note that the column attribute overrides all values from the overridden class. To keep original values, all must be set in column attributes.
此外,我们定义了列的长度,以表明不仅仅是一个列名可以被覆盖。请注意,column属性覆盖了被覆盖类的所有值。为了保持原来的值,所有必须在column属性中设置。
In addition to that, the name column from the Address class has been mapped to ADDRESS_NAME. To override mappings at multiple levels of embedding, we use a dot “.” to specify a path to the overridden field.
除此之外,来自Address类的name列已经被映射到ADDRESS_NAME。为了在多级嵌入中覆盖映射,我们使用一个点”. “来指定覆盖字段的路径。
5. Embedded Collection
5.嵌入收集
Let’s play a little bit with this annotation and see how it works with a collection.
让我们来玩一下这个注释,看看它是如何在一个集合中工作的。
Let’s add a car’s owner details:
让我们添加一个车主的详细资料。
@Embeddable
public class Owner {
private String name;
private String surname;
// standard getters and setters
}
We want to have an owner together with an address, so let’s add a map of owners and their addresses:
我们希望所有者与地址一起,所以让我们添加一个所有者及其地址的地图:。
@Entity
@AttributeOverride(name = "identifier", column = @Column(name = "VIN"))
public class Car extends Vehicle {
// existing fields
@ElementCollection
@AttributeOverrides({
@AttributeOverride(name = "key.name", column = @Column(name = "OWNER_NAME")),
@AttributeOverride(name = "key.surname", column = @Column(name = "OWNER_SURNAME")),
@AttributeOverride(name = "value.name", column = @Column(name = "ADDRESS_NAME")),
})
Map<Owner, Address> owners;
// standard getters and setters
}
Thanks to the annotation, we can reuse the Address class. The key prefix indicates an override of a field from the Owner class. Furthermore, a value prefix points to the field from the Address class. For lists, no addition prefix is required.
由于注解的存在,我们可以重复使用Address类。key前缀表示对Owner类中一个字段的覆盖。此外,value前缀指向来自Address类的字段。对于列表,不需要添加前缀。
6. Conclusion
6.结论
That concludes this short article about the @AttibuteOverride annotation. We’ve seen how to use this annotation when extending or embedding an entity. After that, we’ve learned how to use it with a collection.
关于@AttibuteOverride注解的这篇短文到此结束。我们已经看到了在扩展或嵌入一个实体时如何使用这个注解。之后,我们学习了如何在一个集合中使用它。
As always, the source code of the example is available over on GitHub.
一如既往,该示例的源代码可在GitHub上获得over。