Hibernate vs JPA vs JDO - плюси і мінуси кожного? [зачинено]


174

Я знайомий з ORM як концепцією, і я навіть кілька років тому навіть використовував nHibernate для проекту .NET; однак я не встиг за темою ORM на Java і не мав можливості скористатися жодним із цих інструментів.

Але тепер, можливо, я маю шанс почати використовувати деякі засоби ORM для одного з наших додатків, намагаючись відійти від низки застарілих веб-служб.

Мені важко розповісти різницю між специфікацією JPA, що ви отримуєте з самої Hibernate бібліотеки та що може запропонувати JDO.

Отже, я розумію, що це питання є дещо відкритим, але я сподівався отримати певну думку щодо:

  • Які плюси і мінуси кожного?
  • Що б ви запропонували для нового проекту?
  • Чи є певні умови, коли було б сенс використовувати один фреймворк проти іншого?

Відповіді:


112

Деякі примітки:

  • JDO та JPA - це специфікація, а не реалізація.
  • Ідея полягає в тому, що ви можете обмінятись реалізаціями JPA, якщо ви обмежите свій код лише стандартними JPA. (Дітто для JDO.)
  • Hibernate може бути використаний як одна така реалізація JPA.
  • Однак, Hibernate пропонує вбудований API з функціями, що перевищують та перевищують функції JPA.

ІМО, я б рекомендував зимувати.


Були деякі коментарі / запитання щодо того, що вам потрібно робити, якщо вам потрібно використовувати функції, пов’язані зі сном. Є багато способів переглянути це, але моя порада буде:

  • Якщо вас не турбує перспектива підключення постачальника, тоді зробіть вибір між режимом hibernate та іншими реалізаціями JPA та JDO, включаючи різні розширення для конкретних постачальників у процесі прийняття рішень.

  • Якщо вас турбує перспектива підключення постачальника, і ви не можете використовувати JPA, не вдаючись до конкретних розширень для постачальника, тоді не використовуйте JPA. (Дітто для JDO).

Насправді вам, ймовірно, доведеться компенсувати, наскільки ви турбуєтесь про зв’язування постачальника та наскільки вам потрібні ці розширення для конкретних постачальників.

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


8
інструментарій, приємний і короткий. Ще один момент, який варто зазначити, - це те, що JPA не перешкоджає використанню конкретних функцій, якщо необхідно. Це означає, що JPA дозволяє використовувати будь-яку функцію сплячого режиму, коли Hibernate є реалізацією.
топчеф

1
Які б були переваги використання JPA, якщо мені потрібна якась особлива функція від сплячого режиму?
Бруно Рейс

22
Важливе зауваження, яке слід додати: Хоча JPA та JDO мають чудову підтримку RDBMSes, JDO є агностиком "сховища даних", тому він не обмежується світом RDBMS. На даний момент NoSQL набухає основної сили, людині було б розумно подумати про використання стандарту стійкості, який дозволяє уникнути блокування своїх додатків у традиційному світі SQL. Програми JDO можуть бути легко розгорнутими не сховищами RDBMS. Повний список підтримуваних сховищ даних можна знайти за адресою: datanucleus.org/products/accessplatform/datastores.html
Volksman

2
@Golfman чому вибирати, виходячи з того, що може статися? Пізніше нічого не заважатиме вам перекочувати щось, якщо вам коли-небудь потрібна підтримка NoSQL ... KISS
TM.

1
@Bruno - при використанні не-Hibernate специфічних частин Hibernate, ви які з допомогою JPA. Очевидно, що перевага обмеження себе в чистому JPA полягає в тому, що ви можете легше перейти на іншу реалізацію JPA.
Стівен С

69

Переконайтесь, що ви оцінюєте реалізацію JDO DataNucleus. Ми розпочали роботу зі сплячки, тому що вона виявилася такою популярною, але досить скоро зрозуміла, що це не 100% прозоре рішення. Занадто багато застережень, і документація наповнена "якщо у вас є така ситуація, то ви повинні написати свій код так", який позбавив задоволення від вільного моделювання та кодування, як би ми не хотіли. JDO ніколи не змушував мене коригувати свій код або свою модель, щоб змусити його працювати «належним чином». Я можу просто спроектувати та кодувати прості POJO так, як ніби я збираюся використовувати їх лише «у пам’яті», але я можу зберігати їх прозоро.

