Аннотация @Id
Каждая Entity-сущность в Hibernate должна иметь поле, которое будет первичным ключом: содержать уникальное значение для всех объектов данного класса. Обычно это поле помечается аннотацией @Id.
Общий вид:
@Id
Класс имя;
Пример:
@Entity
@Table(name="user")
class User
{
@Id
@Column(name="id")
public Integer id;
@Embedded
public UserAddress address;
@Column(name="created_date")
public Date createdDate;
}
Размещение аннотаций
Кстати, ты можешь писать аннотации @Column не только у полей, но и методов: у геттеров или сеттеров. Пример:
@Entity
@Table(name="user")
class User
{
public Integer id;
public Date createdDate;
@Id
@Column(name="id")
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name="created_date")
public Date getCreatedDate() {
return this.createdDate;
}
public void setCreatedDate(Date date) {
this.createdDate = date;
}
}
Такой подход появился, когда аннотации начали добавлять не только у классов, но и у интерфейсов. Полей класса у интерфейса нет, зато есть методы: геттеры и сеттеры. Hibernate поддерживает оба этих стандарта.
Важно! Если у класса есть аннотация @Entity, то все его поля рассматриваются Hibernate как сохраняемые поля (если у них не указана аннотация @Transient). Даже если у полей нет вообще никаких аннотаций: при этом имя колонки считается равным имени поля класса.
И тут аннотация @Id играет важную роль. Если аннотация размещена у поля класса, то Hibernate будет смотреть на имена и типы полей. Если аннотация @Id размещена у метода, тогда Hibernate будет смотреть на имена и типы методов.
Пример 1:
@Entity
@Table(name="user")
class User
{
@Id
public Integer id;
public Date createdDate; //это поле будет обработано как будто тут есть @Column(name="createdDate")
}
Пример 2:
@Entity
@Table(name="user")
class User
{
public Integer id;
public Date createdDate;
@Id
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public Date getCreatedDate() { //это поле будет обработано как будто тут есть @Column(name="createdDate")
return this.createdDate;
}
public void setCreatedDate(Date date) {
this.createdDate = date;
}
}
Аннотация @GeneratedValue
Ты можешь присваивать id твоим новым объектам самостоятельно, или отдать это на откуп Hibernate. Для того чтобы Hibernate лучше понимал, как присваивать ID твоим объектам, у него есть специальная аннотация:
@GeneratedValue
Этой аннотацией обычно помечается то же поле, что и аннотацией @Id. У нее есть 4 возможных стратегии присвоения ID:
- AUTO
- IDENTITY
- SEQUENCE
- TABLE
Пример аннотации с указанной стратегией:
@Entity
@Table(name="user")
class User
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Integer id;
public Date createdDate;
}
Если значение стратегии не указано, то выберется стратегия AUTO. Стратегия AUTO означает, что Hibernate будет сам назначать ID, основываясь в первую очередь на типе данных у поля ID.
Почему именно на типе? Да потому, что типы у ID могут быть очень разные, например, String или GUID. Пример:
@Entity
@Table(name="user")
class User
{
@Id
@GeneratedValue
public UUID id;
public Date createdDate;
}
Примечание: GUID в Java называется UUID, так исторически пошло. И Hibernate умеет генерировать уникальные UUID для твоих объектов, если ты его об этом попросишь.
Различные стратегии @GeneratedValue
Если ты укажешь тип GeneratedValue(strategy = GenerationType.IDENTITY), то Hibernate делегирует установку ID на уровень базы данных. Обычно при этом используется колонка, помеченная как PRIMARY KEY, AUTOINCREMENT.
А вот если ты хочешь, чтобы твои ID были уникальными и генерировались по специально заданному алгоритму, то можешь воспользоваться аннотацией GeneratedValue(strategy = GenerationType.SEQUENCE), пример:
@Entity
@Table(name="user")
public class User {
@Id
@GeneratedValue(generator = "sequence-generator")
@GenericGenerator(
name = "sequence-generator",
strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
parameters = {
@Parameter(name = "sequence_name", value = "user_sequence"),
@Parameter(name = "initial_value", value = "4"),
@Parameter(name = "increment_size", value = "1")
}
)
private long userId;
// ...
}
Есть еще много разных способов генерации ID. Например, у тебя может быть составной уникальный ключ, состоящий из нескольких колонок. И при записи объекта в базу, нужно все эти колонки заполнить.
Я не буду их подробно приводить. Все-таки задача наших лекций – это знакомство с Hibernate, а не пересказ официальной документации.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