Understanding Java / Spring JPA annotations is crucial for developers working with Java and relational databases.
In the preceding lesson on JPA, you learned that JPA leverages annotations to supplant the need for SQL Data Definition Language (DDL).
This lesson will focus on exploring some of the most common JPA annotations. These annotations enable you to create database structure with Spring Data JPA, reducing or eliminating the need to write SQL manually.
Spring Data JPA Annotations
Think back to the last time you created a table in MySQL Workbench. Do you recall the sheer number of options available? Each table has settings. Each table has columns. Each column has preferences. Columns can be related to one another. You can choose behavior for deletions and insertions.
With so many options, it stands to reason that Spring JPA libraries need many annotations to provide the required functionality.
The rest of this lesson will summarize each annotation, focusing on the most common use cases. Each summary aims to provide clear insight into how and where to utilize the annotation in your JPA-driven development.
@Entity
Purpose: The @Entity Spring JPA annotation is used to mark a class as a "database entity", meaning the class is persistable. In other words, for every @Entity class, a corresponding database table should be created.
This is one of the most important and powerful annotations provided. Simply annotating a class with @Entity can prompt Spring/Hibernate to create a corresponding database table (if one does not already exist) at application startup, depending on your configuration and database settings.
Where: Class level
Parameters: None
Example:
@Entity
public class CodeWarrior{}
Explanation: Marking the class with @Entity signals JPA that it should be stored in a corresponding code_warrior database table. Depending on your configuration, that table can be created automatically.
@Table
Purpose: The @Table Spring JPA annotation is used alongside @Entity to get more fine-grained control of the database table. If you do not specify a @Table annotation, Spring will automatically choose the table specs. It becomes essential in cases where the desired table name doesn't naturally align with the class name.
Where: Class level
Parameters:
name(String) - specifies the name of the table in the database.schema(String) - the schema where the table should be created.
Example:
@Table(
name = "warriors"
)
@Entity
public class CodeWarrior{
private String name;
}
Explanation: Here, the @Table annotation causes the database table to be named warriors.
@Id
Purpose: @Id is used to specify the field which acts as a unique identifier (primary key) for the class.
Where: Field level
Parameters: None
Example:
@Entity
@Table(name="code_warriors")
public class CodeWarrior {
@Id
private Long id;
}
Explanation: The id field in the CodeWarrior class is specified as the primary key field/column for the code_warriors table.
Info: As you know, all database tables should have a column flagged as "primary key", which uniquely identifies each row in the table. Similarly, the POJOs that represent each table should always have an identifying field. Simply put - you always need an @Id annotated field!
@GeneratedValue
Purpose: @GeneratedValue instructs JPA to manage primary key generation, so you don't have to do it manually.
Where: Alongside the @Id annotation on the primary key field
Parameters:
strategy(GenerationType) - specifies how you want the key to be generated. The default value,GenerationType.AUTOlets JPA choose which strategy (TABLE,SEQUENCE, orIDENTITY) is best for your configuration.
Example:
@Entity
@Table(name="code_warriors")
public class CodeWarrior {
@Id
@GeneratedValue
private Long id;
}
Explanation: Here, the @GeneratedValue annotation specifies that the id field should be handled by JPA using a strategy of its choosing.
@Column
Purpose: The @Column JPA annotation, while optional, provides control over the database column definition. When omitted, JPA will default to using the field name as the column name and infer the column type based on the field type.
Where: Field level
Parameters:
name(String) - specifies the intended column name in the database.length(int) - specifies the maximum data length that can be saved in that field.nullable(boolean) - indicates whether this column can be null in the database.updatable(boolean) - whether to include or exclude this field in an update statement.unique(boolean) - are duplicate values are permitted in the column.precision(int) - how many decimal places to allow for numerical values.
Example:
@Entity
public class CodeWarrior {
@Id
@GeneratedValue
private Long id;
@Column(
name = "user_name",
length = 20,
nullable = false,
updatable = false
)
private String username;
}
Explanation: The username field is annotated with @Column. The parameters indicate that the corresponding database column should:
- Be named
user_name. - Have a maximum length of 20 characters.
- Not have null values.
- Is not updatable.
@Transient
Purpose: The @Transient JPA annotation marks a field as transient. In other words, there is no column in the database, and it will be entirely ignored when the class is being persisted. This can be particularly useful for fields that are necessary in the Java application but do not need to be stored in the database.
Where: Field level
Parameters: None
Example:
@Entity
@Table(name="code_warriors")
public class CodeWarrior {
@Id
@GeneratedValue
private Long id;
@Transient
private String sessionId;
}
Explanation: In this example, the sessionId field is annotated with @Transient, indicating the field should not be persisted in the database.
Summary: Spring JPA Annotations Guide
This lesson covered the most notable Spring Data JPA annotations used to define database tables from within Java objects. They are:
- @Entity - marks a class as persistable
- @Table - can be used to specify table names and the schema where the table should be located
- @Id - indicates the field shall act as the ID/primary key column for the table
- @GeneratedValue - used in conjunction with
@Idto have Spring generate the primary key for you - @Column - allows control over column settings such as name and length
- @Transient - indicates that the field is not to be persisted in the database and should be ignored by JPA
These annotations form the foundation of Spring Data JPA's ability to map Java objects to database tables, significantly easing database management compared to direct SQL and JDBC usage.
Once you get comfortable with these annotations, creating and managing tables will become a lot easier than using JDBC and SQL queries.