Інша перевага JDO / DataNucleus перед сплячим режимом полягає в тому, що він не має всіх витрат на відображення часу запуску і є більш ефективним у пам’яті, оскільки використовує поліпшення коду байтового часу збірки (можливо, додайте 1 сек до свого часу збирання для великого проекту) ніж відображення часу роботи в сплячому режимі на основі схеми проксі-сервера.

Інша річ, яку ви можете роздратувати у сплячому режимі, - це те, що ви посилаєтесь на те, що ви вважаєте об'єктом ... це часто "проксі" для об'єкта. Без переваги покращення байтового коду необхідний шаблон проксі-сервера, щоб дозволити завантаження на вимогу (тобто уникати потягування всього графіку об'єкта, коли ви тягнете об'єкт верхнього рівня). Будьте готові до вибору рівних та хеш-коду, тому що об'єкт, на який ви посилаєтесь, часто є лише проксі-сервером цього об’єкта.

Ось приклад розладів, які ви отримаєте зі сплячки, які ви не отримаєте з JDO:

http://blog.andrewbeacock.com/2008/08/how-to-implement-hibernate-safe-equals.html
http://burtbeckwith.com/blog/?p=53

Якщо вам подобається кодування на "обхідні шляхи", тоді, звичайно, "Зимовий режим" для вас. Якщо ви цінуєте чисту, чисту, орієнтовану на об'єкти, розробку, орієнтовану на модель, де ви витрачаєте весь свій час на моделювання, дизайн та кодування, і жодне з них на некрасиві способи вирішення проблем, тоді витрачайте кілька годин на оцінку JDO / DataNucleus . Вкладені години будуть погашені в тисячу разів.

Оновлення лютого 2017 року

Даний час DataNucleus 'впроваджує стандарт стійкості JPA на додаток до стандарту JDO-стійкості, тому перенесення існуючих проектів JPA від сплячого до DataNucleus повинно бути дуже прямим вперед, і ви можете отримати всі вищезгадані переваги DataNucleus з дуже невеликою зміною коду. , якщо якийсь. Тож, з точки зору питання, вибір конкретного стандарту, JPA (тільки RDBMS) проти JDO (RDBMS + Ні SQL + ODBMSes + інші), DataNucleus підтримує обидва, Hibernate обмежується лише JPA.

Продуктивність оновлень СБ у сплячому режимі

Ще одне питання, яке слід враховувати при виборі ОРМ, - це ефективність його брудного механізму перевірки - що стає дуже важливим, коли йому потрібно побудувати SQL для оновлення об'єктів, які змінилися в поточній транзакції - особливо, коли об'єктів багато. Детальний технічний опис механізму брудної перевірки Hibernate в цій відповіді ТА : JPA із вставкою HIBERNATE дуже повільно


3
І як ми всі знаємо, саме вдосконалення JDO настільки масово прийнято!
Паскаль Тивеннт

15
Широко розрекламована FUD та астротурфінг, виконані ключовими гравцями в сплячку в перші дні стосовно JDO, не є нечесним та огидним, і, без сумніву, мали певний вплив на прийняття JDO. У наші дні розробники знають, що покращення байтового коду зовсім не є проблемою, і часто використовують його для багатьох інших цілей, крім наполегливості. Нова бібліотека покращення байтового коду ASM настільки блискавично швидко, що навіть не встигнути зробити подих, перш ніж це зробити.
Фолксман

