When using entity classes to generate the corresponding database tables, many times you will encounter this situation: in an entity class to reference another entity class, generally encountered in this case, we use @OneToOne
,, @OneToMany
@ManyToOne
and @ManyToMany
These 4 annotations more, but curiosity killed the cat, In addition to these four have no other usage, especially an entity class to be used in several different entity classes, and itself does not need to generate a database table independently , this is the @Embedded
@Embeddable
time, The following is divided into 4 classes to illustrate the case of referencing another entity class in one entity class, the specific database environment is MySQL 5.7.
The two entity classes used are as follows:
Address class
public class Address implements Serializable{ private static final long serialVersionUID = 8849870114128959929L; private String country; private String province; private String city; private String detail; //setter、getter}
Person class:
@Entitypublic class Person implements Serializable{ private static final long serialVersionUID = 8849870114127659929L; @Id @GeneratedValue private Long id; @Column(nullable = false) private String name; @Column(nullable = false) private Integer age; private Address address; //setter、getter}
1, two annotations all do not use
When both annotations are not used, then two entity classes are the same as above, and the resulting table structure is as follows:
The Address property field is mapped to a field of type Tinyblob, which is the data type used to store binary strings of up to 255 characters, and obviously we don't usually use them that way.
2. Use only
@Embeddable
We add annotations to the address entity class @Embeddable
and become the following class:
@Embeddablepublic class Address implements Serializable{ private static final long serialVersionUID = 8849870114128959929L; private String country; private String province; private String city; private String detail; //setter、getter}
The person entity class does not change, and the resulting database table structure is as follows:
You can see that the fields in address are mapped to database columns embedded in the person table, and the types and lengths of these fields also use the default values. If we set the related property of the column in the field in address, we will generate it according to the value we set, the following address class:
@Embeddablepublic class Address implements Serializable{ private static final long serialVersionUID = 8849870114128959929L; @Column(nullable = false) private String country; @Column(length = 30) private String province; @Column(unique = true) private String city; @Column(length = 50) private String detail; //setter、getter}
The resulting table structure is as follows:
The properties that we configured in address are all successfully mapped to the person table.
3. Use only
@Embedded
Here we are only used in person @Embedded
, as follows:
@Entitypublic class Person implements Serializable{ private static final long serialVersionUID = 8849870114127659929L; @Id @GeneratedValue private Long id; @Column(nullable = false) private String name; @Column(nullable = false) private Integer age; @Embedded private Address address; //setter、getter}
The Adddress class is the same as the beginning of the different Pojo classes, and the resulting table structure is as follows:
You can see that this table structure is the same as using annotations in address only @Embeddable
, and in the deep step experiment we add column attributes to address, but what happens when we don't use @Embeddable
annotations?
The address class is as follows:
public class Address implements Serializable{ private static final long serialVersionUID = 8849870114128959929L; @Column(nullable = false) private String country; @Column(length = 30) private String province; @Column(unique = true) private String city; @Column(length = 50) private String detail; //setter、getter}
The resulting data table structure is as follows:
So only use @Embedded
and only use the @Embeddable
resulting effect is the same.
4, two annotations all use
Since the use alone @Embedded
or only use @Embeddable
will have a role, then these two use the effect must be the same, we usually do so. So in this part we do not demonstrate the same effect as above, but instead say two in-depth topics.
4.1 Coverage
@Embeddable
Column properties of a field in a class
Here you will use another two annotations @AttributeOverrides
and @AttributeOverride
These two annotations are used to override the @Embeddable
properties of the fields in the class.
@AttributeOverrides
: Only the @AttributeOverride
type array is included;
@AttributeOverride
: Contains the properties of the @Embeddable
field name name and the new field in the class to overwrite @Column
;
Use the following:
The person class is as follows:
@Entitypublic class Person implements Serializable{ private static final long serialVersionUID = 8849870114127659929L; @Id @GeneratedValue private Long id; @Column(nullable = false) private String name; @Column(nullable = false) private Integer age; @Embedded @AttributeOverrides({@AttributeOverride(name="country", [email protected](name = "person_country", length = 25, nullable = false)), @AttributeOverride(name="city", column = @Column(name = "person_city", length = 15))}) private Address address; //setter、getter}
The address class is as follows:
@Embeddablepublic class Address implements Serializable{ private static final long serialVersionUID = 8849870114128959929L; @Column(nullable = false) private String country; @Column(length = 30) private String province; @Column(unique = true) private String city; @Column(length = 50) private String detail; //setter、getter}
The resulting data table is as follows:
We can see that our @AttributeOverrides
and @AttributeOverride
two annotations work.
4.2 Multi-layer embedded entity class properties
All of the above examples are embedded using a two-layer entity class, in fact, this entity class embedding mapping can be used multilayer, specific examples are as follows.
We have created a new class direction that shows the following directions:
@Embeddablepublic class Direction implements Serializable{ @Column(nullable = false) private Integer longitude; private Integer latitude;}
Address is as follows:
@Embeddablepublic class Address implements Serializable{ private static final long serialVersionUID = 8849870114128959929L; @Column(nullable = false) private String country; @Column(length = 30) private String province; @Column(unique = true) private String city; @Column(length = 50) private String detail; @Embedded private Direction direction;}
The person class is as follows:
@Entitypublic class Person implements Serializable{ private static final long serialVersionUID = 8849870114127659929L; @Id @GeneratedValue private Long id; @Column(nullable = false) private String name; @Column(nullable = false) private Integer age; @Embedded @AttributeOverrides({@AttributeOverride(name="direction.latitude", [email protected](name = "person_latitude")), @AttributeOverride(name="direction.longitude", column = @Column(name = "person_longitude"))}) private Address address;}
The resulting data table is as follows:
Here are a few points to note:
- When you define a property in direction in person, you need to use "." Connect all the related attributes together;
- The Longitude property is defined in direction,
not null
but because annotations are used, @AttributeOverride
although the null attribute is not defined, the default Nullable property is used, and the default is true;
Reproduced in: http://blog.csdn.net/lmy86263/article/details/52108130
@embedded and @embeddable annotations in hibernate