Ошибка при отображении объекта Hibernate DB с использованием того же идентификатора - PullRequest
0 голосов
/ 08 июня 2018

Я занимаюсь практическим проектом с Spring MVC и Hibernate.Зная, что Hibernate может использовать аннотацию для сопоставления строки БД с объектом, я пытаюсь использовать Query, чтобы получить все объекты Account из БД в список, в то время как при их вставке они имеют некоторый дублированный идентификатор.

Код для получения учетных записей

@Override
public List<Account> getAccounts() {
    List<Account> list = new ArrayList<>();
    try {
        Session session = sessionFactory.getCurrentSession();
        Query<AccountEntity> query = session.createQuery("From AccountEntity", AccountEntity.class);
        List<AccountEntity> accounts = query.getResultList();
        for (int i = 0; i < accounts.size(); i++) {
            AccountEntity accountEntity = (AccountEntity) accounts.get(i);
            Account account = new Account();
            account.setAccountNo(accountEntity.getAccNo());
            account.setAccountHolderName(accountEntity.getAccHolderName());
            account.setBalance(accountEntity.getBalance());
            account.setAccountType(accountEntity.getAccountType());
            account.setPsCode(accountEntity.getPsCode());
            account.setDateOfBirth(accountEntity.getDateOfBirth());
            System.out.println("#: " + account.getAccountNo() + ", name: " + account.getAccountHolderName());
            list.add(account);
        }
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return list;
}

Теперь, когда я использую их в представлениях, дублированные идентификаторы создают строки с одинаковыми идентификатором, именем и балансом (имена не совпадают в БД). строки становятся одинаковыми

Это потому, что отображение в Hibernate просто основывается на идентификаторе, если идентификатор тот же, он создает тот же объект.

AccountEntity classс аннотациями:

@ Entity @Table (name = "account") открытый класс AccountEntity {

@Id
@Column(name="accountNo")
private int accNo;

@Column(name="accountHolderName")
private String accHolderName;

@Column(name="balance")
private int balance;

@Column(name="accountType")
private String accountType;

@Column(name="dateOfBirth")
private Date dateOfBirth;

@Column(name="psCode")
private String psCode;

public AccountEntity() {
}

public int getAccNo() {
    return accNo;
}

public void setAccNo(int accNo) {
    this.accNo = accNo;
}

public String getAccHolderName() {
    return accHolderName;
}

public void setAccHolderName(String accHolderName) {
    this.accHolderName = accHolderName;
}

public int getBalance() {
    return balance;
}

public void setBalance(int balance) {
    this.balance = balance;
}

public String getAccountType() {
    return accountType;
}

public void setAccountType(String accountType) {
    this.accountType = accountType;
}

public Date getDateOfBirth() {
    return dateOfBirth;
}

public void setDateOfBirth(Date dateOfBirth) {
    this.dateOfBirth = dateOfBirth;
}

public String getPsCode() {
    return psCode;
}

public void setPsCode(String psCode) {
    this.psCode = psCode;
}

} Что если я удалю @Id здесь?

Ответы [ 2 ]

0 голосов
/ 08 июня 2018

Hibernate кэширует объекты по идентификатору в своем кэше первого уровня (сеанс Hibernate).Как только он находит объект для идентификатора и кэширует его, он всегда возвращает один и тот же экземпляр объекта в течение всего жизненного цикла сеанса Hibernate.(Это случай шаблона, называемого «карта идентичности», есть хорошее объяснение, данное здесь ).

@ Id отмечает поле, сопоставленное первичному ключу таблицы, сопоставленной скласс сущности.Значения первичного ключа должны быть уникальными, никакие две строки таблицы не могут иметь одинаковое значение Id.Hibernate ожидает от вас отображения какой-то реляционной модели, а не просто случайного мусора, а это означает, что ключи должны быть уникальными.

Кстати, помните, что вы не должны ловить исключения, как показано в опубликованном коде, просто позвольте им быть сгенерированными.Вы можете указать компонент, помеченный @ControllerAdvice, для обработки исключений, выданных из контроллера.Самый простой и простой подход - использовать транзакционный уровень обслуживания отдельно от контроллеров для бизнес-логики и доступа к данным.

0 голосов
/ 08 июня 2018

@ Id аннотация объявляет поле первичного ключа в сущности.Каждый объект в спящем режиме должен иметь первичный ключ.Почему у вас есть повторяющиеся записи в вашей таблице, если accountNo является столбцом первичного ключа в базе данных.Если в таблице нет столбца первичного ключа, рассмотрите возможность использования столбца псевдо-первичного ключа.

Вам потребуется первичный ключ для выполнения любых операций CRUD с объектом.Вы можете не отображать первичный ключ для пользователя.Для большинства реляционных баз данных вы можете установить первичный ключ, который будет автоматически генерироваться базой данных.Например, следующий код будет указывать hibernate на использование базы данных для создания столбца id.

    @Id
    @GeneratedValue
    @Column(name = "ItemId", unique = true, nullable = false)
    private Integer                     Id;

Например, в SQL Server вы можете определить столбец как: [ItemId] [int] IDENTITY (10000000,1) НЕ НУЛЬ,

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...