7
Провал JDO передбачувався з початку ( javalobby.org/forums/thread.jspa?forumID=46&threadID=1326 ) і до сплячого, тому ви не можете звинувачувати в цьому сплячку . Hibernate / Toplink досягли успіху там, де гравці Sun та JDO (та їхні OODBMS) зазнали невдач, оскільки в той час вони були кращими відповідями, а не через маркетинг та FUD. Період. Кому байдуже, чи ASM швидко палає сьогодні , його не було 5 років тому, коли це було потрібно, і JDO просто програв битву. JDO концептуально перевершує? Шкода, що не вдалося вчасно реалізувати переможця (і не повернеться через JPA).
Паскаль Thivent

2
Щоб проілюструвати мої слова (ще одна публікація, яка ілюструє біль, який відчували люди під час розвитку, або чому Гібернація перемогла в битві): mail-archive.com/open-jpa-dev@incubator.apache.org/… . Мені здається очевидним, що роздум / cglib був практичною відповіддю на проблеми людей (і людей не хвилює, чи API ідеально перевершує, якщо це боляче), і я не бачу тут жодних ключових гравців у сплячому режимі, просто користувачів . Тож наприкінці мені цікаво, хто насправді поширює
FUD

7
Ну, це, звичайно, не так, як у старі часи, коли було б принаймні 17 різних профі про зимуючий FUD (але вони надходять лише з 3-х різних IP-адрес. Робіть математики людей =)).
Volksman

54

Нещодавно я оцінив і обрав постійну основу для проекту java, і мої висновки такі:

Я бачу, що підтримка на користь JDO полягає насамперед:

  • ви можете використовувати не-sql джерела даних, db4o, hbase, ldap, bigtable, couchdb (плагіни для кассандри) тощо.
  • ви можете легко перейти з sql на не-sql джерело даних і навпаки.
  • немає проксі-об'єктів і, отже, менше болю щодо хеш-коду () та рівності () реалізації
  • більше POJO і, отже, потрібно менше обхідних шляхів
  • підтримує більше типів відносин і полів

і підтримка на користь JPA полягає насамперед:

  • більш популярні
  • jdo мертвий
  • не використовує розширення байт-коду

Я бачу багато публікацій про JPA від розробників JPA, які явно не використовували JDO / Datanucleus, пропонуючи слабкі аргументи за те, щоб не використовувати JDO.

Я також бачу багато публікацій від користувачів JDO, які перейшли до JDO і в результаті набагато щасливіші.

Що стосується популярності JPA, то, здається, це частково пояснюється підтримкою постачальників RDBMS, а не технічно перевершує. (Мені звучить як VHS / Betamax).

