When we develop our applications to interact with some data in storage, mapping it to a POJO is usually the way to translate our data into something usable in code. This post will cover the different annotations that can be added to a Java POJO to let Spring Boot, combined with Spring Data JPA, do its magic when getting a record from a database.
@Entity
The first thing we need to consider when we create our Java object is the Entity annotation. This lets Spring Boot know that it is a Java object that will directly relate to a database table and it should be added to the class as a whole. In the example below, we will have a database table that contains all of our User data, so the Java Object we create to map a user to it when retrieving a record from the database, will look as follows:
package uk.co.austellapp.entity-example.domain;
import javax.persistence.*;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String username;
private String password;
private String email;
}
We have created a basic User class with a few basic properties that a User might expect to have. The important thing to note in this example is the use of the “Entity” annotation, this lets Spring Boot know that it should relate to a Database table called “User”. There are a few extra bits we can add to this annotation:
@Entity
@Table(name = "User_Data")
public class User {
}
Adding the extra @Table annotation means we can configure the Entity more specifically. In the example above we have added an extra property to the @Table annotation which specifies that the Database table our Entity will map to is called “User_Data”. This might be useful for a couple of reasons:
- You have a database already created that you are integrating with and you may with to use the data differently. In this case, the original table name may not be approprtiate for what we want to achieve within the code base making it confusing for any future development.
- You have a database already created that may have a different naming standard to your code base.
@Id
The ID annotation applies to exactly as it says, The ID of the entity you’re creating. This will map to the primary key of the database table. It’s usually a numeric incremented value but can also be a unique reference such as a UUID or a unique string value such as an email.
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String username;
private String password;
private String email;
}
Using the example above, we can see that the User table will have a Primary Key, the “id” field, without the annotation, Spring Boot would not be aware of the object’s ID. You may notice that we’ve also added the @GeneratedValue annotation. This makes Spring Boot aware that it should automatically generate a new ID for each new record without the developer having to assign one.
@Column
Anything that hasn’t been annotated otherwise in the User class will just be treated as a column. However, we can explicitly define some extra properties for each field if we want to.
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column
private String username;
private String password;
private String email;
}
Here we have added the Column annotation to our username field, on its own. Due to its default values, this will not change any behaviour and is redundant. However, we can fine-tune our column field to do numerous things:
@Column(name = "user_name")
This will make Spring Boot aware that our username column within our database is actually called “user_name”.
@Column(unique = true)
This places a restriction on the column and will make Spring Boot aware that it should be unique. Whenever a record is attempted to be stored with a none unique value, i.e. the username already exists for another user, it will throw an exception. The default value for this property is “False” meaning that no column will be unique unless explicitly set.
@Column(nullable = false)
This places a restriction on the column and will make Spring Boot aware that this column cannot be null. If a record is attempted to be stored with a null value for this field, an exception will be thrown. The default value for “nullable” is true, meaning any field can be null unless explicitly set.
@Column(length = 512)
Adding a length property to the Column annotation allows the developer to increase the size of the field they want to insert. By default, this value is 255 and there may be cases where you need to insert a larger string than that. Setting this field to a bigger number should solve your problem if you ever need to increase it!
There are many other properties you can add to the column field but unless you’re ever after something specific, you can get by with just the basics outlined above. You can use more than one in a single Column annotation by separating them with a comma. It would look something like this:
@Column(unique = true, nullable = false)
Summary
Hopefully, this post gives you a good reference for the annotations you can use on a JPA entity class. See the below for a full class with a bit of everything mentioned above thrown in:
package uk.co.austellapp.entity-example.domain;
import javax.persistence.*;
@Entity
@Table(name = "user-data")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(unique = true, name = "user_name")
private String username;
@Column(length = 300)
private String password;
@Column(nullable = false, unique = true)
private String email;
private boolean active;
public User(String username, String password, String email) {
this.username = username;
this.password = password;
this.email = email;
}
public User() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", email='" + email + '\'' +
", active=" + active +
'}';
}
}
Feel free to ask any questions or add any comments if you have any!