Как я маплю сущности. Базовые моменты, исключил частные случаи. Не использовал аннотации валидации, решил что в dto их возможно лучше поставить. Интересно узнать как делают в профессиональном коммерческом проекте? Возможные ошибки? Фичи? Что то мб еще не знаю, и потому не использовал.
// указываю аннотации
@Entity // для всех jpa сущностей
@Table(name = "users", indexes = {
        @Index(name = "idx_users_email", columnList = "email", unique = true)
    }
) // опционально, по необходимости
@AllArgsConstructor
@NoArgsConstructor
@Setter
@Getter
@ToString(exclude = "accounts") // исключаю связные сущности, что бы избежать lazy exception
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class User extends BaseEntity {

    // указываю что поле не должно быть пустым, unique я указал в @Table
    @Column(nullable = false)
    private String email;

    @Column(nullable = false)
    private String name;

    // - сеттер делаю private для коллекций связных сущностей
    // - каскад смотрим что нужно то и ставим, например я хочу что бы при удалении User
    // удалялись и все аккаунты, то нужно CascadeType.REMOVE.
    // - orphanRemoval - по необходимости, используем что бы в бд пошел запрос, если удаляешь в коде что то из коллекции
    // - коллекцию инициализирую сразу, hibernate все равно подставит прокси когда надо, так что проблем не будет
    @Setter(AccessLevel.PRIVATE)
    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Account> accounts = new ArrayList<>();

    // что бы не писать каждый раз в методах в джава коде,
    // добавим методы для коллекций связных сущностей
    public void addAccount(Account account) {
        accounts.add(account);
        account.setUser(this);
    }

    public void removeAccount(Account account) {
        accounts.remove(account);
        account.setUser(null);
    }
}
@Entity
@Table(name = "accounts", indexes = {
        @Index(name = "idx_account_account_number", columnList = "accountNumber", unique = true)
    }
)
@AllArgsConstructor
// убираю возможность создать пустую сущность, не нужен аккаун у которого user = null
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Setter
@Getter
@ToString(exclude = "user")
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class Account extends BaseEntity {

    @Column(name = "account_number", nullable = false)
    private String accountNumber;

    private BigDecimal balance;

    @ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id") // маппинг на стороне чаилда, поэтому foreign key указываем в accounts
    private User user;
}
// добавляем base class что бы вынести совподающие поля потом сделать extends
// таблицы в бд для этого класса не будет
@MappedSuperclass
@Setter
@Getter
public class BaseEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
}
- аннотации валидации не ставил, решил что возможно их лучше в dto проставить. - не все параметры использовал, чисто основные моменты. - не использую @Data - как будто поведение становится менее контролируемым. - осторожно с @ToString и @EqualsAndHashCode, могут возникнуть проблемы с связными сущностями. SQL скрипты такие: (возможно что то не учел, или сделал ошибку, т.к. специально не разбирал, просто с головы как понял)
create table users (
    id bigint not null auto_increment,
    email varchar(50) not null unique,
    name varchar(25) not null,
    constraint users_pk primary key (id),
    constraint users_email_ak unique (email)
)

create table accounts (
    id bigint not null auto_increment,
    user_id bigint not null,
    account_number varchar(150) not null unique,
    balance decimal(6,1),
    constraint accounts_pk primary key (id),
    constraint accounts_users_fk foreign key (user_id) references users(id) on delete cascade
)

--для индекса например так:
create unique index idx_account_account_number on accounts(account_number);
Так же интересно часто ли джуны с бд работают на прямую, грубо говоря, приходится ли писать sql, например по созданию таблиц.