JDO та його посилання на реалізацію Datanucleus явно не мертві, як показано прийняттям Google від Google для GAE та активної розробки вихідного коду (http://sourceforge.net/projects/datanucleus/).

Я бачив ряд скарг на JDO через розширення байт-коду, але поки немає пояснень, чому це погано.

Насправді, у світі, який стає все більш одержимим рішеннями NoSQL, JDO (та реалізація данихнуклеусів) здається набагато безпечнішою.

Щойно я почав використовувати JDO / Datanucleus і налаштував його так, щоб я міг легко перемикатися між використанням db4o та mysql. Для швидкої розробки корисно використовувати db4o і не надто турбуватися про схему БД, а потім, як тільки схема стабілізується, розгортається до бази даних. Я також впевнений, що пізніше я міг би розгорнути всю / частину своєї програми до GAE або скористатися розподіленим сховищем / картою-зменшити а-ля hbase / hadoop / cassandra, не надто багато рефакторингу.

Я знайшов початкові перешкоди для початку роботи з Datanucleus трохи складними - Документація на веб-сайті datanucleus трохи важко потрапити - підручники не так легко виконувати, як хотілося б. Сказавши це, більш детальна документація щодо API та картографування є дуже хорошою, як тільки ви пройдете початкову криву навчання.

Відповідь - це залежить від того, що ви хочете. Я б скоріше мав чистіший код, не-постачальник-блокування, більш орієнтований на pojo, ноші-вірші, варіанти віршів більш популярні.

Якщо ви хочете відчути тепле метушливе відчуття, що ви робите так само, як і більшість інших розробників / овець, виберіть JPA / сплячку. Якщо ви хочете лідирувати у своїй галузі, пробний диск JDO / Datanucleus і зробіть свій власний розум.


9
Насправді, як я вже говорив, я просто створював свої враження про те, що я виявив, намагаючись вибрати рішення. Так, я початківець в Java, чому це повинен бути цей ревент? Ви, з іншого боку, неодноразово публікували свою думку про те, що JDO мертвий, не пропонуючи жодних фактів чи доказів, які підтверджують це, і не визнаючи технічних напрямків, де JDO явно перевершує. У вас, очевидно, є щось особисте проти JDO / Datanucleus і ви використовуєте ці нитки як засіб для увічнення вашої анти-JDO позиції.
Том

4
Паскаль - ви сперечаєтесь тут у кутку. Думаю, вам не вистачає точки рекламного розділу в FAQ. ОП попросила думки щодо двох технологій. Закликає тих, хто підтримує будь-яку сторону, виступити та викласти свої конструктивні критичні погляди / рекомендації. Для Енді / Datanucleus та інших користувачів JDO підкреслити позитиви JDO та захиститись від критики - це не більше реклами, ніж хто-небудь інший, який рекомендує використовувати сплячий режим.
Том

5
Ви можете звернутися до розділу FAQ, де написано "Будьте приємні", оскільки ваші пости на цю тему були звинувачуючими, конфронтаційними чи відвертими. Вашим першим був саркастичний коментар щодо удосконалення. Другий; ціна на труднощі раннього впровадження і вже не актуальна. По-третє, було по-дитячому глузування та образа до тих, хто, можливо, вважає за краще не використовувати RDBMS. Четверте - саркастичне глузування з того, хто має різні погляди на вас. П'ятий був нападом; називає мене папугою. Чи вважаєте ви це "гарним"?
Том

3
Якщо у вас був жахливий досвід роботи з JDO, то поясніть, що було жахливо, визнайте, що це було з попередньою версією, і з цього часу все може покращитися. Вам також потрібно визнати, що інші можуть мати різні потреби до вас. Тільки тому, що ви 'задоволені' JPA і хочете використовувати RDBMS, не означає, що це і інші. Може, поспішивши розширити свою репутацію, ви втратили з поля зору, яку репутацію можна нагородити? пс. Як розробника, вам справді слід зацікавити добробут таких проектів, адже саме це стимулює інновації та зменшує замок від постачальників.
Том,

6
Це буде моя остаточна відповідь :) .. 1. Якщо не було питання, навіщо це піднімати? 2. Я ніколи не сумнівався у вашій чесності, я казав, що ви не любите інших плакатів і що ви суперечили собі. 3. Ніхто не пропонував вам підводити підсумки 8+ років - але підкріплюйте свої заяви фактами та прикладами, а не суб'єктивними твердженнями, які можуть образити. 5. Де на цьому посту ставляться "сплячий / jpa / jboss - зло"? Я цього не бачу. Я бачу лише ваші коментарі проти JDO.
Том

40

Що б ви запропонували для нового проекту?

Я б не запропонував жодного! Використовуйте Spring DAO JdbcTemplateразом із StoredProcedure, RowMapperа RowCallbackHandlerзамість цього.

Мій власний досвід роботи зі сплячим режимом полягає в тому, що заощаджений час передує більш ніж компенсовано нескінченними днями, які ви витратите вниз, намагаючись зрозуміти та налагодити такі проблеми, як несподівана каскадна поведінка оновлення.

Якщо ви використовуєте реляційну БД, то чим ближче ваш код, тим більше контролю у вас є. Шар DAO Spring забезпечує точний контроль шару відображення, при цьому видаляючи потребу в кодовому шаблоні. Крім того, він інтегрується в транзакційний шар Spring, що означає, що ви можете дуже легко додати (через AOP) складну трансакційну поведінку, не вторгнувшись у ваш код (звичайно, ви отримуєте це також із Hibernate).


