Nano Hash - криптовалюты, майнинг, программирование

Отложенная выборка JPA Получение JoinCoulmn MappedBy ID

Вот ситуация

      @Entity
      public class Table_A implements Serializable {

      //TABLE_A FIELDS

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "TABLE_BID")
    public Table_B getTable_B() {
    return table_B;
}
      }

Таким образом, между Table_A и Table_B существует отношение «многие к одному». Мой вопрос: когда я делаю

Long tableB_ID = table_A.getTable_B().getTable_BID();

В реализации JPA/Hibernate выборка получает экземпляр TABLE_B и получает от него соответствующий идентификатор.

or

Получает идентификатор из сопоставленного столбца?

Заранее спасибо за ответы.


  • Я думаю, у вас есть ошибка в коде: table_A.getTable_B.getTable_BID() должно быть table_A.getTable_B().getTable_BID(). Пожалуйста, подтвердите, изменив свой вопрос, что я прав, или оставьте комментарий, если я ошибаюсь. 16.12.2013
  • ты прав. спасибо Андрей 16.12.2013

Ответы:


1

Когда вы указываете ленивую выборку для отношения, это указывает, что при доступе к объекту в этом случае, когда вы вызываете метод getTable_B() в этот момент, поставщик постоянства делает выбор в базе данных и заполняет объект. Это поведение является собственностью поставщика постоянства, в случае Hibernate он использует прокси-объекты, поэтому выборка выполняется при доступе к полю связанного объекта, поэтому getTable_B().getTable_BID(). Если вы хотите получить доступ только к TABLE_BID, вы можете сделать запрос JPQL или сопоставить это поле в своей таблице A, поэтому

 @Column(name="TABLE_BID")
 public Long getTable_BID() {
    return table_BID;
}
16.12.2013
  • Это неверно. вызов getTableB() не загружает состояние, связанное с TableB. Он просто возвращает неинициализированный прокси. Состояние загружается только при вызове метода на возвращаемом прокси. 16.12.2013
  • Это неправда, это зависит от того, как это реализует поставщик постоянства. Один из способов — прокси-объекты. Технически в JPA LAZY — это просто подсказка, и провайдер JPA не обязан его поддерживать. 16.12.2013
  • Но ОП специально попросил Hibernate. И Hibernate не делает этого, как вы говорите в своем ответе. 16.12.2013
  • Я собираюсь обновить свой ответ, но я не упоминаю спящий режим в своем ответе, я написал поставщика постоянства в целом, я не хочу конкретизировать, вопрос JPA/Hiberanate 16.12.2013
  • Получение значения TABLE_BID без обращения к базе данных, потому что, если объект A управляется, он уже имеет значение 16.12.2013
  • Да, объект A уже имеет значение TABLE_BID, поэтому извлечение его из объекта TableB не имеет смысла. Разве @JoinColumn(name = TABLE_BID) не создает этот сопоставленный столбец? Также необходимо аннотировать другой столбец, как вы упомянули в своем ответе? 16.12.2013
  • AFAIR Спецификация JPA не говорит, что @JoinColumn(name = TABLE_BID) создает этот сопоставленный столбец, я думаю, что если вы хотите получить доступ к этому столбцу, вы можете сделать это напрямую, чтобы избежать одного обращения к базе данных, и да, вам нужно сопоставить другой столбец. 16.12.2013
  • Сезар Лоашамин, я думаю, вы ошиблись в своих фактах. Вы уверены, что @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = TABLE_BID) не гарантирует наличие столбца?? 17.12.2013
  • Может быть, я не понимаю вопроса, извините. Возможно, моего английского недостаточно. Столбец гарантирует, что он существует в таблице A, но когда вы переходите к объекту отношения .getTable_B(), он зависит от поставщика постоянства того, как получить эти значения, в спящем режиме у него есть прокси-объект, возможно, если вы получите идентификатор, он не попадет в базу данных, возможно, когда вы получите объект, он пойдет и выберет все поля, как я сказал, @JoinColumn не гарантирует, что значение столбца соединения будет загружено, это зависит от того, как поставщик постоянства управляет отложенной выборкой. 17.12.2013
  • Спасибо, Сезар Лоашамин. 17.12.2013

  • 2

    AFAIR, это зависит от типа доступа, который сам по себе зависит от того, как вы аннотировали свои сущности. Если вы аннотировали геттеры, то вы используете тип доступа к свойству, и получение идентификатора не загрузит состояние TableB из базы данных. Если вы аннотировали поля, то вы используете тип доступа к полю, и получение идентификатора загрузит состояние TableB.

    Это, конечно, зависит от реализации. Но вы можете легко проверить это, включив ведение журнала SQL, выполнив свой код и посмотрев, сгенерирован ли запрос на загрузку состояния TableB или нет.

    16.12.2013
  • Спасибо, я знаю, что мы можем проверить это, включив ведение журнала SQL. Однако я переношу целое приложение, которое не работает, и я не думаю, что смогу сделать это сейчас. Так что просто хотел идею от экспертов. 16.12.2013

  • 3

    Ссылаясь на этот ответ: первый.

    Hibernate необходимо проверить, существует ли еще указанный экземпляр Table_B, поэтому он должен загрузить экземпляр, прежде чем вызывать для него getTable_BID().


    Изменить: На самом деле более интересным вопросом является этот вопрос. И в нем говорится, что то, что выбирает Hibernate, зависит от типа доступа - доступ к свойствам (это то, что у вас есть) не инициализирует прокси; Доступ к полю (помещение @ManyToOne/вашего @Id в поле) инициализирует прокси и загружает объект из базы данных.

    16.12.2013
  • Hibernate знает, существует ли объект, потому что он имеет идентификатор объекта (или null) в столбце соединения. 16.12.2013
  • @JBNizet Я сомневаюсь, что hibernate знает об этом: он не загрузил его, потому что он ленив, поэтому в тот момент он не уверен, что он существует. (PS: в БД может быть отсутствие ограничения внешнего ключа). 16.12.2013
  • @mabi, пожалуйста, игнорируйте схему именования, это абстрактное имя, используемое для вопроса. 16.12.2013
  • @JBNizet jup, должен был прочитать полностью (снова); исправил мой ответ. 16.12.2013
  • @JBNizet спасибо, я думаю, это дает четкое представление о том, как он может себя вести. Но дело в том, что приведенные выше аннотации создают столбец (TABLE_BID) в TableA, однако нет необходимости извлекать идентификатор из объекта tableB, когда он уже доступен в загруженном объекте TableA. 16.12.2013
  • @Andrei: Hibernate ожидает, что ваша схема будет в согласованном состоянии. Итак, если у вас есть идентификатор в JoinColumn, у вас должна быть соответствующая строка в TableB. Если у вас его нет, вы получите исключение, если только вы не используете проприетарную аннотацию [NotFound](docs.jboss.org/hibernate/orm/4.1/javadocs/org/hibernate/annotations/NotFound.html). 17.12.2013
  • @JBNizet точно. Но я сказал, что hibernate будет знать, существует ли эта строка, ТОЛЬКО когда она будет получена. Поскольку отношение помечено как ленивое, при загрузке объекта Table_A (с незагруженным отношением к Table_B) hibernate не знает, существует ли объект (но это то, что вы написали в первом комментарии). 17.12.2013
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

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

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

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

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..