Хобрук: Ваш путь к мастерству в программировании

Hibernate/JPA - индекс внешнего ключа в самом объекте

В настоящее время я работаю над более чем 100 объектами Java, созданными кем-то, у кого нет опыта JPA/Hibernate в объектах JPA. Их объекты ссылаются на другие объекты на основе внешнего ключа в самом классе. Все первичные ключи генерируются вне базы данных.

Например (просто для иллюстрации)

Автомобиль

@Entity
@Table(name="CAR")
public class Car {

    private Integer id;
    private String name;

    @Id
    @Column(name="CAR_ID")
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }

    @Column(name="CAR_NAME")
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

}

Двигатель

@Entity
@Table(name="ENGINE")
public class Engine {

    private Integer id;
    private String name;
    private Integer carId;

    @Id
    @Column(name="ENGINE_ID")
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }

    @Column(name="ENGINE_NAME")
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    @Column(name="CAR_ID")
    public Integer getCarId() {
        return carId;
    }
    public void setCarId(Integer carId) {
        this.carId = carId;
    }

}

Вот как выглядит схема:

CREATE TABLE CAR(CAR_ID INTEGER NOT NULL PRIMARY KEY,CAR_NAME VARCHAR(255))
CREATE TABLE ENGINE(ENGINE_ID INTEGER NOT NULL PRIMARY KEY,CAR_ID INTEGER,ENGINE_NAME VARCHAR(255))
ALTER TABLE ENGINE ADD FOREIGN KEY (CAR_ID) REFERENCES CAR(CAR_ID) ON DELETE CASCADE ON UPDATE CASCADE

Тестирование кода

    Car c = new Car();
    c.setId(100);
    c.setName("Dodge Intrepid");
    em.persist(c);

    Engine e = new Engine();
    e.setId(999);
    e.setName("V6");
    e.setCarId(c.getId());
    em.persist(e);

    Object entity = em.find(c.getClass(),c.getId());
    em.remove(entity);

Таким образом, идентификатор автомобиля содержит ссылку на двигатель в базе данных. Потеря отложенной загрузки не имеет большого значения, потому что мы используем TRANSACTIONAL Entity Manager. Я проверил это, и, похоже, он работает нормально.

Есть ли какие-то очевидные проблемы с этим, которые я упускаю? Я знаю, что это не совсем соответствует спецификации JPA/Hibernate, но я думаю, что это работает.


  • Какова ваша выгода после замены ссылки на объект отношением id? 13.07.2009
  • Преимущество заключается в том, что мне не нужно просматривать и обновлять более 100 объектов, чтобы использовать аннотации @OneToOne или @OneToMany. 13.07.2009

Ответы:


1

Главное, что вы теряете, — это простая навигация по графу объектов без необходимости все время явно извлекать связанные объекты по идентификатору через уровень доступа к данным. Я понимаю, что вы не хотите проходить и преобразовывать все идентификаторы объектов в ссылки на объекты, но в долгосрочной перспективе вам, вероятно, лучше сделать эти инвестиции. Продолжая свой текущий дизайн, вы в конечном итоге напишете много дополнительного кода доступа к данным для извлечения связанных объектов каждый раз, когда вам нужно перемещаться по ассоциации. Кроме того, это усложнит моделирование отношений между объектами, когда объекты не сохраняются в базе данных (например, при построении нового графа объектов или в модульных тестах). Вы также отказываетесь от каскадных (переходных) сохранений и обновлений.

Короче говоря, я думаю, что вашу систему будет сложнее поддерживать в долгосрочной перспективе, а навигация по графам объектов будет довольно неудобной, если вы не решите эту проблему дизайна.

13.07.2009
  • Извините за отрицательное голосование, но я считаю, что вы не учитываете недостатки сохранения графа объектов. Хотя вы справедливо возразили, что по полному графу объектов проще навигация, существуют ситуации, в которых вам никогда не понадобится перемещаться по графу, по крайней мере, для нескольких ссылок в сущности. В этом случае, если вам нужен только идентификатор этого ссылочного объекта, вы либо загружаете весь ссылочный объект, либо заставляете Hibernate лениво загружать его только для проверки его идентификатора. 07.06.2013
  • @djechelon Я только что наткнулся на твой комментарий. Так есть ли решение проблемы, которую вы только что описали? Мне нужна простая навигация по графу объектов, но иногда мне просто нужен идентификатор, например, для проверки на равенство объектов. Спасибо. 12.06.2013
  • Существует: stackoverflow.com/questions/15945944/ 12.06.2013

  • 2

    Отсутствие каких-либо сопоставленных отношений сделает практически невозможным любое объединение в ваших запросах или критериях HQL. Простой Select будет работать, но вы не можете сделать

    from Engine as eng where eng.car.name = 'DODGE'
    

    Если вы, по крайней мере, закодируете основные отношения, это значительно облегчит задачу в долгосрочной перспективе.

    13.07.2009
    Новые материалы

    Создание кнопочного меню с использованием HTML, CSS и JavaScript
    Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

    Внедрите OAuth в свои веб-приложения для повышения безопасности
    OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

    Классы в JavaScript
    class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

    Как свинг-трейдеры могут использовать ИИ для больших выигрышей
    По мере того как все больше и больше профессиональных трейдеров и активных розничных трейдеров узнают о возможностях, которые предоставляет искусственный интеллект и машинное обучение для улучшения..

    Как построить любой стол
    Я разработчик программного обеспечения. Я люблю делать вещи и всегда любил. Для меня программирование всегда было способом создавать вещи, используя только компьютер и мое воображение...

    Обзор: Машинное обучение: классификация
    Только что закончил третий курс курса 4 часть специализации по машинному обучению . Как и второй курс, он был посвящен низкоуровневой работе алгоритмов машинного обучения. Что касается..

    Разработка расширений Qlik Sense с qExt
    Использование современных инструментов веб-разработки для разработки крутых расширений Вы когда-нибудь хотели кнопку для установки переменной в приложении Qlik Sense? Когда-нибудь просили..