4
це чітко антиоб'єктно-реляційне відображення (ORM) на основі великої користувальницької та кодової бази, накопиченої з часів ODBC (початок 90-х) (читати спадщину). Немає ніяких причин не використовувати JDBC (з Spring або без), якщо ви не вирішите перейти та використовувати рамки ORM. Подумайте про тих людей, які одного разу вирішили кинути FORTRAN використовувати C або Pascal.
топчеф

23
@grigory - я маю великий досвід витрачання днів, намагаючись розібратися в проблемах зі сплячки, таких як каскадні оновлення / видалення, смішно неефективні структури запитів і т.д. Таким чином, навряд чи знання лише про сплячку спричинить хороший кінцевий продукт. З мого досвіду, що протягом життєвого циклу проекту сплячка (і ORM за допомогою розширення) коштує більше часу, ніж економить
oxbow_lakes

8
вибачте, що у вас був такий поганий досвід зі сплячки. Я надходжу з важкої бази даних / SQL / зберігається процедура / школа JDBC сама. Я не можу сказати, що я конвертую - кожна технологія вище все ще має місце бути. Але для загального призначення трирівнева програма Java (незалежно від того, який розмір) перший вибір - це технологія ORM - бажано JPA 2. Інші повинні розглядатися на основі таких факторів, як застарілий код, інтеграція, досвід, пакетні важкі вимоги, в режимі реального часу продуктивність тощо, що може спрямовувати (а може і не) підходити до різних стеків технологій баз даних.
топчеф

3
Я повністю не погоджуюся з вищевикладеним "швидким виграшним" визначенням - просто захопіть сплячку в дії ( stackoverflow.com/questions/96729/… ) (і це JPA 1, а JPA 2 стає тільки краще), щоб повністю зрозуміти потужність і охопити цю технологію. має.
топчеф

7
Я трохи провів дослідження, і Spring більше не рекомендує Spring DAO ( static.springsource.org/spring/docs/3.0.x/… ): "Рекомендований стиль інтеграції полягає в кодуванні DAOs проти звичайного Hibernate, JPA та JDO API. старіший стиль використання шаблонів DAO Spring більше не рекомендується; "... Це те, що ви рекомендували? Якщо так, то чому їх не рекомендують?
Користувач1

23

JDO мертвий

JDO насправді не мертвий, тому, будь ласка, перевірте свої факти. JDO 2.2 був випущений в жовтні 2008 р. JDO 2.3 знаходиться на стадії розробки.

Це розроблено відкрито, під Apache. Більше випусків, ніж у JPA, і його специфікація ORM все ще наперед, навіть запропоновані JPA2 функції


12
Люди, безумовно, користуються ним, про що свідчать багато користувачів, якими користується DataNucleus, не маючи на увазі Xcalia, Kodo. Ви пропускаєте основну думку, що JDO та JPA не заповнюють один і той же ринок. JPA - це виключно RDBMS. JDO - це агностик для зберігання даних і використовується для RDBMS, а також LDAP, XML, Excel, OODBM тощо
DataNucleus

3
Мені подобається фактор не-RDBMS, особливо зі збільшенням популярності рішень, що не є RDBMS, це велика справа. Це означає, що якщо JPA не розвиватиметься досить швидко, наявність «більш відкритої» та гнучкої альтернативи (JDO) означає, що популярність JPA буде скорочуватися вниз, поза необхідністю. Не забувайте про технічні аргументи про те, що JDO є більш повним, вищим, зрілим чи будь-яким іншим - це не буде питанням уподобань . Має сенс, що постачальники RDBMS ведуть себе підозріло - дні домінування на ринку RDBMS можуть закінчуватися.
Маній

Ми все ще використовуємо JDO / DataNucleus у 2019 році! Він тепер до версії 5.x і досі перебуває в сплячому режимі за продуктивність розробника та продуктивність роботи. Нещодавно мені довелося проконсультуватися з великим веб-додатком за допомогою Hibernate, і мені нагадали про біль, яку я зазнав, коли я був активним користувачем HIbernate та промоутером багато років тому, керівник команди не повірив мені, коли я сказав їй, що її поле BLOB завжди був охоче зібраний, навіть якщо це було позначено як лінивий збір. Повна відсутність знань "під капотом" досвідченого "самопроголошеного експерта зі сплячого режиму" була сумно тривожною, але очікуваною.
Фолксман


