Тип вибору за замовчуванням для одного-до-одного, багатьох-до-одного та одного-до-багатьох у сплячому режимі


103

Який тип вибору за замовчуванням у сплячих картах?

Що я дізнався після вивчення, це:

  • для одного-до-одного це нетерпляче .
  • для когось багато хто лінивий .

Але випробувавши його в Eclipse, він прагнув усіх.

Це залежить від того, я використовую JPA чи сплячий режим?


1
Якщо ви все ще займаєтесь темами JPA - я оновив ваше запитання новою відповіддю, оскільки старі застаріли для поточної сплячої версії.
Олександр Рюль

Відповіді:


193

Це залежить від того, чи використовуєте Ви JPA або Hibernate.

У специфікації JPA 2.0 за замовчуванням є:

OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER

А в сплячому режимі все ледаче

ОНОВЛЕННЯ:

Остання версія Hibernate узгоджується із зазначеними типовими параметрами JPA.


11
"І в сплячому режимі все ледаче", мабуть, це змінилося в останніх версіях. Будь ласка, дивіться відповідь Олександра Рюля нижче .
Діней

1
Hibernate - це одна з реалізацій JPA, тому коли ви використовуєте Hibernate, ви використовуєте JPA :)
xenteros

Це популярний запит. @Ashish Agarwal Чи можете ви, будь ласка, оновити останній рядок своєї відповіді. У сплячому режимі його поки не ліниво.
Саурабх Тіварі

Оновлено публікацію щодо останньої поведінки в сплячому режимі.
M Anouti

Було оновлено, що стверджується, що eager є типом вибору за замовчуванням для кожного зіставлення, яке переконується у розділі 11.3 як у поточній 5.x, так і в новій 6.x сплячій документації, тому я скасував редагування. Крім того, це суперечить рекомендації не мати автоматичного прагнення, оскільки це означало б, ймовірно, вибір всієї бази даних під час отримання одного об’єкта.
Олександр Рюль

51

Я знаю, що відповіді були правильними на момент запитання, але оскільки люди (як я в цю хвилину) все ще трапляються, що їх цікавить, чому їх WildFly 10 поводиться інакше, я хотів би дати оновлення для поточного сплячого 5 .x версія:

У Посібнику користувача Hibernate 5.2 це вказано в главі 11.2. Застосування стратегій отримання :

Рекомендація зі сплячого режиму полягає в тому, щоб статично позначати всі асоціації ледачими та використовувати динамічні стратегії отримання для готовності. На жаль, це суперечить специфікації JPA, яка визначає, що всі асоціації один до одного та багато хто до одного повинні бути охоче отримані за замовчуванням . Зимовий режим, як постачальник JPA, шанує цей дефолт.

Таким чином, сплячка також поводиться так, як Ашіш Агарвал, зазначений вище для JPA:

OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER

(див. специфікацію JPA 2.1 )


І що, якщо ми використовуємо натиснуту сплячку замість JPA impl, чи діють це так само?
jMounir

@jMounir: Ну, я цього не пробував, але оскільки в сплячому режимі заявляється, що він поводиться так, як визначено в JPA, я не бачу, чому це буде відрізнятися при використанні Hibernate для себе. В обох випадках можна змінити стратегію за замовчуванням.
Олександр Рюль

15

Щоб відповісти на ваше запитання, Hibernate - це реалізація стандарту JPA. У сплячому режимі є свої особливості функціонування, але відповідно до документів зі сну

За замовчуванням Hibernate використовує ледачий вибір добірки для колекцій та лінивий добір проксі для однозначних асоціацій. Ці параметри за замовчуванням мають сенс для більшості асоціацій у більшості програм.

Тож Hibernate завжди завантажує будь-який об’єкт, використовуючи стратегію ледачого отримання, незалежно від того, який тип відносин ви заявляли. Він буде використовувати лінивий проксі (який повинен бути неініціалізованим, але не нульовим) для одного об'єкта у взаємозв'язку «один на один» або «багато в одного», а також колекція з нулями, яка буде гідралізувати значення при спробі отримати доступ до нього .

Слід розуміти, що Hibernate намагатиметься заповнити ці об’єкти значеннями лише при спробі доступу до об'єкта, якщо ви не вказали fetchType.EAGER.


0

Для асоціацій з однозначним значенням, тобто "Один на один" та "Багато в одному": -
За замовчуванням Lazy = Проксі-
проксі-ліні завантаження : - Це означає, що проксі-об'єкт вашого асоційованого об'єкта завантажується. Це означає, що для проксі-об'єкта асоційованого об'єкта завантажується лише ідентифікатор, що з'єднує два об'єкти.
Напр .: A і B - це два об'єднання, що мають багато об'єднань. тобто: може бути декілька A на кожен B. Кожен об'єкт A міститиме посилання на B.
`

public class A{
    int aid;
    //some other A parameters;
    B b;
}
public class B{
    int bid;
     //some other B parameters;
}

`
Відношення A буде містити стовпці (допомога, ставка, ... інші стовпці об'єкта A).
Відношення B буде містити стовпці (ставка, ... інші стовпці об'єкта B)

Проксі означає, що коли A отримано, тільки B вибирається для B і зберігається в проксі-об'єкті B, який містить тільки id. Проксі-об'єкт B - це об'єкт проксі-класу, який є підкласом B з лише мінімальними полями. Оскільки ставка вже є частиною співвідношення A, не потрібно запускати запит, щоб отримати ставку від відношення B. Інші атрибути об'єкта B ліниво завантажуються лише тоді, коли доступ до поля, окрім ставки, не має.

Для колекцій, тобто багато-багато-багато-і-багато-багато: -
За замовчуванням


ледачий = вірно. Зверніть також увагу, що стратегія отримання (виберіть, приєднайтеся тощо) може перемогти лінивого. тобто: якщо lazy = 'true' і fetch = 'join', вилучення A також отримає B або Bs (у випадку колекцій). Причину ви можете отримати, якщо задуматися.
Вибір за замовчуванням для однозначного об'єднання - це "приєднатися".
Файл для колекцій за замовчуванням - це "вибрати". Перевірте останні два рядки. Я вивів це логічно.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.