10

Я використовую JPA (реалізація OpenJPA від Apache, що базується на кодовій базі KODO JDO, якій більше 5 років і надзвичайно швидко / надійно). ІМХО кожен, хто скаже вам обійти характеристики, дає вам погану пораду. Я вклав час і був неодмінно нагороджений. За допомогою JDO або JPA ви можете змінити постачальників з мінімальними змінами (JPA має відображення в ормах, тому ми говоримо менше, ніж день, щоб можливо змінити постачальників). Якщо у вас є 100+ таблиць, як у мене, це величезна кількість. Крім того, ви отримуєте вбудований кеш-пам'ять з вилученням кеш-кластера та його всім хорошим. SQL / Jdbc чудово підходить для високоефективних запитів, але прозора наполегливість набагато перевершує написання алгоритмів і процедур введення даних. У мене всього 16 запитів SQL у всій моїй системі (50 к + рядків коду).


8

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


6
+1 для DataNucleus, а не для відповіді.
WolfmanDragon

8

Кожен, хто каже, що JDO мертвий, є астротурфінгом, який це знає.

JDO живий і здоровий. Технічні характеристики все ще є більш потужними, зрілими та вдосконаленими, ніж значно більш молодий та стриманий JPA.

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


1
Або ви використовуєте іншу (прекрасну) реалізацію із значно більшою та відповідно чуйною спільнотою. Так, деякі люди теж дбають про це.
Паскаль Thivent

1
А ви говорите про FUD> :) Смішно.
Паскаль Thivent

2
Здається, ваш коментар передбачає, що я не використовував і сплячку, і JDO.
Volksman

2
Здається, цей потік має дуже багато посилань від кількох людей на те, наскільки великий DataNucleus. Не використовуйте це місце як рекламну платформу.
ТМ.

3
Нічого дивного від Golfman, який склеює ті самі відчайдушні маркетингові речі у кожній нитці, що включає JPA або DataNucleus (що він використовує з 1996 року , перш ніж він навіть існував !).
Паскаль Thivent

2

Я використовував Hibernate (реалізація JPA) та JPOX (реалізація JDO) в одному проекті. JPOX спрацював нормально, але зіткнувся з помилками досить швидко, там, де деякі функції Java 5 мови він не підтримував у той час. У нього виникли проблеми з приємною грою з транзакціями XA. Я генерував схему бази даних з об'єктів JDO. Він хотів підключатися до бази даних кожного разу, що дратує, якщо ваше з'єднання Oracle не працює.

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

Деякі інші респонденти запропонували просто використовувати SQL. Справжній випадок використання вбивць для реляційного відображення об'єктів - це тестування та розробка. Бази даних, створені для обробки великого обсягу даних, як правило, дорогі і їх важко встановити. З ними складно перевірити. Існує безліч баз даних Java в пам'яті, які можна використовувати для тестування, але, як правило, марні для виробництва. Можливість використовувати реальну, але обмежену базу даних, підвищить продуктивність розробки та надійність коду.


1
Наскільки я можу сказати, JPOX змінив назву на DataNucleus (і з тих пір мав випуски).
Стипендіати доналу

2
Подумайте, ви дійсно виявите, що DataNucleus має набагато менш відкриті помилки, ніж інше програмне забезпечення, на яке ви звертаєтесь. Подумайте, ви також виявите, що розробка DataNucleus скорочує кількість помилок швидше, ніж це інше програмне забезпечення.
DataNucleus

1

Я зробив зразок WebApp у травні 2012 року, який використовує JDO 3.0 та DataNucleus 3.0 - подивіться, наскільки він чистий: https://github.com/TorbenVesterager/BadAssWebApp

Гаразд, можливо, це занадто чисто, тому що я використовую POJO як для бази даних, так і для клієнта JSON, але це весело :)

PS: Містить кілька приміток SuppressWarnings (розроблено в IntelliJ 11)

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