{"id":7613,"date":"2024-03-01T15:39:33","date_gmt":"2024-03-01T14:39:33","guid":{"rendered":"https:\/\/pomoc.comarch.pl\/cee\/640\/?post_type=ht_kb&#038;p=7613"},"modified":"2025-03-18T14:16:32","modified_gmt":"2025-03-18T13:16:32","slug":"podrecznik-programowania","status":"publish","type":"ht_kb","link":"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/","title":{"rendered":"Podr\u0119cznik programowania"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_82_2 ez-toc-wrap-left counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Spis tre\u015bci<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Prze\u0142\u0105cznik Spisu Tre\u015bci\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Wprowadzenie\" >Wprowadzenie<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Opis\" >Opis<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Grupa_docelowa\" >Grupa docelowa<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Skroty\" >Skr\u00f3ty<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Wymagania_wstepne\" >Wymagania wst\u0119pne<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Architektura_klientaserwera\" >Architektura klienta\/serwera<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Interfejs_uzytkownika\" >Interfejs u\u017cytkownika<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Logika_aplikacji\" >Logika aplikacji<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Przechowywanie_danych\" >Przechowywanie danych<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Komunikacja_z_baza_danych\" >Komunikacja z baz\u0105 danych<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Baza_danych_konfiguracji_systemu\" >Baza danych konfiguracji systemu<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Baza_danych_repozytorium\" >Baza danych repozytorium<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Baza_danych_Online_Transaction_Processing_OLTP\" >Baza danych Online Transaction Processing (OLTP)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Baza_danych_Online_Analytical_Processing_OLAP\" >Baza danych Online Analytical Processing (OLAP)<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Programowanie_w_Comarch_ERP_Enterprise\" >Programowanie w Comarch ERP Enterprise<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-16\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Zlecenie_deweloperskie\" >Zlecenie deweloperskie<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-17\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Zadanie_deweloperskie\" >Zadanie deweloperskie<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-18\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Podstawowy_proces_deweloperski\" >Podstawowy proces deweloperski<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-19\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Krok_1_Utworzenie_zlecenia_deweloperskiego_i_rozpoczecie_opracowania\" >Krok 1: Utworzenie zlecenia deweloperskiego i rozpocz\u0119cie opracowania<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-20\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Krok_2_Opracowanie\" >Krok 2: Opracowanie<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-21\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Krok_3_Zwolnienie_zadania_deweloperskiego\" >Krok 3: Zwolnienie zadania deweloperskiego<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-22\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Krok_4_Aktywacja_zadania_deweloperskiego\" >Krok 4: Aktywacja zadania deweloperskiego<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-23\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Krok_5_Testy_zlecenia_deweloperskiego\" >Krok 5: Testy zlecenia deweloperskiego<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-24\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Obiekty_deweloperskie\" >Obiekty deweloperskie<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-25\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Obszary_nazw\" >Obszary nazw<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-26\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Struktura_obszaru_nazw\" >Struktura obszaru nazw<\/a><\/li><\/ul><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-27\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Typy_obiektow_deweloperskich\" >Typy obiekt\u00f3w deweloperskich<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-28\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Akcja\" >Akcja<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-29\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Akcje_dla_przyciskow\" >Akcje dla przycisk\u00f3w<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-30\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Akcje_dla_przelacznikow\" >Akcje dla prze\u0142\u0105cznik\u00f3w<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-31\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Akcja_dla_zakladek\" >Akcja dla zak\u0142adek<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-32\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Akcja_dla_menu_kontekstowego\" >Akcja dla menu kontekstowego<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-33\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Szablony\" >Szablony<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-34\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Aplikacja\" >Aplikacja<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-35\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Aplikacja_dialogowa\" >Aplikacja dialogowa<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-36\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Aplikacja_w_tle\" >Aplikacja w tle<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-37\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Aktualizacja_danych_dialogu\" >Aktualizacja danych dialogu<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-38\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Automatyczna_aktualizacja_danych_w_tle\" >Automatyczna aktualizacja danych w tle<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-39\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Reczna_aktualizacja_danych_w_tle\" >R\u0119czna aktualizacja danych w tle<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-40\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Narzedzie\" >Narz\u0119dzie<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-41\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Raport\" >Raport<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-42\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Grupa_jednostek_biznesowych\" >Grupa jednostek biznesowych<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-43\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Obiekt_biznesowy\" >Obiekt biznesowy<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-44\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Atrybuty\" >Atrybuty<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-45\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Atrybuty_NSL\" >Atrybuty NSL<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-46\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Typy_obiektow_biznesowych\" >Typy obiekt\u00f3w biznesowych<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-47\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Generowane_klasy_Java\" >Generowane klasy Java<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-48\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Atrybuty_daty_i_znacznika_czasu\" >Atrybuty daty i znacznika czasu<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-49\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Zaleznosc_czasowa\" >Zale\u017cno\u015b\u0107 czasowa<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-50\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Data-Description-LDT_i_Data-Description-Column\" >Data-Description-LDT i Data-Description-Column<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-51\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Plik\" >Plik<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-52\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Zdarzenie\" >Zdarzenie<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-53\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Rozszerzenie\" >Rozszerzenie<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-54\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Obszar_Framework\" >Obszar (Framework)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-55\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Zdolnosc\" >Zdolno\u015b\u0107<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-56\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Funkcja\" >Funkcja<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-57\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Obiekt_pomocy\" >Obiekt pomocy<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-58\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Ikona_symbol\" >Ikona (symbol)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-59\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Klasa_Java\" >Klasa Java<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-60\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Klucz_licencyjne\" >Klucz licencyjne<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-61\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Logiczny_typ_danych\" >Logiczny typ danych<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-62\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Logiczny_typ_danych_typu_prymitywny\" >Logiczny typ danych typu prymitywny<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-63\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Logiczny_typ_danych_typu_logiczny\" >Logiczny typ danych typu logiczny<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-64\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Logiczny_typ_danych_typu_zlozony\" >Logiczny typ danych typu z\u0142o\u017cony<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-65\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Komunikat\" >Komunikat<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-66\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Klasa_komunikatu\" >Klasa komunikatu<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-67\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Obszar_nazw\" >Obszar nazw<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-68\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Wyszukiwanie_OQL\" >Wyszukiwanie OQL<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-69\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Widok_OQL\" >Widok OQL<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-70\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Czesc_Part\" >Cz\u0119\u015b\u0107 (Part)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-71\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Stringtable\" >Stringtable<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-72\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Termin\" >Termin<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-73\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Przebieg_testowy_Test_Run\" >Przebieg testowy (Test Run)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-74\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Tekst\" >Tekst<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-75\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Zestaw_wartosci_Valueset\" >Zestaw warto\u015bci (Valueset)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-76\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Wersje_obiektow_deweloperskich\" >Wersje obiekt\u00f3w deweloperskich<\/a><\/li><\/ul><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-77\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Usluga_trwalosci_danych\" >Us\u0142uga trwa\u0142o\u015bci danych<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-78\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Manager_transakcji\" >Manager transakcji<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-79\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Transakcje_systemu_ERP\" >Transakcje systemu ERP<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-80\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Widocznosc_zmian_w_zagniezdzonych_transakcjach\" >Widoczno\u015b\u0107 zmian w zagnie\u017cd\u017conych transakcjach<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-81\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Zarzadzanie_pamiecia_podreczna_Cache\" >Zarz\u0105dzanie pami\u0119ci\u0105 podr\u0119czn\u0105 (Cache)<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-82\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Shared_Cache\" >Shared Cache<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-83\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Transaction_Cache\" >Transaction Cache<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-84\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Manager_obiektow\" >Manager obiekt\u00f3w<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-85\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Metoda_getObject\" >Metoda getObject()<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-86\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Metoda_getObjectIterator\" >Metoda getObjectIterator()<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-87\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Metoda_getResultSet\" >Metoda getResultSet()<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-88\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Metoda_putObject\" >Metoda putObject()<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-89\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Metoda_deleteObject\" >Metoda deleteObject()<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-90\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Wspoldzialanie_managera_obiektow_i_pamieci_podrecznej\" >Wsp\u00f3\u0142dzia\u0142anie managera obiekt\u00f3w i pami\u0119ci podr\u0119cznej<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-91\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Update_Statements\" >Update Statements<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-92\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Tryb_dostepu\" >Tryb dost\u0119pu<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-93\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Jezyk_tresci_Content_Language\" >J\u0119zyk tre\u015bci (Content Language)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-94\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Informacje_o_modyfikacjach_%E2%80%9Especjalistyczne%E2%80%9D_usuwanie\" >Informacje o modyfikacjach \/ &#8222;specjalistyczne&#8221; usuwanie<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-95\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Zaleznosc_czasowa-2\" >Zale\u017cno\u015b\u0107 czasowa<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-96\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Tryb_Insert_Only\" >Tryb Insert Only<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-97\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Tryb_Update\" >Tryb Update<\/a><\/li><\/ul><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-98\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Zarzadzanie_blokadami\" >Zarz\u0105dzanie blokadami<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-99\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Praca_na_obiektach_biznesowych\" >Praca na obiektach biznesowych<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-100\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Aktualizacje_baz_danych\" >Aktualizacje baz danych<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-101\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Generowanie_obiektow_biznesowych\" >Generowanie obiekt\u00f3w biznesowych<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-102\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Etap_1_%E2%80%93_wygenerowanie_obiektu_biznesowego\" >Etap 1 &#8211; wygenerowanie obiektu biznesowego<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-103\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Etap_2_%E2%80%93_Klasy_Update\" >Etap 2 &#8211; Klasy Update<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-104\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Etap_3_%E2%80%93_Konwersja_obiektu_biznesowego\" >Etap 3 &#8211; Konwersja obiektu biznesowego<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-105\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Etap_4_%E2%80%93_Rozwoj_i_testy\" >Etap 4 &#8211; Rozw\u00f3j i testy<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-106\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Etap_5_%E2%80%93_Zwolnienie_zadania_deweloperskiego\" >Etap 5 &#8211; Zwolnienie zadania deweloperskiego<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-107\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Etap_6_%E2%80%93_Aktywacja_obiektu_biznesowego\" >Etap 6 &#8211; Aktywacja obiektu biznesowego<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-108\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Etap_7_%E2%80%93_Aktywacja_zadania_deweloperskiego\" >Etap 7 &#8211; Aktywacja zadania deweloperskiego<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-109\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Rozwoj_klas_Update\" >Rozw\u00f3j klas Update<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-110\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Aktualizacja_danych\" >Aktualizacja danych<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-111\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Dostep_odczytu_przez_managera_obiektow\" >Dost\u0119p odczytu przez managera obiekt\u00f3w<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-112\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Metoda_getObject-2\" >Metoda getObject()<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-113\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Metoda_getObjectArray\" >Metoda getObjectArray()<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-114\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Metody_getObjectList\" >Metody getObjectList()<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-115\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Metoda_getObjectIterator-2\" >Metoda getObjectIterator()<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-116\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Metoda_getResultSet-2\" >Metoda\u00a0getResultSet()<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-117\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Wytyczne_dotyczace_uzytkowania\" >Wytyczne dotycz\u0105ce u\u017cytkowania<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-118\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Wczytywanie_za_pomoca_relacji\" >Wczytywanie za pomoc\u0105 relacji<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-119\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Dostepy_zapisu_przez_managera_obiektow\" >Dost\u0119py zapisu przez managera obiekt\u00f3w<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-120\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Metody_putObject\" >Metody putObject()<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-121\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Metoda_deleteObject-2\" >Metoda deleteObject()<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-122\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Obsluga_bledow_transakcji\" >Obs\u0142uga b\u0142\u0119d\u00f3w transakcji<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-123\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Transakcja_odczytu_przez_begin\" >Transakcja odczytu przez begin<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-124\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Transakcja_odczytu_przez_create\" >Transakcja odczytu przez create<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-125\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Transakcja_zapisu_przez_begin\" >Transakcja zapisu przez begin<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-126\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Transakcja_zapisu_przez_create\" >Transakcja zapisu przez create<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-127\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Transakcja_zapisu_blokowego_przez_create\" >Transakcja zapisu blokowego przez create<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-128\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Trwale_i_przechodnie_obiekty_biznesowe\" >Trwa\u0142e i przechodnie obiekty biznesowe<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-129\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Blokady_logiczne\" >Blokady logiczne<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-130\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Blokowanie_optymistyczne\" >Blokowanie optymistyczne<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-131\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Blokowanie_pesymistyczne\" >Blokowanie pesymistyczne<\/a><\/li><\/ul><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-132\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Dynamiczny_OQL\" >Dynamiczny OQL<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-133\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Joins\" >Joins<\/a><ul class='ez-toc-list-level-6' ><li class='ez-toc-heading-level-6'><a class=\"ez-toc-link ez-toc-heading-134\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Inner_Join\" >Inner Join<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-6'><a class=\"ez-toc-link ez-toc-heading-135\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Left_Outer_Join\" >Left Outer Join<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-6'><a class=\"ez-toc-link ez-toc-heading-136\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Right_Outer_Join\" >Right Outer Join<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-6'><a class=\"ez-toc-link ez-toc-heading-137\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Full_Outer_Join\" >Full Outer Join<\/a><\/li><\/ul><\/li><\/ul><\/li><\/ul><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-138\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/podrecznik-programowania\/#Schematy_numeracji\" >Schematy numeracji<\/a><\/li><\/ul><\/nav><\/div>\n<h2 id=\"wprowadzenie\" ><span class=\"ez-toc-section\" id=\"Wprowadzenie\"><\/span>Wprowadzenie<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<h3 id=\"opis\" ><span class=\"ez-toc-section\" id=\"Opis\"><\/span>Opis<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Niniejszy dokument zawiera podstawowe poj\u0119cia i metody pracy wymagane podczas tworzenia aplikacji dialogowych w Comarch ERP Enterprise.<\/p>\n<section class=\"document-alert-box warning\"><div class=\"document-alert-title\">Uwaga<\/div><div class=\"document-alert-content\">W tej wersji dokumentu nadal mog\u0105 by\u0107 konieczne poprawki tre\u015bci. Dokument oczekuje na korekt\u0119 redakcyjn\u0105.<\/div><\/section>\n<h3 id=\"grupa-docelowa\" ><span class=\"ez-toc-section\" id=\"Grupa_docelowa\"><\/span>Grupa docelowa<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Grup\u0105 docelow\u0105 s\u0105 programi\u015bci ze znajomo\u015bci\u0105 j\u0119zyka Java, kt\u00f3rzy chc\u0105 zapozna\u0107 si\u0119 z procesem tworzenia aplikacji dialogowych i pozna\u0107 za\u0142o\u017cenia Comarch ERP Enterprise.<\/p>\n<h3 id=\"skroty\" ><span class=\"ez-toc-section\" id=\"Skroty\"><\/span>Skr\u00f3ty<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><strong>API<\/strong> Application Programming Interface<br \/>\n<strong>BO<\/strong> Business Object<br \/>\n<strong>BOD<\/strong> Business Object Definition<br \/>\n<strong>DB<\/strong> Baza danych<br \/>\n<strong>DHTML<\/strong> Dynamic HTML<br \/>\n<strong>GUI<\/strong> Graphical User Interface<br \/>\n<strong>GUID<\/strong> Global Unique IDentifier<br \/>\n<strong>HTML<\/strong> Hyper Text Markup Language<br \/>\n<strong>JDK<\/strong> Java Development Kit<br \/>\n<strong>JVM<\/strong> Java Virtual Machine<br \/>\n<strong>IDE<\/strong> Integrated Development Environment<br \/>\n<strong>MM<\/strong> Message Manager<br \/>\n<strong>NLS<\/strong> National Language Support<br \/>\n<strong>LDT<\/strong> Logiczny typ danych<br \/>\n<strong>OLTP<\/strong> Online Transaction Processing<br \/>\n<strong>OLAP<\/strong> Online Analytical Processing<br \/>\n<strong>OM<\/strong> Object Manager<br \/>\n<strong>OQL<\/strong> Object Query Language<br \/>\n<strong>SAS<\/strong> ERP System Application Server<br \/>\n<strong>SDK<\/strong> ERP System Development Kit<br \/>\n<strong>SOM<\/strong> ERP System Output Manager<br \/>\n<strong>SQL<\/strong> Structured Query Language<br \/>\n<strong>TM<\/strong> Transaction Manager<br \/>\n<strong>UI<\/strong> User Interface<br \/>\n<strong>URI<\/strong> Uniform Resource Identifier<br \/>\n<strong>URL<\/strong> Uniform Resource Locator<br \/>\n<strong>VE<\/strong> Visual Element<br \/>\n<strong>VEC<\/strong> Visual Element Container<\/p>\n<h3 id=\"wymagania-wstepne\" ><span class=\"ez-toc-section\" id=\"Wymagania_wstepne\"><\/span>Wymagania wst\u0119pne<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Na potrzeby prezentacji wymagany jest system Comarch ERP Enterprise i skonfigurowane \u015brodowisko programistyczne (Eclipse).<\/p>\n<h2 id=\"architektura-klienta-serwera\" ><span class=\"ez-toc-section\" id=\"Architektura_klientaserwera\"><\/span>Architektura klienta\/serwera<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>System ERP zosta\u0142 opracowany zgodnie z 3-warstwow\u0105 architektur\u0105 i zasadniczo sk\u0142ada si\u0119 z nast\u0119puj\u0105cych trzech warstw. W nawiasach podano realizuj\u0105cy komponent oprogramowania:<\/p>\n<ul>\n<li>graficzny interfejs u\u017cytkownika (przegl\u0105darka)<\/li>\n<li>logika aplikacji (serwer aplikacji systemu ERP)<\/li>\n<li>przechowywanie danych (system zarz\u0105dzania baz\u0105 danych)<\/li>\n<\/ul>\n<p>Taki podzia\u0142 zapewnia optymalne opcje konfigurowania i skalowania, poniewa\u017c warstwy s\u0105 od siebie niezale\u017cne. Graficzny interfejs u\u017cytkownika definiuje interfejsy dla interakcji u\u017cytkownika. Logika aplikacji stanowi po\u0142\u0105czenie graficznego interfejsu u\u017cytkownika z przechowywaniem danych. Platform\u0105 wykonawcz\u0105 jest serwer aplikacji systemu ERP (SAS), kt\u00f3ry wymaga wirtualnej maszyny Java (JVM). Dzi\u0119ki oddzieleniu warstw, r\u00f3\u017cne zrealizowane interfejsy u\u017cytkownika mog\u0105 korzysta\u0107 z tej samej logiki aplikacji dla tych samych funkcji aplikacji.<\/p>\n<h3 id=\"interfejs-uzytkownika\" ><span class=\"ez-toc-section\" id=\"Interfejs_uzytkownika\"><\/span>Interfejs u\u017cytkownika<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>System ERP posiada graficzny <em>interfejs <\/em>u\u017cytkownika (Graphical User Interface, w skr\u00f3cie GUI), kt\u00f3ry mo\u017ce by\u0107 wy\u015bwietlany po stronie klienta w przegl\u0105darce Internet Explorer. U\u017cytkownik mo\u017ce porusza\u0107 si\u0119 zar\u00f3wno po intranecie, jak i Internecie, poniewa\u017c uzyskuje dost\u0119p do systemu ERP za pomoc\u0105 swojego klienta poprzez po\u0142\u0105czenie TCP\/IP.<\/p>\n<h3 id=\"logika-aplikacji\" ><span class=\"ez-toc-section\" id=\"Logika_aplikacji\"><\/span>Logika aplikacji<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Logika aplikacji tworzy warstw\u0119 \u015brodkow\u0105 w architekturze 3-warstwowej. To tutaj znajduj\u0105 si\u0119 wszelkie aplikacje biznesowe. Serwer aplikacji systemu ERP (SAS) korzysta z r\u00f3\u017cnych us\u0142ug systemowych silnika systemu, takich jak:<\/p>\n<ul>\n<li>Zarz\u0105dzanie pami\u0119ci\u0105 podr\u0119czn\u0105<\/li>\n<li>Obs\u0142uga transakcji<\/li>\n<li>Obs\u0142uga ci\u0105g\u0142o\u015bci<\/li>\n<li>Obs\u0142uga zdarze\u0144<\/li>\n<li>Us\u0142uga licencyjna<\/li>\n<li>Przetwarzanie w tle<\/li>\n<li>Dziennik zmian<\/li>\n<li>Us\u0142uga blokowania<\/li>\n<li>Zlecenia wydania<\/li>\n<li>Web Server<\/li>\n<\/ul>\n<p>Klienci komunikuj\u0105 si\u0119 z SAS za pomoc\u0105 protoko\u0142u HTTP\/HTTP za po\u015brednictwem serwera WWW dostosowanego do wymaga\u0144 systemu ERP. \u00a0Liczba SAS w ramach systemu ERP zale\u017cy od struktury organizacyjnej firmy i liczby u\u017cytkownik\u00f3w.<\/p>\n<p>Ka\u017cdy u\u017cytkownik wymaga okre\u015blonej przestrzeni dyskowej w SAS, np. dla danych aplikacji itp. Zasoby dost\u0119pne dla ka\u017cdego SAS s\u0105 ograniczone, co skutkuje odpowiednim g\u00f3rnym limitem liczby u\u017cytkownik\u00f3w na SAS. Procesy wymagaj\u0105ce du\u017cej mocy obliczeniowej, np. ODBC, serwer logistyki magazynowej, r\u00f3wnie\u017c powinny by\u0107 obs\u0142ugiwane w oddzielnym SAS.<\/p>\n<p>Ka\u017cdy u\u017cytkownik wymaga okre\u015blonej przestrzeni dyskowej w SAS, np. dla danych aplikacji itp. Zasoby dost\u0119pne dla ka\u017cdego SAS s\u0105 ograniczone, co skutkuje odpowiednim g\u00f3rnym limitem liczby u\u017cytkownik\u00f3w na SAS. Procesy wymagaj\u0105ce du\u017cej mocy obliczeniowej, np. ODBC, serwer logistyki magazynowej, r\u00f3wnie\u017c powinny by\u0107 obs\u0142ugiwane w oddzielnym SAS.<\/p>\n<p>Innym powodem podzia\u0142u na kilka SAS jest garbage collector dla JVM. Ka\u017cdy SAS ma w\u0142asne JVM. W okre\u015blonych odst\u0119pach czasu garbage collector usuwa niepotrzebne obiekty. Dzi\u0119ki temu zwalnia si\u0119 pami\u0119\u0107 na potrzeby innych proces\u00f3w. Nowoczesne garbage collectory wykonuj\u0105 to zadanie r\u00f3wnolegle z innymi uruchomionymi procesami. W pewnych sytuacjach, np. gdy ko\u0144czy si\u0119 miejsce w pami\u0119ci, inne procesy s\u0105 zatrzymywane, aby garbage collector mia\u0142 wystarczaj\u0105co du\u017co czasu na zwolnienie miejsca w pami\u0119ci. Zamiast jednego du\u017cego SAS, lepiej jest pracowa\u0107 na kilku mniejszych SAS. Poniewa\u017c pami\u0119\u0107 ka\u017cdego SAS jest mniejsza, garbage collector potrzebuje r\u00f3wnie\u017c mniej czasu na ka\u017cdy SAS. Logika aplikacji dzia\u0142a w okre\u015blonym \u015brodowisku. Wa\u017cnymi terminami w tym kontek\u015bcie s\u0105 <em>session<\/em>, <em>thread<\/em> i <em>transaction<\/em>.<\/p>\n<p><em>Session (sesja)<\/em><\/p>\n<p>Sesje to oddzielne obszary robocze, z kt\u00f3rych ka\u017cdy zawiera zestaw obiekt\u00f3w. Sesja reprezentuje korze\u0144 grafu obiekt\u00f3w i definiuje kontekst wszystkich dzia\u0142a\u0144 w systemie ERP. Rozr\u00f3\u017cnia si\u0119 sesje interaktywne i sesje nieinteraktywne. Sesje interaktywne zawieraj\u0105 informacje o aktywnych aplikacjach w przegl\u0105darce, uwierzytelnianiu u\u017cytkownika i wszystkich powi\u0105zanych zasobach. Zasadniczo sesja mo\u017ce pomie\u015bci\u0107 dowoln\u0105 liczb\u0119 instancji aplikacji. Sesje nieinteraktywne rozpoczynaj\u0105 si\u0119 wraz z uruchomieniem us\u0142ugi lub zlecenia przetwarzania. Sesje ko\u0144cz\u0105 si\u0119 wylogowaniem u\u017cytkownika lub w wyniku b\u0142\u0119du po\u0142\u0105czenia po przekroczeniu limitu czasu. Wszystkie zaj\u0119te zasoby, takie jak pami\u0119\u0107 i blokady, s\u0105 ponownie zwalniane najp\u00f3\u017aniej w momencie zako\u0144czenia sesji.<\/p>\n<p><em>Thread (w\u0105tek)<\/em><\/p>\n<p>W\u0105tek jest wymagany do opracowania dzia\u0142a\u0144 lub zg\u0142osze\u0144 uruchamianych w ramach sesji. W\u0105tki s\u0105 r\u00f3wnoleg\u0142ymi jednostkami wykonawczymi, kt\u00f3re s\u0105 przypisane do sesji na czas opracowania zg\u0142oszenia. Sesja przekazuje do w\u0105tku to, co ma zosta\u0107 opracowane. W\u0105tek przejmuje opracowanie i zwraca wynik. Oznacza to, \u017ce w\u0105tek jest wymagany dla sesji tylko podczas aktywnego opracowania. Aby skutecznie rozdziela\u0107 ograniczone zasoby, stopniowo budowana jest pula w\u0105tk\u00f3w. W razie potrzeby z tej puli mo\u017cna przypisa\u0107 do jednej sesji kilka w\u0105tk\u00f3w.<\/p>\n<p>Z perspektywy dewelopera aplikacji zawsze tylko jeden w\u0105tek jest aktywny. Oznacza to, \u017ce deweloper nie musi si\u0119 zajmowa\u0107 synchronizacj\u0105 w\u0105tk\u00f3w. W\u0105tki maj\u0105 przypisane priorytety realizacji, np. mo\u017cna ustawi\u0107 wy\u017cszy priorytet dla przetwarzania dialogu i ni\u017cszy priorytet dla przetwarzania w tle. W\u0105tek wraz z przyporz\u0105dkowan\u0105 sesj\u0105 stanowi\u0105<br \/>\n\u015brodowisko pracy, w kt\u00f3rym np. uruchamiane s\u0105 transakcje i zg\u0142aszane blokady.<br \/>\nW\u0105tki s\u0105 udost\u0119pniane przez maszyn\u0119 wirtualn\u0105 JAVA\u2122, kt\u00f3ra w razie potrzeby rozdziela w\u0105tki do wielu procesor\u00f3w.<\/p>\n<p><em>Transaction (transakcja)<\/em><\/p>\n<p>Sesja mo\u017ce zawiera\u0107 kilka tzw. transakcji Toplevel. Transakcja zazwyczaj zawiera sekwencj\u0119 operacji na instancjach obiekt\u00f3w biznesowych. Transakcja jest u\u017cywana do utworzenia jednostki. Jednostka ta jest realizowana w ca\u0142o\u015bci lub uniewa\u017cniania, w celu przywr\u00f3cenia zmienionych danych do sp\u00f3jnego stanu. System ERP posiada<br \/>\nw\u0142asny mechanizm zarz\u0105dzania transakcjami, kt\u00f3ry obs\u0142uguje zagnie\u017cd\u017cone transakcje.<\/p>\n<p>Po rozpocz\u0119ciu sesji w bazie danych OLTP automatycznie otwierana jest transakcja (transakcja dummy), aby umo\u017cliwi\u0107 deweloperowi aplikacji dost\u0119p do odczytu instancji obiekt\u00f3w biznesowych. Modyfikacja instancji musi odbywa\u0107 si\u0119 w ramach nowej transakcji, kt\u00f3ra jest otwierana za pomoc\u0105 mened\u017cera transakcji. Aby uzyska\u0107 dost\u0119p do instancji obiekt\u00f3w biznesowych w transakcji, deweloper aplikacji mo\u017ce u\u017cy\u0107 Object Manager lub Object Query Language (OQL).<\/p>\n<p>Podczas modyfikacji instancji obiektu biznesowego system ERP blokuje automatycznie ten obiekt. Dzi\u0119ki temu nie jest mo\u017cliwa modyfikacja tego samego obiektu biznesowego przez inne transakcje.<\/p>\n<p>Do komunikacji z baz\u0105 danych wykorzystywana jest pula po\u0142\u0105cze\u0144 z baz\u0105 danych. W celu przes\u0142ania danych wymagane jest uzyskanie po\u0142\u0105czenia z tej puli po\u0142\u0105cze\u0144 i otwarcie transakcji bazy danych. Dopiero po pomy\u015blnym potwierdzeniu transakcji bazy danych przez <em>commit<\/em> lub po anulowaniu przez <em>rollback<\/em> transakcja Toplevel b\u0119dzie rzeczywi\u015bcie zako\u0144czona w systemie ERP. Oznacza to, \u017ce blokady na obiektach biznesowych s\u0105 zwalniane dopiero wtedy, gdy transakcja Toplevel b\u0119dzie ponownie zwolniona.<\/p>\n<p><em>Obs\u0142uga zasob\u00f3w<\/em><\/p>\n<p>Skalowalno\u015b\u0107 i wydajno\u015b\u0107 systemu klient-serwer zale\u017c\u0105 od tego, w jaki spos\u00f3b obs\u0142ugiwane s\u0105 ograniczone lub kosztowne zasoby. Podstawowe zasady s\u0105 dwie:<\/p>\n<ul>\n<li>wsp\u00f3lne, naprzemienne korzystanie z ograniczonych zasob\u00f3w<\/li>\n<li>pooling kosztownych zasob\u00f3w<\/li>\n<\/ul>\n<p>Serwer sieci web u\u017cywa puli w\u0105tk\u00f3w do przetwarzania przychodz\u0105cych zg\u0142osze\u0144 ze sta\u0142\u0105 liczb\u0105 w\u0105tk\u00f3w. Umo\u017cliwia to<br \/>\nr\u00f3wnomierne roz\u0142o\u017cenie obci\u0105\u017cenia na serwerze aplikacji systemu ERP i unikni\u0119cie generowania kosztownego zasobu. Na tej samej zasadzie zapytania sesji do bazy danych rozdzielane s\u0105 na sta\u0142\u0105 liczb\u0119 po\u0142\u0105cze\u0144 z baz\u0105 danych. Oznacza to redukcj\u0119 koszt\u00f3w (overhead) zwi\u0105zanych z \u017c\u0105daniem po\u0142\u0105czenia z baz\u0105 danych.<\/p>\n<h3 id=\"przechowywanie-danych\" ><span class=\"ez-toc-section\" id=\"Przechowywanie_danych\"><\/span>Przechowywanie danych<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Trzecia warstwa obejmuje przechowywanie danych w relacyjnych bazach danych. Obs\u0142ugiwane s\u0105 systemy zarz\u0105dzania bazami danych (DBMS) Oracle\u00ae, MS-SQL-Server i DB2\/AS400\u00ae.<br \/>\nW celu wydajnego przechowywania danych stosowany jest nast\u0119puj\u0105cy spos\u00f3b partycjonowania:<\/p>\n<ul>\n<li>Baza danych konfiguracji systemu<\/li>\n<li>Baza danych repozytorium<\/li>\n<li>Baza danych Online Transaction Profession (OLTP)<\/li>\n<li>Baza danych Online Analytical Processing (OLAP)<\/li>\n<\/ul>\n<p>Ten uk\u0142ad bazy danych daje mo\u017cliwo\u015b\u0107 rozdzielenia okre\u015blonych zestaw\u00f3w danych do r\u00f3\u017cnych system\u00f3w zarz\u0105dzania bazami, co zapewnia odpowiedni\u0105 elastyczno\u015b\u0107 i skalowalno\u015b\u0107.<\/p>\n<p>Zwi\u0119kszenie wydajno\u015bci wynika z zarz\u0105dzania podobnymi zestawami danych w poszczeg\u00f3lnych bazach danych. Wida\u0107 to ju\u017c po podobnym przebiegu zmian w poszczeg\u00f3lnych bazach danych: zestawy danych w bazie danych repozytorium prawie nigdy nie s\u0105 zmieniane w czasie dzia\u0142ania systemu, podczas gdy te w bazie danych OLTP s\u0105 zmieniane na bie\u017c\u0105co.<\/p>\n<p>Podczas rozwoju systemu ERP skupiono si\u0119 na szybkim dost\u0119pie do danych z baz danych w celu uzyskania kr\u00f3tkich czas\u00f3w reakcji. Dlatego system ERP wykorzystuje tylko niezb\u0119dne mechanizmy relacyjnych system\u00f3w zarz\u0105dzania bazami danych. Obejmuj\u0105 one wydajne trwa\u0142e przechowywanie danych i zoptymalizowane wykonywanie zapyta\u0144.<br \/>\n\u015awiadomie zrezygnowano z trigerr\u00f3w producenta, referencyjnej i semantycznej integralno\u015bci<br \/>\nczy \u201estored procedures\u201c, r\u00f3wnie\u017c z uwagi na kompatybilno\u015b\u0107. Szybki dost\u0119p jest realizowany g\u0142\u00f3wnie poprzez oddzielny system zarz\u0105dzania pami\u0119ci\u0105 podr\u0119czn\u0105, kt\u00f3remu podlegaj\u0105 wszystkie bazy danych. Minimalizuje to liczb\u0119 dost\u0119p\u00f3w do bazy danych i zwi\u0119ksza og\u00f3ln\u0105 przepustowo\u015b\u0107 danych.<\/p>\n<h3 id=\"komunikacja-z-baza-danych\" ><span class=\"ez-toc-section\" id=\"Komunikacja_z_baza_danych\"><\/span>Komunikacja z baz\u0105 danych<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Producenci u\u017cywaj\u0105 r\u00f3\u017cnych interfejs\u00f3w lub r\u00f3\u017cnych dialekt\u00f3w SQL do komunikacji z bazami danych. Aby ustandaryzowa\u0107 t\u0119 komunikacj\u0119, zaimplementowano Object Query Language (OQL) oparty na koncepcjach obiektowych i relacyjnych. OQL bazuje na standardzie SQL. Przy por\u00f3wnywalnym zakresie funkcji jak w SQL, OQL jest obs\u0142ugiwany przez wszystkie wymienione systemy zarz\u0105dzania bazami danych. Z perspektywy programisty aplikacji dialekty SQL nie maja znaczenia.<\/p>\n<p>J\u0119zyk zapyta\u0144 OQL jest zintegrowany z systemem ERP. Podczas t\u0142umaczenia<br \/>\nspecyficzne nazwy systemu ERP s\u0105 konwertowane na techniczne nazwy baz danych zgodnie z nazewnictwem obszaru nazw (namespace). Pozwala to na tworzenie unikalnych odniesie\u0144 do obiekt\u00f3w i eliminuje wyst\u0119powanie konflikt\u00f3w nazw w systemie.<\/p>\n<p>Object Manager zapewnia deweloperowi aplikacji prosty spos\u00f3b dost\u0119pu do danych. Umo\u017cliwia on wykonywanie na obiektach biznesowych poszczeg\u00f3lnych operacji odczytu, wstawiania, zmiany i usuwania danych. W tym kontek\u015bcie programista mo\u017ce r\u00f3wnie\u017c u\u017cywa\u0107 instrukcji OQL, w celu jednoczesnego przetwarzania wielu instancji obiekt\u00f3w biznesowych.<\/p>\n<p>OQL i Object Manager tworz\u0105 dla programisty aplikacji interfejs do baz danych. Stosuj\u0105 niezale\u017cny od platformy protok\u00f3\u0142 JDBC\u21223. R\u00f3\u017cne sterowniki JDBC\u2122 s\u0105 zwykle dostarczane z dodatkowymi parametrami specyficznymi dla producenta, kt\u00f3re s\u0105 u\u017cywane przez system ERP w celu wykorzystania specjalnych funkcji system\u00f3w zarz\u0105dzania bazami danych i wykorzystania ich potencja\u0142u wydajno\u015bci.<\/p>\n<h3 id=\"baza-danych-konfiguracji-systemu\" ><span class=\"ez-toc-section\" id=\"Baza_danych_konfiguracji_systemu\"><\/span>Baza danych konfiguracji systemu<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>System ERP mo\u017ce by\u0107 rozmieszczony na r\u00f3\u017cnych komputerach. Dlatego centralnie, w bazie danych konfiguracji systemu przechowywane s\u0105 obiekty niezb\u0119dne do konfiguracji systemu. Obiekty konfiguracyjne wp\u0142ywaj\u0105 na \u015brodowisko wykonawcze i obejmuj\u0105 wszystkie dane zintegrowanych zasob\u00f3w, a tak\u017ce dane uwierzytelniaj\u0105ce u\u017cytkownik\u00f3w. W odpowiednich aplikacjach dialogowych mo\u017cna konfigurowa\u0107 zar\u00f3wno poszczeg\u00f3lne systemy, jak i rodziny system\u00f3w.<\/p>\n<h3 id=\"baza-danych-repozytorium\" ><span class=\"ez-toc-section\" id=\"Baza_danych_repozytorium\"><\/span>Baza danych repozytorium<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Wszystkie obiekty deweloperskie s\u0105 przechowywane w bazie danych repozytorium. Opisuj\u0105 one lub definiuj\u0105 system ERP. W \u015brodowisku produkcyjnym dost\u0119p do obiekt\u00f3w deweloperskich jest mo\u017cliwy tylko w trybie odczytu.<br \/>\nDane te s\u0105 zmieniane tylko w fazie rozwoju i poprzez instalacj\u0119 aktualizacji oprogramowania. Wszystkie obiekty deweloperskie podlegaj\u0105 ci\u0105g\u0142emu wersjonowaniu i s\u0105 zarz\u0105dzane w obszarach nazw systemu ERP, kt\u00f3re maj\u0105 tak\u0105 sam\u0105 struktur\u0119 jak obszary nazw JAVA\u2122.<\/p>\n<p>Data Dictionary systemu ERP jest r\u00f3wnie\u017c przechowywany w bazie danych repozytorium. Opisuje on schemat bazy danych systemu ERP przy u\u017cyciu systemu typ\u00f3w odniesie\u0144 do obiekt\u00f3w. System typ\u00f3w jest niezale\u017cny od platform baz danych. Data Dictionary stanowi podstaw\u0119 mapowania statycznego, kt\u00f3re odwzorowuje zawarto\u015b\u0107 relacyjnych baz w obiektowym \u015brodowisku wykonawczym.<\/p>\n<div class=\"wp-menu-arrow\">\n<div>Baza danych repozytorium jest centraln\u0105 lokalizacj\u0105 instalacji, aktywacji i dystrybucji aktualizacji oprogramowania. Oznacza to, \u017ce rozszerzenia i modyfikacje systemu ERP mog\u0105 by\u0107 obs\u0142ugiwane centralnie, a nie oddzielnie dla poszczeg\u00f3lnych baz danych i komputer\u00f3w.<\/div>\n<div><\/div>\n<div>Opr\u00f3cz obiekt\u00f3w deweloperskich w bazie danych repozytorium przechowywane s\u0105 r\u00f3wnie\u017c inne dane. To tutaj znajduje si\u0119 dziennik, kt\u00f3ry przechowuje informacje o zdarzeniach systemowych. Ponadto dost\u0119pne s\u0105 definicje uprawnie\u0144 dla ca\u0142ego systemu lub dla konkretnych baz danych OLTP. Baza danych repozytorium pe\u0142ni rol\u0119 centralnej bazy danych systemu.<\/div>\n<div><\/div>\n<\/div>\n<h3 id=\"baza-danych-online-transaction-processing-oltp\" ><span class=\"ez-toc-section\" id=\"Baza_danych_Online_Transaction_Processing_OLTP\"><\/span>Baza danych Online Transaction Processing (OLTP)<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>W bazie danych Online Transaction Processing (OLTP) administrowane s\u0105 dane podstawowe i transakcyjne dla<br \/>\naplikacji biznesowych.\u00a0 Baza danych OLTP jest najbardziej wykorzystywana przez u\u017cytkownik\u00f3w w systemie produkcyjnym. Dane mog\u0105 by\u0107 r\u00f3wnie\u017c utrzymywane oddzielnie przez wiele baz danych OLTP<br \/>\n(mandant), co mo\u017ce by\u0107 konieczne w przypadku oddzielnych prawnych podmiot\u00f3w biznesowych.<\/p>\n<h3 id=\"baza-danych-online-analytical-processing-olap\" ><span class=\"ez-toc-section\" id=\"Baza_danych_Online_Analytical_Processing_OLAP\"><\/span>Baza danych Online Analytical Processing (OLAP)<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Baza danych Online Analytical Processing (OLAP) s\u0142u\u017cy do analizy danych biznesowych podobnie jak w innych rozwi\u0105zaniach hurtowni danych. Do cel\u00f3w statystycznych odpowiednie dane podstawowe i transakcyjne s\u0105 pobierane z bazy danych OLTP i zapisywane w bazie danych OLAP zgodnie z &#8222;star schema&#8221;. Umo\u017cliwia to zapytania obejmuj\u0105ce wyb\u00f3r, podsumowanie lub agregacj\u0119 i grupowanie du\u017cych ilo\u015bci danych.<\/p>\n<h2 id=\"programowanie-w-comarch-erp-enterprise\" ><span class=\"ez-toc-section\" id=\"Programowanie_w_Comarch_ERP_Enterprise\"><\/span>Programowanie w Comarch ERP Enterprise<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Do rozwoju aplikacji w systemie ERP dost\u0119pne s\u0105: ERP System Development Kit ( SDK) oraz Application Development<br \/>\nKit (ADK). Obok odpowiedniej wiedzy technicznej wymagane jest \u015brodowisko IDE Java\u2122 z Compiler, Editor i Debugger. Jako IDE zalecane jest Eclipse w wersji 3.7 lub wy\u017cszej. IDE musi obs\u0142ugiwa\u0107 Jav\u0119 co najmniej w wersji 7 jako \u015brodowisko deweloperskie JDK. Spos\u00f3b przygotowania \u015brodowiska programistycznego opisano w dokumentacji <em>Utworzenie \u015brodowisk programistycznych.<\/em><\/p>\n<p>Klasy s\u0105 uporz\u0105dkowane w pakietach, kt\u00f3rych podzia\u0142 jest oparty na obszarach (frameworks) systemu ERP. Development Kits zawieraj\u0105 dodatkowe narz\u0119dzia zintegrowane z systemem. Nale\u017c\u0105 do nich:<\/p>\n<ul>\n<li>narz\u0119dzia administracyjne do realizacji i obs\u0142ugi zlece\u0144 i zada\u0144 deweloperskich<\/li>\n<li>aplikacja <em>Obiekty deweloperskie<\/em> do definiowania i rozszerzania obiekt\u00f3w deweloperskich, takich jak obiekty biznesowe, wyszukiwania QOL, widoki OQL, komunikaty itp.<\/li>\n<li>narz\u0119dzia do zarz\u0105dzania baz\u0105 danych (tworzenie, kopiowanie i obs\u0142uga)<br \/>\nadministrowanie)<\/li>\n<li>narz\u0119dzia do importu i eksportu danych<\/li>\n<li>narz\u0119dzia do zarz\u0105dzania aktualizacjami oprogramowania<\/li>\n<\/ul>\n<p>Aby m\u00f3c programowa\u0107 z Comarch ERP Enterprise deweloper musi musi wiedzie\u0107, czym jest zlecenie deweloperskie, zadanie deweloperskie i obiekt deweloperski oraz w jaki spos\u00f3b te trzy elementy s\u0105 ze sob\u0105 powi\u0105zane.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-7642 size-full\" src=\"https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2024\/01\/Programowanie-z-Comarch-ERP-Enterprise.png\" alt=\"\" width=\"643\" height=\"138\" srcset=\"https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/Programowanie-z-Comarch-ERP-Enterprise.png 643w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/Programowanie-z-Comarch-ERP-Enterprise-300x64.png 300w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/Programowanie-z-Comarch-ERP-Enterprise-50x11.png 50w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/Programowanie-z-Comarch-ERP-Enterprise-600x129.png 600w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/Programowanie-z-Comarch-ERP-Enterprise-320x69.png 320w\" sizes=\"auto, (max-width: 643px) 100vw, 643px\" \/><\/p>\n<p>Zlecenie deweloperskie zawiera opis tego, co nale\u017cy wykona\u0107. Mo\u017ce to by\u0107 nowe opracowanie, albo te\u017c korekta b\u0142\u0119du.<br \/>\nOpracowanie zlecenia deweloperskiego odbywa si\u0119 w jednym lub kilku zadaniach deweloperskich.<\/p>\n<p>Obiekty deweloperskie s\u0105 podstawow\u0105 jednostk\u0105 w programowaniu aplikacji. Obiekty deweloperskie to metadane, kt\u00f3re klasyfikuj\u0105 okre\u015blone warto\u015bci i opisuj\u0105 ich w\u0142a\u015bciwo\u015bci. Stanowi\u0105 one warto\u015bci funkcjonalne i techniczne w systemie ERP. Istniej\u0105 r\u00f3\u017cne typy obiekt\u00f3w deweloperskich.<\/p>\n<p>Obiekty deweloperskie podlegaj\u0105 wersjonowaniu, tzn. po zmianie jednego obiektu powstaje nowa wersja, a wcze\u015bniejsze wersje s\u0105 archiwizowane.<\/p>\n<p>W ramach jednego zadania deweloperskiego mo\u017cna opracowywa\u0107 wiele obiekt\u00f3w deweloperskich jako jednostk\u0119.<\/p>\n<h3 id=\"zlecenie-deweloperskie\" ><span class=\"ez-toc-section\" id=\"Zlecenie_deweloperskie\"><\/span>Zlecenie deweloperskie<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Zlecenie deweloperskie jest narz\u0119dziem wspieraj\u0105cym dewelopera podczas programowania w systemie ERP. Zlecenie dokumentuje post\u0119p w trakcie ca\u0142ego procesu opracowania. Zazwyczaj w zlecenie deweloperskie zaanga\u017cowanych jest czterech u\u017cytkownik\u00f3w: <em>Creator, Coordinator, Programmer<\/em> oraz <em>Tester<\/em>.<br \/>\nU\u017cytkownik tworzy zlecenie deweloperskie. Mo\u017ce to by\u0107 np. pracownik dzia\u0142u wsparcie klienta. Podczas rejestracji zlecenia deweloperskiego okre\u015blana jest osoba, kt\u00f3ra ma zaj\u0105\u0107 si\u0119 realizacj\u0105 danego zlecenia, czyli koordynacj\u0105 dalszych dzia\u0142a\u0144. Koordynator decyduje, kto b\u0119dzie programist\u0105 oraz kto przeprowadzi oba testy.<\/p>\n<p>Zlecenie deweloperskie zawsze posiada aktualnego u\u017cytkownika obs\u0142uguj\u0105cego <em>Editor<\/em>. Jest on okre\u015blany na podstawie statusu zlecenia. Poni\u017csza tabela zawiera list\u0119 dost\u0119pnych status\u00f3w i wynikaj\u0105cych z nich <em>Editors<\/em>.<\/p>\n<table style=\"border-collapse: collapse; width: 0%; height: 446px;\">\n<tbody>\n<tr style=\"height: 25px;\">\n<td style=\"width: 50%; height: 25px;\"><strong>Status<\/strong><\/td>\n<td style=\"width: 125.661%; height: 25px;\"><strong>Editor<\/strong><\/td>\n<\/tr>\n<tr style=\"height: 25px;\">\n<td style=\"width: 50%; height: 25px;\">Created<\/td>\n<td style=\"width: 125.661%; height: 25px;\"><em>Coordinator<\/em><\/td>\n<\/tr>\n<tr style=\"height: 25px;\">\n<td style=\"width: 50%; height: 25px;\">Classified<\/td>\n<td style=\"width: 125.661%; height: 25px;\"><em>Programmer<\/em><\/td>\n<\/tr>\n<tr style=\"height: 25px;\">\n<td style=\"width: 50%; height: 25px;\">In progress<\/td>\n<td style=\"width: 125.661%; height: 25px;\"><em>Programmer<\/em><\/td>\n<\/tr>\n<tr style=\"height: 25px;\">\n<td style=\"width: 50%; height: 25px;\">Implemented<\/td>\n<td style=\"width: 125.661%; height: 25px;\"><em>Tester<\/em><\/td>\n<\/tr>\n<tr style=\"height: 25px;\">\n<td style=\"width: 50%; height: 25px;\">Initial test<\/td>\n<td style=\"width: 125.661%; height: 25px;\"><em>Tester<\/em><\/td>\n<\/tr>\n<tr style=\"height: 25px;\">\n<td style=\"width: 50%; height: 25px;\">Initial test completed<\/td>\n<td style=\"width: 125.661%; height: 25px;\"><em>Tester<\/em><\/td>\n<\/tr>\n<tr style=\"height: 25px;\">\n<td style=\"width: 50%; height: 25px;\">In second test<\/td>\n<td style=\"width: 125.661%; height: 25px;\"><em>Tester<\/em><\/td>\n<\/tr>\n<tr style=\"height: 25px;\">\n<td style=\"width: 50%; height: 25px;\">Completed<\/td>\n<td style=\"width: 125.661%; height: 25px;\"><em>Coordinator<\/em><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 50%;\">Closed<\/td>\n<td style=\"width: 125.661%;\"><em>Coordinator<\/em><\/td>\n<\/tr>\n<tr style=\"height: 25px;\">\n<td style=\"width: 50%; height: 25px;\">Completed without changes<\/td>\n<td style=\"width: 125.661%; height: 25px;\"><em>Coordinator<\/em><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 50%;\">Consultation<\/td>\n<td style=\"width: 125.661%;\">Dowolny u\u017cytkownik<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 50%;\">Postponed<\/td>\n<td style=\"width: 125.661%;\"><em>Coordinator<\/em><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Opracowywanie przebiega zwykle od statusu <em>Created<\/em> do <em>Closed<\/em> w podanej powy\u017cej kolejno\u015bci.<\/p>\n<p>Status <em>Completed without changes<\/em> ustawia si\u0119, je\u015bli zlecenie nie zosta\u0142o opracowane lub nie by\u0142y konieczne \u017cadne zmiany.<br \/>\nJe\u015bli wymagane s\u0105 szczeg\u00f3\u0142owe informacje, mo\u017cna ustawi\u0107 status <em>Consultation<\/em>. W tym miejscu mo\u017cna wprowadzi\u0107 dowolnego u\u017cytkownika odpowiedzialnego za dostarczenie wymaganych informacji.<br \/>\nJe\u015bli opracowanie zostanie przerwane na d\u0142u\u017cszy czas, mo\u017cna ustawi\u0107 status <em>Postponed<\/em>.<\/p>\n<p>Wszystkie informacje, etapy pracy itp. mog\u0105 by\u0107 udokumentowane w zleceniu poprzez<br \/>\nteksty i za\u0142\u0105czniki. Teksty s\u0105 ustandaryzowane i zale\u017cne od statusu i u\u017cytkownika, np. tester mo\u017ce utworzy\u0107 w zleceniu ze statusem <em>Initial test <\/em>tekst typu <em>Comment, <\/em>kt\u00f3ry opisuje przebieg testu.<br \/>\nWa\u017cnym tekstem jest tekst do paczek instalacyjnych &#8211; S<em>upport Delivery Text<\/em>. Opisuje, jaki problem zosta\u0142 usuni\u0119ty lub jakie przeprowadzono modyfikacje. Ten tekst mo\u017ce by\u0107 opublikowany p\u00f3\u017aniej i powinien by\u0107 odpowiednio napisany.<\/p>\n<p>Zlecenie deweloperskie podczas tworzenia otrzymuje unikalny kod. Sk\u0142ada si\u0119 on z typu zlecenia, np. <em>SUP<\/em>, oraz sze\u015bciocyfrowego numeru. Informacje o typach zlece\u0144 dost\u0119pnych w systemie mo\u017cna uzyska\u0107 od administratora.<\/p>\n<p>Zlecenie deweloperskie posiada ponadto nast\u0119puj\u0105ce cechy: priorytet, kategori\u0119, hierarchi\u0119 i wersj\u0119 (release).<\/p>\n<p>Priorytet mo\u017ce by\u0107 u\u017cyty do okre\u015blenia stopnia pilno\u015bci opracowania zlecenia. Przyjmuje warto\u015bci od <em>Priority 1<\/em> (bardzo wa\u017cne) do <em>Priority 9<\/em> (nieistotne).<\/p>\n<p>Kategoria s\u0142u\u017cy do okre\u015blenia obszaru, kt\u00f3rego dotycz\u0105 prace rozwojowe. Dost\u0119pne s\u0105 nast\u0119puj\u0105ce kategorie:<\/p>\n<ul>\n<li>rozw\u00f3j (dodanie nowego elementu)<\/li>\n<li>dokumentacja<\/li>\n<li>korekta (bugfix)<\/li>\n<li>informacja<\/li>\n<li>ergonomia<\/li>\n<\/ul>\n<p>W przypadku hierarchii zlecenie mo\u017cna przypisa\u0107 do danego obszaru funkcjonalnego.<br \/>\nRelease okre\u015bla wersj\u0105 oprogramowania, w kt\u00f3rej ma nast\u0105pi\u0107 opracowanie zlecenia.<br \/>\nZlecenia deweloperskie zawiera jedno lub wiele zada\u0144 deweloperskich, w ramach kt\u00f3rych odbywa si\u0119 w\u0142a\u015bciwa implementacja.<\/p>\n<p>Obs\u0142uga zlece\u0144 deweloperskich wymaga aktywacji us\u0142ugi zlece\u0144 deweloperskich dla systemu deweloperskiego.<\/p>\n<h3 id=\"zadanie-deweloperskie\" ><span class=\"ez-toc-section\" id=\"Zadanie_deweloperskie\"><\/span>Zadanie deweloperskie<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Przetwarzanie obiekt\u00f3w deweloperskich mo\u017ce odbywa\u0107 si\u0119 wy\u0142\u0105cznie w ramach<br \/>\nzadania deweloperskiego. Zadanie deweloperskie musi by\u0107 przypisane do zlecenia deweloperskiego. Zadanie deweloperskie tworzy powiazanie pomi\u0119dzy opracowuj\u0105cymi u\u017cytkownikami, obiektami deweloperskimi i i tre\u015bci\u0105.<\/p>\n<p>Nowe zadanie deweloperskie otrzymuje automatycznie unikalny numer. Zadanie musi by\u0107 przypisane do zlecenia deweloperskiego, kt\u00f3re w momencie przyporz\u0105dkowania musi mie\u0107 status\u00a0<em>W opracowaniu.<\/em><br \/>\nW przypadku systemu bez bez us\u0142ugi zlece\u0144 deweloperskich w zleceniu mo\u017cna wprowadzi\u0107 dowolny tekst.<\/p>\n<p>Statusy zada\u0144 deweloperskich:<\/p>\n<ul>\n<li>otwarte<\/li>\n<li>w kolejce do zwolnienia<\/li>\n<li>w trakcie zwalniania<\/li>\n<li>zwolnione<\/li>\n<li>zwolnienie z ostrze\u017ceniami nie powiod\u0142o si\u0119<\/li>\n<li>w kolejce do aktywowania<\/li>\n<li>w trakcie aktywowania<\/li>\n<li>aktywowane<\/li>\n<li>aktywowane bez aktualizacji oprogramowania<\/li>\n<\/ul>\n<p>Podczas dodawania obiektu deweloperskiego do zadania deweloperskiego obiekt ten jest blokowany w systemie. Blokada ta nazywana jest blokad\u0105 globaln\u0105. Ustawienie blokady globalnej gwarantuje, \u017ce<br \/>\n\u017ce obiekt deweloperski nie b\u0119dzie modyfikowany r\u00f3wnolegle w innym zadaniu deweloperskim.<br \/>\nUsuniecie globalnej blokady nast\u0119puje w momencie, gdy obiekt deweloperski jest usuwany z zadania deweloperskiego lub gdy zadanie deweloperskie zostanie aktywowane.<\/p>\n<p>Zadanie deweloperskie mo\u017ce by\u0107 opracowywane przez wielu u\u017cytkownik\u00f3w, je\u015bli s\u0105 oni dodani do zadania jako<br \/>\nu\u017cytkownicy opracowuj\u0105cy. Podczas modyfikacji obiektu deweloperskiego przyporz\u0105dkowanego do zadania deweloperskiego nast\u0119puje dodatkowo blokada lokalna, opr\u00f3cz wspomnianej blokady globalnej.<br \/>\nZapobiega to jednoczesnej modyfikacji danego obiektu przez wielu u\u017cytkownik\u00f3w.<br \/>\nU\u017cytkownik opracowuj\u0105cy musi r\u0119cznie zwolni\u0107 obiekt po zako\u0144czeniu edycji i w ten spos\u00f3b usun\u0105\u0107 blokad\u0119 lokaln\u0105.<\/p>\n<p>Opracowanie zadania deweloperskiego ko\u0144czy si\u0119 zwolnieniem i aktywacj\u0105 zadania.<\/p>\n<p>Efektem zako\u0144czonego zadania deweloperskiego jest aktualizacja oprogramowania. Zwykle rezultaty zada\u0144 deweloperskich z jednego zlecenia deweloperskiego s\u0105 zebrane w aktualizacji oprogramowania. Zadania s\u0105 \u0142\u0105czone do momentu wydania utworzonej aktualizacji oprogramowania. Kolejne zadania deweloperskie z tego samego zlecenia deweloperskiego s\u0105 zebrane w nowej aktualizacji oprogramowania. Utworzona aktualizacja<br \/>\naktualizacja przenosi modyfikacje do systemu pochodnego\u00a0np. systemu produkcyjnego klienta.<\/p>\n<h3 id=\"podstawowy-proces-deweloperski\" ><span class=\"ez-toc-section\" id=\"Podstawowy_proces_deweloperski\"><\/span>Podstawowy proces deweloperski<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Przed om\u00f3wieniem poszczeg\u00f3lnych typ\u00f3w obiekt\u00f3w deweloperskich, przyjrzyjmy si\u0119 typowemu procesowi deweloperskiemu oraz niekt\u00f3rym specyficznym w\u0142a\u015bciwo\u015bciom aplikacji\u00a0<em>Zadania deweloperskie.<\/em><\/p>\n<h4 id=\"krok-1-utworzenie-zlecenia-deweloperskiego-i-rozpoczecie-opracowania\" ><span class=\"ez-toc-section\" id=\"Krok_1_Utworzenie_zlecenia_deweloperskiego_i_rozpoczecie_opracowania\"><\/span>Krok 1: Utworzenie zlecenia deweloperskiego i rozpocz\u0119cie opracowania<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Proces rozwoju rozpoczyna si\u0119 utworzeniem zlecenia deweloperskiego za pomoc\u0105 aplikacji\u00a0<em>Zlecenia deweloperskie.\u00a0<\/em>W tym celu u\u017cytkownik musi okre\u015bli\u0107 <em>Description<\/em>, <em>Release<\/em>, <em>Full task desription<\/em> i <em>Coordinator<\/em>.<\/p>\n<p>Po zapisaniu zlecenia <em>Coordinator<\/em> jest automatycznie wprowadzony jako <em>Editor<\/em>. Zam\u00f3wienie przyjmuje teraz status <em>Created<\/em>.<\/p>\n<p><em>Coordinator<\/em> sprawdza utworzone zlecenie i dodaje lub koryguje wymagane dane, tj. priorytet, kategori\u0119, hierarchi\u0119, release i czas przetwarzania. Konieczne jest wprowadzenie programist\u00f3w i tester\u00f3w. W razie potrzeby koordynator mo\u017ce wprowadzi\u0107 dodatkowe teksty. Nast\u0119pnie ustawia status zlecenia na <em>Classified.<\/em><\/p>\n<h4 id=\"krok-2-opracowanie\" ><span class=\"ez-toc-section\" id=\"Krok_2_Opracowanie\"><\/span>Krok 2: Opracowanie<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Programista rozpoczyna opracowanie zlecenia deweloperskiego ustawiaj\u0105c jego status na <em>In Progress<\/em>. Nast\u0119pnie w aplikacji <em>Zadania deweloperskie <\/em>w obszarze <em>Rozw\u00f3j oprogramowania <\/em>dodaje nowe zadanie deweloperskie do zlecenia.<\/p>\n<section class=\"document-alert-box indicator\"><div class=\"document-alert-title\">Wskaz\u00f3wka<\/div><div class=\"document-alert-content\">W przypadku braku us\u0142ugi zlece\u0144 deweloperskich (Ninus), proces deweloperski rozpoczyna si\u0119 od tego kroku.<\/div><\/section>\n<p>Programista rozpoczyna opracowanie obiekt\u00f3w lub tworzy nowe w aplikacji\u00a0<em>Obiekty deweloperskie.<\/em><\/p>\n<p>S\u0105 one automatycznie dodawane do zadania i blokowane globalnie (r\u00f3wnie\u017c lokalnie podczas ich modyfikacji). Wi\u0105\u017ce si\u0119 to z tzw. check-out. Korzystaj\u0105c z narz\u0119dzi SAS (crtbo, crtvs, &#8230;) nale\u017cy w razie potrzeby wygenerowa\u0107 na nowo \u017ar\u00f3d\u0142a dla zmienionych obiekt\u00f3w deweloperskich i utworzy\u0107 tymczasowe tabele bazy danych dla zmienionych obiekt\u00f3w biznesowych. Wygenerowane \u017ar\u00f3d\u0142a s\u0105 przechowywane w katalogu roboczym zadania, podczas dodawania do zadania nast\u0119puje check-out klas Java i zapisanie do opracowania w tym samym miejscu. Od tego momentu rozpoczyna si\u0119 w\u0142a\u015bciwe programowanie.<\/p>\n<section class=\"document-alert-box warning\"><div class=\"document-alert-title\">Uwaga<\/div><div class=\"document-alert-content\">Nie jest mo\u017cliwa automatyczna modyfikacja wygenerowanych \u017ar\u00f3de\u0142.<\/div><\/section>\n<p>Je\u015bli testy przeprowadzone przez dewelopera zako\u0144cz\u0105 si\u0119 pomy\u015blnie, nast\u0119puje implementacja \u017ar\u00f3de\u0142. Proces ten nazywany jest check-in i wykonywany jest za pomoc\u0105 przycisk\u00f3w na standardowym pasku narz\u0119dzi aplikacji <em>Zadania deweloperskie<\/em>. Wygenerowane i zaprogramowane \u017ar\u00f3d\u0142a s\u0105 przenoszone do repozytorium i kompilowane ze stanem klasy systemu. Je\u015bli wyst\u0105pi\u0105 b\u0142\u0119dy, nale\u017cy je usun\u0105\u0107 i powt\u00f3rzy\u0107 check-in.<\/p>\n<h4 id=\"krok-3-zwolnienie-zadania-deweloperskiego\" ><span class=\"ez-toc-section\" id=\"Krok_3_Zwolnienie_zadania_deweloperskiego\"><\/span>Krok 3: Zwolnienie zadania deweloperskiego<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Nast\u0119pnym krokiem jest zwolnienie zadania deweloperskiego. Po jego wykonaniu nie jest ju\u017c mo\u017cliwa modyfikacja obiekt\u00f3w deweloperskich zawartych w zadaniu. Je\u015bli w ramach zadania wprowadzono zmiany w obiektach biznesowych, wprowadzone zmiany w schemacie musz\u0105 zosta\u0107 aktywowane na bazie danych za pomoc\u0105 komendy \u201eactjob\u201c. Aktywacja odbywa si\u0119 poprzez zast\u0105pienie starych, wci\u0105\u017c aktywnych tabel nowymi tabelami tymczasowymi. System automatycznie przenosi dane dane ze starych tabel do nowych.<br \/>\nJe\u015bli konieczna jest konwersja danych lub okre\u015blenie specjalnych warto\u015bci pocz\u0105tkowych dla nowo dodanych atrybut\u00f3w, deweloper musi dostosowa\u0107 odpowiednie programy aktualizacji.<\/p>\n<h4 id=\"krok-4-aktywacja-zadania-deweloperskiego\" ><span class=\"ez-toc-section\" id=\"Krok_4_Aktywacja_zadania_deweloperskiego\"><\/span>Krok 4: Aktywacja zadania deweloperskiego<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Aktywacja zadania deweloperskiego jest ostatnim krokiem opracowania. Wszystkie globalne blokady na\u0142o\u017cone przez zadanie deweloperskie zostaj\u0105 anulowane. Dla zadania deweloperskiego tworzona jest aktualizacja oprogramowania ze zmianami lub zmiany s\u0105 dodawane do istniej\u0105cej otwartej aktualizacji oprogramowania z innego aktywowanego zadania w tym samym zleceniu deweloperskim. \u0179r\u00f3d\u0142a Java, klasy Java, pliki, ikony i pliki pomocy online zast\u0119puj\u0105 starsze wersje w systemie plik\u00f3w serwera systemu ERP. Po ponownym uruchomieniu serwera b\u0119d\u0105 stosowane nowe pliki klas.<\/p>\n<section class=\"document-alert-box indicator\"><div class=\"document-alert-title\">Wskaz\u00f3wka<\/div><div class=\"document-alert-content\">Je\u015bli nie jest u\u017cywana us\u0142uga zlece\u0144 deweloperskich (Ninus), proces deweloperski ko\u0144czy si\u0119 na tym kroku.<\/div><\/section>\n<p>Etap implementacji jest zako\u0144czony, gdy wszystkie zadania deweloperskie nale\u017c\u0105ce do zlecenia deweloperskiego zostan\u0105 aktywowane. U\u017cytkownik opracowuj\u0105cy nadaje zleceniu status <em>Implemented<\/em>. U\u017cytkownik opracowuj\u0105cy <em>(editor)<\/em> zmienia si\u0119 na testera (<em>tester<\/em>).<\/p>\n<h4 id=\"krok-5-testy-zlecenia-deweloperskiego\" ><span class=\"ez-toc-section\" id=\"Krok_5_Testy_zlecenia_deweloperskiego\"><\/span>Krok 5: Testy zlecenia deweloperskiego<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Testy zlecenia deweloperskiego odbywa si\u0119 w dw\u00f3ch etapach. Pierwszy test jest przeprowadzany w systemie deweloperskim. Je\u015bli przebiegnie pomy\u015blnie, aktualizacja oprogramowania jest implementowana w systemie testowym i na tym systemie przeprowadzany jest drugi test.<\/p>\n<p>Przed rozpocz\u0119ciem testowania nale\u017cy zmieni\u0107 status zlecenia deweloperskiego na <em>Initial test. <\/em>Tester sprawdza, czy zadania zosta\u0142y zrealizowane bez b\u0142\u0119d\u00f3w. Je\u015bli implementacja \u017c\u0105danych modyfikacji jest niekompletna lub nieprawid\u0142owa, programista musi ponownie opracowa\u0107 zlecenie deweloperskie. Status zlecenia zmienia w\u00f3wczas z powrotem na <em>Classified<\/em>.<\/p>\n<p>Je\u015bli pierwszy test zako\u0144czy\u0142 si\u0119 pomy\u015blnie, status zlecenia nale\u017cy zmieni\u0107 na <em>Initial test completed<\/em>. Nast\u0119pnie, jak<br \/>\njak opisano powy\u017cej, aktualizacja oprogramowania jest importowana do systemu testowego. W tym momencie rozpoczyna si\u0119 drugi test. Tester ustawia status zlecenia na <em>In second test<\/em>. W przypadku wyst\u0105pienia b\u0142\u0119d\u00f3w zlecenie musi zosta\u0107 ponownie opracowane przez programist\u0119.<\/p>\n<p>Je\u015bli drugi tekst zako\u0144czy\u0142 si\u0119 pomy\u015blnie, zlecenie otrzymuje status <em>Completed<\/em>. Oznacza to zako\u0144czenie fazy test\u00f3w.<\/p>\n<h3 id=\"obiekty-deweloperskie\" ><span class=\"ez-toc-section\" id=\"Obiekty_deweloperskie\"><\/span>Obiekty deweloperskie<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Rozw\u00f3j w systemie ERP opiera si\u0119 na \u0142\u0105czeniu r\u00f3\u017cnych obiekt\u00f3w. Mog\u0105 to by\u0107 na przyk\u0142ad klasy Java, ikony, logiczne typy danych, zestawy warto\u015bci, obiekty pomocy itp. Wszystkie obiekty u\u017cywane podczas programowania s\u0105 okre\u015blane og\u00f3lnym terminem: <em>obiekt deweloperski<\/em>. System ERP obs\u0142uguje predefiniowany zestaw r\u00f3\u017cnych typ\u00f3w obiekt\u00f3w. S\u0105 one okre\u015blane jako typy obiekt\u00f3w deweloperskich. Ka\u017cdy obiekt deweloperski posiada nazw\u0119 i obszar nazw. Na podstawie<br \/>\nkombinacji obszaru nazw i nazwy mo\u017cna jednoznacznie zidentyfikowa\u0107 obiekt deweloperski. Obiekt musi by\u0107 unikalny w ramach swojego typu. Oznacza to, \u017ce nie mog\u0105 na przyk\u0142ad istnie\u0107 klasy Java, kt\u00f3re maj\u0105 ten sam obszar nazw i nazw\u0119.<\/p>\n<p>Z drugiej strony mo\u017cliwe jest istnienie logicznego typu danych i klasy Java z t\u0105 sam\u0105 kombinacj\u0105 obszaru nazw i nazwy. W niekt\u00f3rych przypadkach przyjmuje si\u0119 nawet, \u017ce istniej\u0105 obiekty deweloperskie r\u00f3\u017cnych typ\u00f3w z tym samym obszarem nazw i nazw\u0105. Dobrym tego przyk\u0142adem s\u0105 zestawy warto\u015bci (<em>value sets<\/em>). W momencie tworzenia nowego zestawu warto\u015bci jest zwykle generowana klasa Java o tej samej nazwie.<\/p>\n<p>Wszystkie stosowane obiekty deweloperskie s\u0105 wersjonowane i zapisywane w repozytorium.<\/p>\n<p>Poni\u017cej opisane s\u0105 obszary nazw, a w dalszej cz\u0119\u015bci dokumentu poszczeg\u00f3lne typy obiekt\u00f3w deweloperskich i wersjonowanie.<\/p>\n<h4 id=\"obszary-nazw\" ><span class=\"ez-toc-section\" id=\"Obszary_nazw\"><\/span><a id=\"obszary-nazw\"><\/a>Obszary nazw<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Wszystkie obiekty deweloperskie systemu ERP s\u0105 uporz\u0105dkowane w obszarach nazw. Ten sk\u0142ada si\u0119 z jednego lub wi\u0119cej s\u0142\u00f3w oddzielonych kropk\u0105, np. <em>com.cisag.app<\/em> lub <em>com.cisag.pgm<\/em>. Obszary nazw maj\u0105 struktur\u0119 hierarchiczn\u0105 w formie drzewa, kt\u00f3rego podstaw\u0105 jest obszar nazw <em>com<\/em>. Dla obszaru nazw<br \/>\n<em>com.cisag.app.sales.ui <\/em>struktura jest nast\u0119puj\u0105ca:<\/p>\n<pre>com\ncom.cisag\ncom.cisag.app\ncom.cisag.app.sales\ncom.cisag.app.sales.ui<\/pre>\n<p>Podczas tworzenia obszaru nazw mo\u017cna zdefiniowa\u0107 dla niego specjalne zachowanie. Obszar mo\u017ce by\u0107 oznaczony jako testowy lub jako wewn\u0119trzny. Obszar nazw oznaczony jako testowy nie mo\u017ce zosta\u0107 wydany z aktualizacj\u0105. Dotyczy to r\u00f3wnie\u017c wszystkich zawartych w nim obiekt\u00f3w deweloperskich. W przypadku wewn\u0119trznego obszaru nazw mo\u017cna dla ka\u017cdego zadania deweloperskiego indywidulanie zdecydowa\u0107, czy obiekty deweloperskie zostan\u0105 wydane z aktualizacj\u0105.<\/p>\n<p>Po wybraniu dla obszaru nazw jednego z tych dw\u00f3ch oznacze\u0144, nie b\u0119dzie ju\u017c mo\u017cliwo\u015bci jego zmiany. Wszystkie obszary, kt\u00f3re zostan\u0105 utworzone w ramach tego obszaru, otrzymaj\u0105 automatycznie to oznaczenie, bez mo\u017cliwo\u015bci zmiany.<\/p>\n<p>Dla obiekt\u00f3w uporz\u0105dkowanych w strukturach obszar\u00f3w nazw stosowane s\u0105 nast\u0119puj\u0105ce regu\u0142y:<\/p>\n<ul>\n<li>Wszystkie obiekty deweloperskie danego typu znajduj\u0105ce si\u0119 w jednym obszarze nazw musza si\u0119 r\u00f3\u017cni\u0107 nazw\u0105, bez rozr\u00f3\u017cniania pisowni wielk\u0105 i ma\u0142\u0105 liter\u0105.<\/li>\n<li>Obiekty z dw\u00f3ch r\u00f3\u017cnych obszar\u00f3w nazw s\u0105 zawsze r\u00f3\u017cnymi obiektami, nawet je\u015bli ich nazwy s\u0105 takie same.<\/li>\n<li>W przypadku obiektu <em>Klasa Java<\/em> obszar nazw odpowiada r\u00f3wnie\u017c nazwie pakietu Java.<\/li>\n<\/ul>\n<p>Regu\u0142y dotycz\u0105ce obszar\u00f3w nazw zapobiegaj\u0105 nak\u0142adaniu si\u0119 na siebie nazw obiekt\u00f3w deweloperskich.<br \/>\nObiekty rozwojowe pochodz\u0105ce ze standardu mog\u0105 zatem istnie\u0107 obok obiekt\u00f3w deweloperskich programowanych przez partner\u00f3w, bez ryzyka wyst\u0105pienia konflikt\u00f3w w nazewnictwie.<\/p>\n<h5 id=\"struktura-obszaru-nazw\" ><span class=\"ez-toc-section\" id=\"Struktura_obszaru_nazw\"><\/span>Struktura obszaru nazw<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Obszar nazw sk\u0142ada si\u0119 z jednego lub wi\u0119cej s\u0142\u00f3w oddzielonych kropkami i ma struktur\u0119 hierarchiczn\u0105. S\u0142owa mog\u0105 sk\u0142ada\u0107 si\u0119 z liter a &#8211; z i musz\u0105 by\u0107 pisane ma\u0142ymi literami. Podstaw\u0105 wszystkich obszar\u00f3w nazw w systemie ERP jest obszar <em>com<\/em>. Kolejny poziom tworzy prefiks deweloperski sk\u0142adaj\u0105cy si\u0119 z 3-5 znak\u00f3w. Jest on definiowany w momencie przyznania licencji i nie podlega modyfikacji. Prefiks deweloperski standardowego rozwoju to <em>cisag<\/em>. Nast\u0119pny poziom jest r\u00f3wnie\u017c \u015bci\u015ble okre\u015blony. S\u0105 to trzy obszary nazw:<\/p>\n<table style=\"border-collapse: collapse; width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 153.766px;\"><strong>Obszar nazw<\/strong><\/td>\n<td style=\"width: 583.234px;\"><strong>Opis<\/strong><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 153.766px;\">com.&lt;pr\u00e4fix&gt;.app<\/td>\n<td style=\"width: 583.234px;\">Wszystkie obiekty deweloperskie zawieraj\u0105ce si\u0119 w tym obszarze s\u0105 u\u017cywane\u00a0w aplikacjach biznesowych.<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 153.766px;\">com.&lt;pr\u00e4fix&gt;.dbu<\/td>\n<td style=\"width: 583.234px;\">Dla ka\u017cdego obiektu deweloperskiego istniej\u0105 wygenerowane klasy Java i program aktualizacji dla ka\u017cdej wersji. Program aktualizacji definiuje, w jaki spos\u00f3b<br \/>\nnale\u017cy zmieni\u0107 dane, aby m\u00f3c przej\u015b\u0107 do kolejnej wersji.<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 153.766px;\">com.&lt;pr\u00e4fix&gt;.nls<\/td>\n<td style=\"width: 583.234px;\">W tym obszarze nazw znajduj\u0105 si\u0119 specjalne wygenerowane klasy Java dla atrybut\u00f3w obiekt\u00f3w biznesowych specyficznych dla danego j\u0119zyka,\u00a0kt\u00f3re umo\u017cliwiaj\u0105 dost\u0119p<br \/>\ndost\u0119p do bazy danych.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Struktura obszaru nazw zawarta w com.&lt;prefix&gt;.app jest uzasadniona technicznie i opiera si\u0119 na obszarach (frameworks) zdefiniowanych w systemie ERP. Istnieje mo\u017cliwo\u015b\u0107 dalszych gradacji.<\/p>\n<p>Najni\u017cszy poziom obszaru nazw tworzy zazwyczaj po\u0142\u0105czenie maksymalnie sze\u015bciu obszar\u00f3w nazw:<\/p>\n<pre>com.&lt;pr\u00e4fix&gt;.app.&lt;klasyfikacja techniczna&gt;\ncom.&lt;pr\u00e4fix&gt;.app.&lt;klasyfikacja techniczna&gt;.obj\ncom.&lt;pr\u00e4fix&gt;.app.&lt;klasyfikacja techniczna&gt;.log\ncom.&lt;pr\u00e4fix&gt;.app.&lt;klasyfikacja techniczna&gt;.ui\ncom.&lt;pr\u00e4fix&gt;.app.&lt;klasyfikacja techniczna&gt;.gui\ncom.&lt;pr\u00e4fix&gt;.app.&lt;klasyfikacja techniczna&gt;.res2d\ncom.&lt;pr\u00e4fix&gt;.app.&lt;klasyfikacja techniczna&gt;.hook\ncom.&lt;pr\u00e4fix&gt;.app.&lt;klasyfikacja techniczna&gt;.model\ncom.&lt;pr\u00e4fix&gt;.app.&lt;klasyfikacja techniczna&gt;.rest<\/pre>\n<p>Ka\u017cdy z obszar\u00f3w nazw ma okre\u015blone znaczenie. Typy obiekt\u00f3w deweloperskich, opisane w rozdziale <em>Typy obiekt\u00f3w deweloperskich<\/em>, s\u0105 rozdzielane do tych obszar\u00f3w nazw wed\u0142ug okre\u015blonych regu\u0142 lub kryteri\u00f3w. Niekt\u00f3re typy obiekt\u00f3w deweloperskich podlegaj\u0105 pewnej zasadzie: musz\u0105 znajdowa\u0107 si\u0119 dok\u0142adnie w jednej okre\u015blonej przestrzeni nazw. Dotyczy to na przyk\u0142ad obiekt\u00f3w biznesowych, kt\u00f3re zawsze musz\u0105 znajdowa\u0107 si\u0119 w obszarze nazw zako\u0144czonym na <em>.obj<\/em>. Inne typy s\u0105 przypisywane do obszar\u00f3w nazw raczej wed\u0142ug rodzaju ich zastosowania.<\/p>\n<p><em>Szczeg\u00f3lne obszary nazw rozwoju standardu<\/em><\/p>\n<p>Obszar nazw <em>com.cisag<\/em> obejmuje trzy specjalne obszary:<\/p>\n<table style=\"border-collapse: collapse; width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 23.125%;\"><strong>Obszar nazw<\/strong><\/td>\n<td style=\"width: 76.75%;\"><strong>Opis<\/strong><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 23.125%;\">com.cisag.pgm<\/td>\n<td style=\"width: 76.75%;\">Ten obszar nazw zawiera Application Programming Interface (API), w kt\u00f3rym programowane s\u0105 aplikacje w systemie ERP. S\u0105 to zazwyczaj klasy <em>wrapper<\/em> lub interfejsy, kt\u00f3re s\u0105 implementowane przez klasy w obszarze nazw <em>com.cisag.sys<\/em>.<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 23.125%;\">com.cisag.sys<\/td>\n<td style=\"width: 76.75%;\">Ten obszar nazw zawiera silnik systemu, inne komponenty systemu oraz <em>data dictionary<\/em>.<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 23.125%;\">com.cisag.archive<\/td>\n<td style=\"width: 76.75%;\">Ten obszar nazw zawiera <em>data dictionary<\/em>, w kt\u00f3rym zapisywane s\u0105 metadane wersji wszystkich obiekt\u00f3w deweloperskich.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3 id=\"typy-obiektow-deweloperskich\" ><span class=\"ez-toc-section\" id=\"Typy_obiektow_deweloperskich\"><\/span>Typy obiekt\u00f3w deweloperskich<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>System ERP opiera si\u0119 na zdefiniowanym zestawie typ\u00f3w obiekt\u00f3w deweloperskich. Ka\u017cdy typ obiektu ma specjalne znaczenie i zastosowanie. Poni\u017cej wymienione zosta\u0142y niekt\u00f3re typy. Szczeg\u00f3\u0142owe informacje o ka\u017cdym z typ\u00f3w znajduj\u0105 si\u0119 w odpowiednich podrozdzia\u0142ach, jak r\u00f3wnie\u017c w dokumencie\u00a0<em>Obiekty deweloperskie.<\/em><\/p>\n<h4 id=\"akcja\" ><span class=\"ez-toc-section\" id=\"Akcja\"><\/span>Akcja<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Akcje s\u0105 u\u017cywane w systemie ERP do programowania interfejs\u00f3w. S\u0105 one niezb\u0119dne w procesie tworzenia przycisk\u00f3w, zak\u0142adek, menu i menu kontekstowych. Dla akcji\u00a0mo\u017cna wprowadzi\u0107 etykiet\u0119, tooltip, kombinacj\u0119 klawiszy, ma\u0142\u0105 ikon\u0119 i du\u017c\u0105 ikon\u0119. Akcje mog\u0105 dziedziczy\u0107 po innych akcjach, tzn. mo\u017cna wprowadzi\u0107 akcj\u0119, z kt\u00f3rej pobierana jest dana etykieta lub tooltip. Kt\u00f3re atrybuty zostan\u0105 przej\u0119te, mo\u017cna okre\u015bli\u0107 za pomoc\u0105 listy wyboru dla ka\u017cdego atrybutu, dost\u0119pne opcje to:\u00a0<em>Z dziedziczenia<\/em> i<em> Niestandardowe <\/em>(zdefiniowane przez u\u017cytkownika).<\/p>\n<p>Akcje mog\u0105 by\u0107 tworzone tylko w obszarach nazw ko\u0144cz\u0105cych si\u0119 na &#8222;.gui&#8221; lub &#8222;.ui&#8221;. Akcje s\u0105 u\u017cywane w innych akcjach do dziedziczenia lub w klasach Java. Stosowany obszar nazw &#8222;.ui&#8221; lub &#8222;.gui&#8221; powinien zale\u017ce\u0107 od klasy Java. Zwykle akcja znajduje si\u0119 w tym samym obszarze nazw co\u00a0u\u017cywana klasa Java.<\/p>\n<p>Nazwa akcji powinna by\u0107 wybrana w taki spos\u00f3b, aby mo\u017cna by\u0142o po niej rozpozna\u0107 przynale\u017cno\u015b\u0107 do aplikacji, dialogu lub komponentu UI. Na przyk\u0142ad nazwa akcji mo\u017ce zaczyna\u0107 si\u0119 od nazwy danej aplikacji.<\/p>\n<p>Ponadto nazwa akcji powinna wskazywa\u0107 na to, dla jakich element\u00f3w UI jest wykorzystywana, np. przycisku, prze\u0142\u0105cznika, zak\u0142adki czy menu podr\u0119cznego.<\/p>\n<h5 id=\"akcje-dla-przyciskow\" ><span class=\"ez-toc-section\" id=\"Akcje_dla_przyciskow\"><\/span>Akcje dla przycisk\u00f3w<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Szablon akcji stosowanych dla przycisk\u00f3w to:<br \/>\n&lt;Nazwa klasy&gt;&lt;Nazwa akcji&gt;[Button]<br \/>\nNazwa klasy jest nazw\u0105 klasy aplikacji, okna dialogowego lub komponentu. Przyrostek Button jest opcjonalny i dodawany tylko w celu doprecyzowania.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\">Aplikacja <em>Licencje<\/em> zawiera przycisk s\u0142u\u017c\u0105cy do dodawania wpis\u00f3w. Akcja b\u0119dzie utworzona w nast\u0119puj\u0105cym obszarze nazw:<br \/>\nObszar nazw: com.cisag.app.internal.ui<br \/>\nNazwa: LicenceDefinitionMaintenanceAddEntry<br \/>\nNazwa alternatywna: LicenceDefinitionMaintenanceAddEntryButton<\/div><\/section>\n<h5 id=\"akcje-dla-przelacznikow\" ><span class=\"ez-toc-section\" id=\"Akcje_dla_przelacznikow\"><\/span>Akcje dla prze\u0142\u0105cznik\u00f3w<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Szablon akcji stosowanych dla prze\u0142\u0105cznik\u00f3w to:<br \/>\n&lt;Nazwa klasy&gt;Toggle&lt;Nazwa akcji&gt;<br \/>\nNazwa klasy jest nazw\u0105 klasy aplikacji, okna dialogowego lub komponentu. Nast\u0119pnie s\u0142owo <em>Toggle<\/em>, a po nim nazwa akcji.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\">Aplikacja <em>Licencje<\/em> zawiera prze\u0142\u0105cznik do wy\u015bwietlania i ukrywania szczeg\u00f3\u0142\u00f3w na li\u015bcie. Akcja b\u0119dzie utworzona w nast\u0119puj\u0105cym obszarze nazw:<br \/>\nObszar nazw: com.cisag.app.internal.ui<br \/>\nNazwa: LicenceDefinitionMaintenanceToogleDetails<\/div><\/section>\n<section class=\"document-alert-box indicator\"><div class=\"document-alert-title\">Wskaz\u00f3wka<\/div><div class=\"document-alert-content\">W przypadku prze\u0142\u0105cznik\u00f3w nale\u017cy okre\u015bli\u0107 w tooltipie obie funkcje (np. poka\u017c\/ukryj obszar nawigacji).<\/div><\/section>\n<h5 id=\"akcja-dla-zakladek\" ><span class=\"ez-toc-section\" id=\"Akcja_dla_zakladek\"><\/span>Akcja dla zak\u0142adek<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Szablon akcji stosowanych dla zak\u0142adek to:<br \/>\n&lt;Nazwa klasy&gt;&lt;Nazwa akcji&gt;Tab<br \/>\nNazwa klasy jest nazw\u0105 klasy aplikacji, okna dialogowego lub komponentu. Nast\u0119pnie nazwa akcji, a po niej s\u0142owo <em>Tab<\/em>.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\">Aplikacja <em>Licencje<\/em> zawiera zak\u0142adk\u0119 z rozszerzeniami. Akcja b\u0119dzie utworzona w nast\u0119puj\u0105cym obszarze nazw:<br \/>\nObszar nazw: com.cisag.app.internal.ui<br \/>\nNazwa: LicenceDefinitionMaintenanceExtensionTab<\/div><\/section>\n<h5 id=\"akcja-dla-menu-kontekstowego\" ><span class=\"ez-toc-section\" id=\"Akcja_dla_menu_kontekstowego\"><\/span>Akcja dla menu kontekstowego<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Szablon akcji stosowanych dla menu kontekstowego to:<br \/>\n&lt;Nazwa klasy&gt;Popup&lt;Nazwa akcji&gt;<br \/>\nNazwa klasy jest nazw\u0105 klasy aplikacji, okna dialogowego lub komponentu. Nast\u0119pnie s\u0142owo <em>Popup<\/em>, a po nim nazwa akcji.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\">Aplikacja <em>Licencje<\/em> zawiera zak\u0142adk\u0119 z rozszerzeniami. Akcja b\u0119dzie utworzona w nast\u0119puj\u0105cym obszarze nazw:<br \/>\nObszar nazw: com.cisag.app.internal.ui<br \/>\nNazwa: LicenceDefinitionMaintenanceExtensionTab<\/div><\/section>\n<h5 id=\"szablony\" ><span class=\"ez-toc-section\" id=\"Szablony\"><\/span>Szablony<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>W com.cisag.pgm istnieje kilka akcji, kt\u00f3re w przypadku takiego samego zastosowania powinny by\u0107 u\u017cywane jako szablon dla akcji w\u0142asnych. Nie mog\u0105 one by\u0107 stosowane bezpo\u015brednio, ale akcje w\u0142asne mog\u0105 dziedziczy\u0107 po nich i przybiera\u0107 form\u0119 Shortcuts i Icons.<\/p>\n<p>Dla zastosowania w standardowym pasku narz\u0119dzi:<br \/>\ncom.cisag.pgm.gui.coolbar.Execute<br \/>\ncom.cisag.pgm.gui.coolbar.ExecuteList<br \/>\ncom.cisag.pgm.gui.coolbar.ExecuteMenu<\/p>\n<p>Dla zastosowania w paskach narz\u0119dzi:<br \/>\ncom.cisag.pgm.gui.coolbar.Add (&#8222;Nowe\/Dodaj&#8221;)<br \/>\ncom.cisag.pgm.gui.coolbar.AddDuplicate (&#8222;Duplikuj&#8221;)<br \/>\ncom.cisag.pgm.gui.coolbar.AddFromSearch (&#8222;Wyszukaj i dodaj&#8221;)<br \/>\ncom.cisag.pgm.gui.coolbar.Remove (&#8222;Wstaw\/Usu\u0144 znacznik usuwania&#8221;)<br \/>\ncom.cisag.pgm.gui.coolbar.ToggleDetails(&#8222;Szczeg\u00f3\u0142y&#8221;)<br \/>\ncom.cisag.pgm.gui.coolbar.FilterEntries (&#8222;Filtruj pozycje\/wpisy&#8221;)<br \/>\ncom.cisag.pgm.gui.coolbar.Find (&#8222;Wyszukaj&#8221;)<br \/>\ncom.cisag.pgm.gui.coolbar.ShowDetailsDialog<br \/>\n(&#8222;Cechy&#8221;)<\/p>\n<p>Do obs\u0142ugi klawiatury:<br \/>\ncom.cisag.pgm.gui.Enter<\/p>\n<h4 id=\"aplikacja\" ><span class=\"ez-toc-section\" id=\"Aplikacja\"><\/span>Aplikacja<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Aplikacje maj\u0105 szerokie zastosowanie w systemie ERP i dziel\u0105 si\u0119 na aplikacje dialogowe, aplikacje dzia\u0142aj\u0105ce w tle, aktualizacje danych dialogowych, automatyczne aktualizacje danych w tle, r\u0119czne aktualizacje danych w tle, us\u0142ugi, reorganizacje i narz\u0119dzia.<\/p>\n<h5 id=\"aplikacja-dialogowa\" ><span class=\"ez-toc-section\" id=\"Aplikacja_dialogowa\"><\/span>Aplikacja dialogowa<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Aplikacje dialogowe to aplikacje, na kt\u00f3rych najcz\u0119\u015bciej\u00a0 pracuje si\u0119 w systemie ERP. S\u0105 to<br \/>\naplikacje jak np. <em>Zam\u00f3wienia sprzeda\u017cy<\/em> lub aplikacje typu <em>Lista.<\/em><\/p>\n<p>Aplikacje dialogowe musz\u0105 by\u0107 tworzone w obszarze nazw, kt\u00f3ry ko\u0144czy si\u0119 na &#8222;.ui&#8221;. Nazwa aplikacji dialogowej nie podlega \u017cadnym regu\u0142om. Nale\u017cy jednak pami\u0119ta\u0107, \u017ce: normalne aplikacje zarz\u0105dzania ko\u0144cz\u0105 si\u0119 na &#8222;Maintenance&#8221;,\u00a0 aplikacje zapyta\u0144 i aplikacje typu Lista ko\u0144cz\u0105 si\u0119 na &#8222;Inquiry&#8221; lub &#8222;Cockpit&#8221;.<\/p>\n<p>Aplikacja dialogowa posiada nazw\u0119, kt\u00f3ra jest wy\u015bwietlana w panelu nawigacji i na pasku g\u0142\u00f3wnym aplikacji. Nazwa aplikacji jest wy\u015bwietlana w panelu nawigacji u\u017cytkownika, je\u015bli spe\u0142nione s\u0105 nast\u0119puj\u0105ce warunki: opcja wy\u015bwietlania i serwisu jest ustawiona na &#8222;Wy\u015bwietlanie, obs\u0142uga&#8221;, u\u017cytkownik posiada niezb\u0119dne uprawnienia do korzystania z aplikacji, funkcja (o ile istnieje) jest aktywowana w Konfiguracji.<\/p>\n<section class=\"document-alert-box indicator\"><div class=\"document-alert-title\">Wskaz\u00f3wka<\/div><div class=\"document-alert-content\">Je\u015bli wygl\u0105d aplikacji ma by\u0107 dostosowany dla okre\u015blonego typu organizacji, nale\u017cy odpowiednio dopasowa\u0107 klas\u0119 Java &#8222;com.cisag.app.multiorg.log.ApplicationRegistry&#8221;.<\/div><\/section>\n<p>Aplikacja musi by\u0107 typu &#8222;Dialog&#8221;. Specjalne zastosowanie musi pozosta\u0107 puste. W panelu nawigacji aplikacja jest przypisana do podanego obszaru (framework). Klasa Java zawiera program, kt\u00f3ry ma zosta\u0107 uruchomiony po wywo\u0142aniu aplikacji. Zazwyczaj obszar nazw i nazwa klasy Java s\u0105 takie same jak obszar nazw i nazwa aplikacji.<br \/>\nJe\u015bli aplikacja ma by\u0107 wy\u015bwietlana w menu kontekstowym jednostki biznesowej, to minimalnym wymaganiem jest to, \u017ce akcja &#8222;Load&#8221; musi zosta\u0107 utworzona z parametrem typu Business Object. \u017b\u0105dana jednostka biznesowa musi by\u0107 wprowadzona jako obiekt biznesowy.<\/p>\n<p>Jedna z aplikacji w menu kontekstowym jednostki biznesowej jest wyr\u00f3\u017cniona jako aplikacja domy\u015blna. Ta aplikacja jest okre\u015blana wed\u0142ug okre\u015blonych regu\u0142. Opr\u00f3cz wspomnianych minimalnych wymaga\u0144 dla wy\u015bwietlania w menu kontekstowym, mo\u017cna wprowadzi\u0107 inne specyfikacje, dzi\u0119ki kt\u00f3rym aplikacja b\u0119dzie mia\u0142a &#8222;wy\u017csz\u0105 rang\u0119&#8221;.<\/p>\n<p>Po pierwsze, nazwa parametru akcji &#8222;Load&#8221; mo\u017ce odpowiada\u0107 nazwie jednostki biznesowej. Przyk\u0142adowo, dla jednostki biznesowej com.cisag.app.general.obj.Partner mo\u017cna u\u017cy\u0107 nazwy parametru &#8222;Partner&#8221;.<br \/>\nPo drugie, mo\u017cna wprowadzi\u0107 g\u0142\u00f3wn\u0105 jednostk\u0119 biznesow\u0105, kt\u00f3ra odpowiada\u00a0obiektowi biznesowemu parametru.<\/p>\n<p>Dla ustalenia preferowanej aplikacji w menu kontekstowym przyjmuje si\u0119 nast\u0119puj\u0105c\u0105 narastaj\u0105c\u0105\u00a0 kolejno\u015b\u0107 pod wzgl\u0119dem istotno\u015bci:<br \/>\n&#8211; Akcja<br \/>\n&#8211; Akcja i nazwa parametru<br \/>\n&#8211; Akcja i g\u0142\u00f3wna jednostka biznesowa<br \/>\n&#8211; Akcja, g\u0142\u00f3wna jednostka biznesowa i nazwa parametru<br \/>\nJe\u015bli na najwy\u017cszym poziomie istotno\u015bci znajduje si\u0119 kilka aplikacji, wybierana jest ta aplikacja, kt\u00f3ra znajduje si\u0119 na pierwszym miejscu w kolejno\u015bci alfabetycznej.<\/p>\n<section class=\"document-alert-box indicator\"><div class=\"document-alert-title\">Wskaz\u00f3wka<\/div><div class=\"document-alert-content\">Przy pomocy klasy abstrakcyjnej <em>CisEntityMenuFilter <\/em>mo\u017cna ukry\u0107 aplikacj\u0119 w menu kontekstowym. W tym celu nale\u017cy utworzy\u0107 klas\u0119 Java, kt\u00f3ra dziedziczy po <em>CisEntityMenuFilter<\/em> i implementuje jej abstrakcyjn\u0105 metod\u0119.\u00a0Ta klasa Java musi by\u0107 zarejestrowana na <em>CisInitialiser<\/em>.<\/div><\/section>\n<p>Aktywn\u0105 baz\u0105 danych wymagan\u0105 dla aplikacji dialogowej jest <em>Baza danych OLTP<\/em>, a w rzadkich przypadkach <em>Baza danych OLAP<\/em>. <em>Baza danych repozytorium<\/em> i <em>Baza danych konfiguracji<\/em> s\u0105 wymagane tylko dla aplikacji dialogowych do rozwoju systemu ERP.<\/p>\n<h5 id=\"aplikacja-w-tle\" ><span class=\"ez-toc-section\" id=\"Aplikacja_w_tle\"><\/span>Aplikacja w tle<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Aplikacje dzia\u0142aj\u0105ce w tle s\u0105 u\u017cywane w zadaniach przetwarzania lub uruchamiane za po\u015brednictwem dialogu batch submit. Aplikacje w tle s\u0105 u\u017cywane do wykonywania czasoch\u0142onnych akcji i przetwarzania danych w tle. Do przetwarzania nie jest wymagana dodatkowa interakcja u\u017cytkownika, a podczas przetwarzania u\u017cytkownik mo\u017ce<br \/>\nnormalnie kontynuowa\u0107 swoj\u0105 prac\u0119 z systemem ERP.<\/p>\n<p>Aplikacje w tle musz\u0105 by\u0107 tworzone w obszarze nazw, kt\u00f3ry ko\u0144czy si\u0119 na &#8222;.log&#8221; lub &#8222;.print&#8221;. Aplikacja musi posiada\u0107 typ <em>T\u0142o<\/em>. Szczeg\u00f3lne zastosowanie musi pozosta\u0107 nieuzupe\u0142nione. Klasa Java zawiera program, kt\u00f3ry ma zosta\u0107 uruchomiony po wywo\u0142aniu aplikacji. Obszar nazw i nazwa klasy Java s\u0105 zazwyczaj takie same jak obszar nazw i nazwa aplikacji.<\/p>\n<h5 id=\"aktualizacja-danych-dialogu\" ><span class=\"ez-toc-section\" id=\"Aktualizacja_danych_dialogu\"><\/span>Aktualizacja danych dialogu<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Aktualizacje danych dialogu s\u0105 wykonywane w celu aktualizacji danych, dla kt\u00f3rej u\u017cytkownik musi poda\u0107 dodatkowe informacje. Aktualizacj\u0119 danych mo\u017cna uruchomi\u0107 z poziomu aplikacji <em>Zapytania o aktualizacje danych<\/em>. Wy\u015bwietlana jest pomoc kontekstowa aplikacji oraz maska wprowadzania danych (je\u015bli istnieje), w kt\u00f3rej u\u017cytkownik mo\u017ce wprowadzi\u0107 dodatkowe dane wymagane przez aktualizacj\u0119.<\/p>\n<p>Aktualizacje danych dialogu musz\u0105 by\u0107 tworzone w obszarze nazw, kt\u00f3ra ko\u0144czy si\u0119 na &#8222;.ui&#8221;. Nazwa aplikacji dialogowej nie podlega \u017cadnym regu\u0142om. Jednak nazwa cz\u0119sto sk\u0142ada si\u0119 z &#8222;UPD&#8221; i zlecenia deweloperskiego, np. UPDSUP12345.<br \/>\nAplikacja musi by\u0107 typu <em>Dialog<\/em>. Szczeg\u00f3lne zastosowanie musi by\u0107 ustawione na <em>Aktualizacja danych<\/em>. Aktualizacje danych dialogu s\u0105 zwykle przyporz\u0105dkowane do obszaru (framework) com.cisag.pgm.Update.<\/p>\n<h5 id=\"automatyczna-aktualizacja-danych-w-tle\" ><span class=\"ez-toc-section\" id=\"Automatyczna_aktualizacja_danych_w_tle\"><\/span>Automatyczna aktualizacja danych w tle<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Automatyczna aktualizacja danych w tle jest wykonywana podczas instalacji aktualizacji oprogramowania, kt\u00f3re zawiera dan\u0105 aktualizacj\u0119 danych. Ta aktualizacja danych jest wymagana np. w przypadku, gdy zmieniono obiekt biznesowy i\u00a0 konieczne jest dostosowanie zasobu danych. Automatyczne aktualizacje danych w tle powinny by\u0107 tworzone w<br \/>\nobszarze nazw com.&lt;prefix&gt;.app.update.log. Nazwa aplikacji dialogowej nie podlega \u017cadnym regu\u0142om. Cz\u0119sto<br \/>\nnazwa sk\u0142ada si\u0119 z &#8222;UPD&#8221; i zlecenia deweloperskiego, np. UPDSUP12345.<\/p>\n<p>Aplikacja musi by\u0107 typu <em>T\u0142o<\/em>. Szczeg\u00f3lne zastosowanie musi by\u0107 ustawione na <em>Aktualizacja danych. <\/em>Aktualizacje danych s\u0105 zazwyczaj przyporz\u0105dkowane do obszaru (framework) com.cisag.pgm.Update. Obszar nazw i nazwa klasy Java s\u0105 zwykle takie same obszar nazw i nazwa aplikacji. Klasa Java dla aktualizacji danych w tle musi implementowa\u0107 abstrakcyjn\u0105 klas\u0119 com.cisag.pgm.base.CisUpdateBatchApplication.<\/p>\n<h5 id=\"reczna-aktualizacja-danych-w-tle\" ><span class=\"ez-toc-section\" id=\"Reczna_aktualizacja_danych_w_tle\"><\/span>R\u0119czna aktualizacja danych w tle<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>R\u0119czna aktualizacja danych w tle r\u00f3\u017cni si\u0119 od aktualizacji automatycznej tym, \u017ce nie jest wykonywana podczas instalacji aktualizacji oprogramowania. R\u0119czna aktualizacja danych w tle mo\u017ce by\u0107 wykonana w dowolnym momencie poprzez zlecenie przetwarzania. Aplikacja musi by\u0107 typu <em>T\u0142o<\/em>. Szczeg\u00f3lne zastosowanie musi by\u0107 ustawione na <em>Aktualizacja danych w tle<\/em>.<\/p>\n<h5 id=\"narzedzie\" ><span class=\"ez-toc-section\" id=\"Narzedzie\"><\/span>Narz\u0119dzie<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Narz\u0119dzia s\u0105 uruchamiane w systemie ERP w Toolshell poprzez okre\u015blenie klasy<br \/>\nJava. Klasa Java musi zawiera\u0107 mainMethode.<br \/>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\">public class TestTool {<br \/>\npublic static void main(String[] argv) {<br \/>\n&#8230;.<br \/>\n}<br \/>\n}<\/div><\/section><br \/>\nNarz\u0119dzia s\u0105 tworzone w obszarze nazw ko\u0144cz\u0105cym si\u0119 na &#8222;.tools&#8221;.<br \/>\nTyp musi by\u0107 ustawiony na <em>Tool<\/em>. Szczeg\u00f3lne zastosowanie musi pozosta\u0107 nieuzupe\u0142nione.<\/p>\n<h4 id=\"raport\" ><span class=\"ez-toc-section\" id=\"Raport\"><\/span>Raport<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Raporty s\u0142u\u017c\u0105 do tworzenia dokument\u00f3w raport\u00f3w lub dokument\u00f3w ko\u0144cowych (do wydruku)<br \/>\nza pomoc\u0105 ERP System Output Manager. Uk\u0142ad i parametry raportu i parametry raportu s\u0105 opracowywane z zastosowaniem Crystal Reports.<br \/>\nGotowe pliki raport\u00f3w mo\u017cna zaimportowa\u0107 do systemu ERP i uzupe\u0142ni\u0107 o dodatkowe dane. Dane te obejmuj\u0105 m.in. etykiety parametr\u00f3w i sta\u0142e tekstowe w raporcie.<\/p>\n<h4 id=\"grupa-jednostek-biznesowych\" ><span class=\"ez-toc-section\" id=\"Grupa_jednostek_biznesowych\"><\/span>Grupa jednostek biznesowych<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Grupy jednostek biznesowych s\u0105 stosowane do zdefiniowania uprawnie\u0144.<\/p>\n<h4 id=\"obiekt-biznesowy\" ><span class=\"ez-toc-section\" id=\"Obiekt_biznesowy\"><\/span>Obiekt biznesowy<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Obiekt biznesowy jest techniczn\u0105 definicj\u0105 zmiennej funkcjonalnej, dla kt\u00f3rej okre\u015blone specyfikacje (instancje) s\u0105 zapisywane w bazie danych w oddzielnej tabeli. Obiekt biznesowy (BO) stanowi przede wszystkim kontener danych bez logiki funkcjonalnej. Posiada obszar nazw i konkretn\u0105 nazw\u0119. Dane, kt\u00f3re maja by\u0107 przechowywane, s\u0105 opisywane za pomoc\u0105 jednej lub kilku definicji atrybut\u00f3w (w skr\u00f3cie <em>atrybuty<\/em>). Obiekt biznesowy mo\u017ce dziedziczy\u0107 atrybuty z definicji cz\u0119\u015bciowej.<\/p>\n<p>Obiekt biznesowy to wielko\u015b\u0107 techniczna, kt\u00f3ra mo\u017ce by\u0107 odczytana, zapisana i usuwana przez us\u0142ug\u0119 trwa\u0142o\u015bci danych (persystencja) systemu ERP. Dokonuje si\u0119 przy tym konwertowanie pomi\u0119dzy obiektowym modelem danych u\u017cywanym w aplikacji a relacyjnym modelem danych. Inne w\u0142a\u015bciwo\u015bci, kt\u00f3re nale\u017cy okre\u015bli\u0107 to rodzaj danych, oczekiwany rozmiar danych i strategia pami\u0119ci podr\u0119cznej (cache). S\u0142u\u017cy to przede wszystkim systemowi do optymalizacji wydajno\u015bci i minimalizacji dost\u0119p\u00f3w do baz danych.<\/p>\n<p>Obiekt biznesowy, zwany r\u00f3wnie\u017c definicj\u0105 obiektu biznesowego, jest podstaw\u0105 generowania klas i tabel. Wygenerowane klasy Java enkapsuluj\u0105 wykorzystanie bazy danych i zapewniaj\u0105 aplikacji dost\u0119p do danych instancji obiekty biznesowego. Dla obiektu biznesowego generowana jest tabela g\u0142\u00f3wna i tabele pomocnicze ze strukturami dost\u0119pu z przechowywanych definicji indeks\u00f3w.<\/p>\n<h5 id=\"atrybuty\" ><span class=\"ez-toc-section\" id=\"Atrybuty\"><\/span>Atrybuty<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Atrybut nie jest niezale\u017cnym typem obiektu deweloperskiego, ale cz\u0119\u015bci\u0105 definicji obiektu biznesowego, cz\u0105stki <em>part <\/em>lub rozszerzenia. Atrybut ma nazw\u0119, kt\u00f3ra jest unikalna w obiekcie deweloperskim (np. obiekcie biznesowym). Posiada typ okre\u015blony przez przyporz\u0105dkowany logiczny typ danych. Atrybut mo\u017ce by\u0107 r\u00f3wnie\u017c zdefiniowany jako array okre\u015blonego typu. W klasie Java wygenerowanej dla obiektu biznesowego atrybuty staj\u0105 si\u0119 zmiennymi, kt\u00f3re zawieraj\u0105 warto\u015bci funkcjonalne. Jak jak zwykle w przypadku klas Java, mo\u017cna wykona\u0107 zapytanie o warto\u015bci za pomoc\u0105 metody <em>get<\/em><br \/>\n(dla boolowskiej metody <em>is<\/em>)\u00a0i zmienia\u0107 je za pomoc\u0105 metody <em>set.<\/em><\/p>\n<h5 id=\"atrybuty-nsl\" ><span class=\"ez-toc-section\" id=\"Atrybuty_NSL\"><\/span>Atrybuty NSL<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>NLS to skr\u00f3t od National Language Support. Atrybut NLS jest atrybutem wieloj\u0119zycznym opartym na typie pierwotnym <em>string<\/em>, dla kt\u00f3rego ustawiono cech\u0119 <em>multilingual capable<\/em>. Je\u015bli atrybutowi przypisano identyfikowalny logiczny typ danych, w\u00f3wczas warto\u015b\u0107 mo\u017ce by\u0107 dost\u0119pna w kilku j\u0119zykach. T\u0142umaczenia atrybutu s\u0105 zapisywane w oddzielnym obiekcie biznesowym NLS. Jego nazwa sk\u0142ada si\u0119 z nazwy obiektu biznesowego, kt\u00f3ry zawiera identyfikowalny atrybut\u00a0 oraz nazwy kolumny tabeli bazy danych identyfikowalnego atrybutu. Obiekt biznesowy NLS jest automatycznie tworzony w paczce NLS, kt\u00f3ra r\u00f3\u017cni si\u0119 od pierwotnej paczki tym, \u017ce po skr\u00f3cie systemu w obszarze nazw dodany jest string \u201enls&#8221;, np. <em>com.cisag.nls<\/em>. Baza danych (mandant) zawsze ma przyporz\u0105dkowany j\u0119zyk g\u0142\u00f3wny i ewentualnie kilka j\u0119zyk\u00f3w dodatkowych. Warto\u015b\u0107 w g\u0142\u00f3wnym j\u0119zyku atrybutu jest zapisywana w tabeli powi\u0105zanego obiektu biznesowego i dlatego mo\u017ce by\u0107 skutecznie wyszukiwana w zapytaniach. Warto\u015bci j\u0119zyk\u00f3w dodatkowych dla atrybutu, czyli t\u0142umaczenia, s\u0105 przechowywane w oddzielnej tabeli obiektu NLS. Z punktu widzenia programisty aplikacji dost\u0119p do atrybutu NLS jest maksymalnie transparentny.<\/p>\n<p>Poni\u017cszy rysunek przedstawia obiekt biznesowy com.cisag.app.edu.obj.Book z wieloj\u0119zycznym atrybutem <em>description<\/em>. Obiekt biznesowy NLS com.cisag.nls.app.edu.obj.Book_DESCRIPTION, utworzony przez system, zawiera wszelkie j\u0119zyki dodatkowe dla atrybutu.<\/p>\n<figure id=\"attachment_7766\" aria-describedby=\"caption-attachment-7766\" style=\"width: 508px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-7766 size-full\" src=\"https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2024\/01\/diagram-UML.png\" alt=\"\" width=\"508\" height=\"151\" srcset=\"https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/diagram-UML.png 508w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/diagram-UML-300x89.png 300w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/diagram-UML-50x15.png 50w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/diagram-UML-320x95.png 320w\" sizes=\"auto, (max-width: 508px) 100vw, 508px\" \/><figcaption id=\"caption-attachment-7766\" class=\"wp-caption-text\">Diagram UML dla Business Object Book<\/figcaption><\/figure>\n<p><em>Indeksy<\/em><\/p>\n<p>Indeks jest struktur\u0105 dost\u0119pu do zapisanych instancji obiektu biznesowego. Instancja jest identyfikowana poprzez<br \/>\nwarto\u015bci specjalnie oznaczonych atrybut\u00f3w, tzw. atrybut\u00f3w kluczowych.<br \/>\nRozr\u00f3\u017cnia si\u0119 nast\u0119puj\u0105ce indeksy:<\/p>\n<ul>\n<li>Primary key<\/li>\n<li>Business key<\/li>\n<li>Secondary key<\/li>\n<li>Non unique index<\/li>\n<\/ul>\n<p>Obiekt biznesowy z regu\u0142y zawsze posiada <em>Primary key <\/em>i <em>Business key<\/em>, kt\u00f3re s\u0105 unikalnymi indeksami. W ramach danego obiektu biznesowego indeks posiada unikaln\u0105 nazw\u0119. W klasie obiekt\u00f3w biznesowych dla ka\u017cdego zdefiniowanego indeksu jest generowana metoda w postaci buildIndexnameKey(&#8230;). Metoda ta dostarcza klucz techniczny dla us\u0142ugi trwa\u0142o\u015bci do warto\u015bci klucza podstawowego danej instancji obiektu biznesowego. W ten spos\u00f3b us\u0142uga us\u0142ugi trwa\u0142o\u015bci mo\u017ce pobiera\u0107 instacj\u0119 z bazy danych.<\/p>\n<p>Zasadniczo indeksy przyspieszaj\u0105 dost\u0119py odczytu, ale spowalniaj\u0105 dost\u0119py zapisu (create, update, delete), poniewa\u017c zarz\u0105dzanie indeksami wymaga dodatkowego nak\u0142adu pracy.<\/p>\n<p><em>Primary key<\/em><\/p>\n<p>Primary key o sta\u0142ej nazwie <em>Primary<\/em> opiera si\u0119 na unikalnych warto\u015bciach klucza podstawowego. Klucz podstawowy obiektu biznesowego zazwyczaj sk\u0142ada si\u0119 tylko z atrybutu opartego na logicznym typie danych typu prymitywnego <em>guid<\/em>. Jest to sztucznie wprowadzony klucz i mo\u017ce by\u0107 r\u00f3wnie\u017c okre\u015blany jako to\u017csamo\u015b\u0107 obiektu. Umo\u017cliwia identyfikacj\u0119 instancji obiektu biznesowego i skuteczny dost\u0119p ze wzgl\u0119du na jego niewielk\u0105 d\u0142ugo\u015b\u0107. Identyfikuje instancj\u0119 obiektu biznesowego r\u00f3wnie\u017c wtedy, gdy zmieni si\u0119 klucz funkcjonalny. Wszystkie atrybuty w kluczu podstawowym s\u0105 polami obowi\u0105zkowymi. Ten Indeks ten jest u\u017cywany jako podstawowy indeks tabeli w bazie danych.<\/p>\n<p><em>Business key<\/em><\/p>\n<p>Business key stanowi unikalny klucz funkcjonalny i jest zazwyczaj odczytywalny, np. numer artyku\u0142u, kod kraju. Jest\u00a0zwykle u\u017cywany w aplikacjach biznesowych do identyfikacji instancji obiektu biznesowego. Nazwa klucza<br \/>\nbiznesowego powinna zaczyna\u0107 si\u0119 od przedrostka &#8222;By&#8221;. Je\u015bli na przyk\u0142ad<br \/>\nkluczem funkcjonalnym obiektu biznesowego jest atrybut &#8222;code&#8221;, indeks powinien nazywa\u0107 si\u0119 &#8222;ByCode&#8221;. Je\u015bli klucz funkcjonalny sk\u0142ada si\u0119 z kilku atrybut\u00f3w, nale\u017cy wybra\u0107 odpowiedni\u0105 nazw\u0119. Dla tabeli bazy danych tworzony jest unikalny indeks przy u\u017cyciu atrybut\u00f3w klucza.<\/p>\n<p><em>Secondary key<\/em><\/p>\n<p>Istnieje mo\u017cliwo\u015b\u0107 zdefiniowania dodatkowego indeksu pomocniczego, kt\u00f3ry jest oparty na innym unikalnym kluczu.<br \/>\nUnikalny indeks jest tworzony dla tabeli bazy danych przy u\u017cyciu atrybut\u00f3w klucza. Nazwy<br \/>\npowinny by\u0107 przypisywane w taki sam spos\u00f3b jak nazwy kluczy biznesowych.<\/p>\n<p><em>Non unique index<\/em><\/p>\n<p>Indeks nieunikalny opiera si\u0119 na atrybutach, kt\u00f3rych warto\u015bci mog\u0105 by\u0107 wieloznaczne. Indeks jest tworzony na tabeli dla znajduj\u0105cych si\u0119 w niej atrybut\u00f3w (duplikaty s\u0105 zatem dozwolone), przy czym w jednym dost\u0119pie mo\u017ce by\u0107 dostarczone wiele instancji. Przyk\u0142adem jest obiekt biznesowy <em>com.cisag.app.general.obj.Item<\/em>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-7768 size-full\" src=\"https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2024\/01\/Non-unique-index.png\" alt=\"\" width=\"711\" height=\"181\" srcset=\"https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/Non-unique-index.png 711w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/Non-unique-index-300x76.png 300w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/Non-unique-index-50x13.png 50w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/Non-unique-index-600x153.png 600w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/Non-unique-index-320x81.png 320w\" sizes=\"auto, (max-width: 711px) 100vw, 711px\" \/><\/p>\n<p>W tym przyk\u0142adzie w klasie &#8222;com.cisag.app.general.obj.Item&#8221; generowane s\u0105 nast\u0119puj\u0105ce metody do indeks\u00f3w z zastosowaniem nazw indeks\u00f3w:<br \/>\nDla <em>Non unique index<\/em> nie jest generowana \u017cadna metoda.<\/p>\n<p><em>Relacje<\/em><\/p>\n<p>Relacja jest funkcjonalnym po\u0142\u0105czeniem pomi\u0119dzy dwoma obiektami biznesowymi.<\/p>\n<section class=\"document-alert-box indicator\"><div class=\"document-alert-title\">Wskaz\u00f3wka<\/div><div class=\"document-alert-content\">\u0179r\u00f3d\u0142em relacji mo\u017ce by\u0107 nie tylko obiekt biznesowy, ale r\u00f3wnie\u017c <em>part, view <\/em>lub <em>extension. <\/em>W niniejszym dokumencie dla u\u0142atwienia opisane zosta\u0142y tylko relacje pomi\u0119dzy obiektami biznesowymi.<\/div><\/section>\n<p>Aby odzwierciedli\u0107 po\u0142\u0105czenie funkcjonalne, dla obiektu biznesowego okre\u015bla si\u0119 definicj\u0119 relacji (w skr\u00f3cie: relacja). W systemie ERP relacje s\u0105 zawsze <em>unidirektional<\/em>, tzn. prowadz\u0105 tylko od \u017ar\u00f3d\u0142a do celu. Je\u015bli potrzebne s\u0105 oba kierunki, nale\u017cy osobno utworzy\u0107 drug\u0105 relacj\u0119. Relacja mo\u017ce posiada\u0107 kardynalno\u015b\u0107 &#8222;1-1&#8221; lub &#8222;1-n&#8221;. Relacje opcjonalne nie s\u0105 modelowane oddzielnie i s\u0105 uwzgl\u0119dnione w kardynalno\u015bci. Relacja jest cz\u0119\u015bci\u0105 definicji obiektu biznesowego. Ma unikaln\u0105 nazw\u0119 i okre\u015bla przyporz\u0105dkowanie atrybut\u00f3w \u017ar\u00f3d\u0142owych do atrybut\u00f3w docelowych. W klasie Java nale\u017c\u0105cej do obiektu biznesowego generowana jest metoda retrieveRelationshipName dla ka\u017cdej podanej relacji.<br \/>\n(&#8230;).<\/p>\n<p><em>Relacja 1-1<\/em><\/p>\n<p>Relacja o kardynalno\u015bci &#8222;1-1&#8221; przypisuje do instancji obiektu biznesowego maksymalnie jedn\u0105 inn\u0105 instancj\u0119 obiektu biznesowego. Na podstawie warto\u015bci atrybut\u00f3w \u017ar\u00f3d\u0142owych wyszukiwane s\u0105 te same warto\u015bci w atrybutach docelowych, aby zidentyfikowa\u0107 cel relacji. Dla zapewnienia unikalno\u015bci relacji, w atrybutach docelowych musi by\u0107 zdefiniowany unikalny indeks, tj. <em>primary key<\/em>, <em>business key<\/em> lub <em>secondary key. <\/em>Integralno\u015b\u0107 referencyjna nie jest sprawdzana przez system.<\/p>\n<p><em>Relacja 1-n<\/em><\/p>\n<p>Relacja o kardynalno\u015bci &#8222;1-n&#8221; przypisuje do instancji obiekty biznesowego jedn\u0105 lub wiele instancji tego samego obiektu biznesowego, ale mo\u017ce r\u00f3wnie\u017c nie przypisywa\u0107 \u017cadnej instancji. Na podstawie warto\u015bci atrybut\u00f3w \u017ar\u00f3d\u0142owych wyszukiwane s\u0105 te same warto\u015bci w atrybutach docelowych. Nazwa takiej relacji powinna by\u0107 podana w liczbie mnogiej, aby zaznaczy\u0107 kardynalno\u015b\u0107.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\">Poni\u017csza ilustracja przedstawia przyk\u0142ad relacji mi\u0119dzy obiektami biznesowymi <em>Country<\/em> i <em>Region<\/em>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-7771 size-full\" src=\"https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2024\/01\/Beziehung-1n.png\" alt=\"\" width=\"591\" height=\"202\" srcset=\"https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/Beziehung-1n.png 591w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/Beziehung-1n-300x103.png 300w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/Beziehung-1n-50x17.png 50w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/Beziehung-1n-320x109.png 320w\" sizes=\"auto, (max-width: 591px) 100vw, 591px\" \/><\/p>\n<p>W systemie ERP mo\u017cna w nast\u0119puj\u0105cy spos\u00f3b modelowa\u0107 te relacje:<\/p>\n<p>Jeden kraj ma wiele region\u00f3w:<\/p>\n<table style=\"border-collapse: collapse; width: 71.375%;\">\n<tbody>\n<tr>\n<td style=\"width: 32.9247%; text-align: center;\"><strong>Nazwa relacji<\/strong><\/td>\n<td style=\"width: 38.4503%; text-align: center;\"><strong>Regiony<\/strong><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 32.9247%;\">Obiekt \u017ar\u00f3d\u0142owy<\/td>\n<td style=\"width: 38.4503%;\">com.cisag.app.general.obj.Country<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 32.9247%;\">Obiekt docelowy<\/td>\n<td style=\"width: 38.4503%;\">com.cisag.app.general.obj.Region<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 32.9247%;\">Kardynalno\u015b\u0107<\/td>\n<td style=\"width: 38.4503%;\">1-n<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 32.9247%;\">Mapping atrybutu<\/td>\n<td style=\"width: 38.4503%;\">Country.guid auf Region.country<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>W klasie obiektu biznesowego <em>com.cisag.app.general.obj.Country<\/em> generowana jest nast\u0119puj\u0105ca metoda dla relacji:<br \/>\n<em>public CisObjectIterator retrieveRegions()<\/em><\/p>\n<p>Jeden region nale\u017cy dok\u0142adnie do jednego kraju:<\/p>\n<table style=\"border-collapse: collapse; width: 71.375%;\">\n<tbody>\n<tr>\n<td style=\"width: 32.9247%; text-align: center;\"><strong>Nazwa relacji<\/strong><\/td>\n<td style=\"width: 38.4503%; text-align: center;\"><strong>Regiony<\/strong><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 32.9247%;\">Obiekt \u017ar\u00f3d\u0142owy<\/td>\n<td style=\"width: 38.4503%;\">com.cisag.app.general.obj.Region<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 32.9247%;\">Obiekt docelowy<\/td>\n<td style=\"width: 38.4503%;\">com.cisag.app.general.obj.Country<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 32.9247%;\">Kardynalno\u015b\u0107<\/td>\n<td style=\"width: 38.4503%;\">1-n<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 32.9247%;\">Mapping celu<\/td>\n<td style=\"width: 38.4503%;\">Primary<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 32.9247%;\">Mapping atrybutu<\/td>\n<td style=\"width: 38.4503%;\">Region.country auf Country.guid<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>W klasie obiektu biznesowego <em>com.cisag.app.general.obj.Regions<\/em>\u00a0generowana jest nast\u0119puj\u0105ca metoda dla relacji:<br \/>\n<em>public Country retrieveCountry()<\/em><\/div><\/section>\n<p><em>Zale\u017cno\u015bci pomi\u0119dzy obiektami biznesowymi<\/em><\/p>\n<p>Obiekty biznesowe i modelowane przez nie zmienne funkcjonalne s\u0105 zazwyczaj niezale\u017cne, tzn. istnienie jednego obiektu biznesowego nie jest powi\u0105zane z istnieniem innego. Niekt\u00f3re zmienne funkcjonalne nie istniej\u0105 samodzielnie, ale s\u0105 zale\u017cne od innych. Je\u015bli pozycja zlecenia nale\u017cy dok\u0142adnie do jednego nag\u0142\u00f3wka zlecenia, to nie mo\u017ce istnie\u0107 bez przypisanego jej nag\u0142\u00f3wka zlecenia. Te obie zmienne funkcjonalne, nag\u0142\u00f3wek zlecenia i pozycja zlecenia, razem tworz\u0105 logiczn\u0105 jednostk\u0119 &#8211; zlecenie. Nag\u0142\u00f3wek zlecenia jest niejako reprezentantem zlecenia, a jego w\u0142a\u015bciwo\u015bci s\u0105 danymi istotnymi dla przedmiotowego zlecenia. Do modelowania takich zale\u017cno\u015bci s\u0142u\u017cy typ obiekt\u00f3w biznesowych.<\/p>\n<h5 id=\"typy-obiektow-biznesowych\" ><span class=\"ez-toc-section\" id=\"Typy_obiektow_biznesowych\"><\/span>Typy obiekt\u00f3w biznesowych<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Obiekty biznesowe istniej\u0105 zazwyczaj w znormalizowanej formie. Zdarza si\u0119, \u017ce rzeczywista zmienna funkcjonalna jest opisana przez wi\u0119cej ni\u017c jeden obiekt biznesowy. Niemniej jednak, zawsze istnieje jeden g\u0142\u00f3wny obiekt biznesowy, nag\u0142\u00f3wek jednostki biznesowej. Wszystkie inne obiekty biznesowe w tej grupie, <em>Supplements<\/em> i <em>Dependents<\/em>, s\u0105 zale\u017cne od g\u0142\u00f3wnego obiektu biznesowego. Ca\u0142a grupa tworzy jednostk\u0119 biznesow\u0105. Nag\u0142\u00f3wek jednostki biznesowej, <em>Supplements<\/em> i <em>Dependents<\/em> tworz\u0105 hierarchiczn\u0105 struktur\u0119 z jednoznaczn\u0105 przynale\u017cno\u015bci\u0105.<br \/>\nW definicji obiektu biznesowego okre\u015bla si\u0119, czy jest on suplementem (przypisany typ: <em>Supplement<\/em>), elementem zale\u017cnym (przypisany typ: <em>Dependent<\/em>), czy g\u0142\u00f3wnym obiektem biznesowym (przypisany typ: <em>Business Entity<\/em>).<\/p>\n<p><em>Jednostka biznesowa (Business Entity)<\/em><\/p>\n<p>Obiekt biznesowy typu <em>Business Entity<\/em> jest szczeg\u00f3lnym przyk\u0142adem grupy obiekt\u00f3w biznesowych, od kt\u00f3rej zale\u017c\u0105 inne obiekty biznesowe (<em>Supplements<\/em> i <em>Dependents<\/em>). Ca\u0142a grupa opisuje modelowan\u0105 jednostk\u0119 biznesow\u0105 (wielko\u015b\u0107 funkcjonalna). Cz\u0119sto zdarza si\u0119, \u017ce jednostka biznesowa jest modelowana tylko przez jeden obiekt biznesowy.<\/p>\n<p><em>Supplement<\/em><\/p>\n<p>Obiekt biznesowy typu <em>Supplement<\/em> stanowi uzupe\u0142nienie nag\u0142\u00f3wka jednostki biznesowej. <em>Supplement<\/em> posiada specjaln\u0105 relacj\u0119 o nazwie &#8222;_businessObject&#8221;, kt\u00f3ra wskazuje na powi\u0105zanie z nag\u0142\u00f3wkiem jednostki biznesowej (kardynalno\u015b\u0107 &#8222;1-1&#8221;). Us\u0142uga trwa\u0142o\u015bci systemu ERP wymaga tej (technicznej) relacji, aby zapewni\u0107 obs\u0142ug\u0119 dziennika modyfikacji i informacji o zmianach. W przypadku zmiany suplementu, dane te s\u0105 wprowadzane do nag\u0142\u00f3wka jednostki biznesowej i suplementu.<\/p>\n<p>Suplementy pe\u0142ni\u0105 t\u0119 sam\u0105 funkcj\u0119 co rozszerzenia. Mog\u0105 by\u0107 u\u017cywane do uzupe\u0142niania obiekt\u00f3w biznesowych o atrybuty, jednak bez uzupe\u0142niania tabeli g\u0142\u00f3wnego obiektu biznesowego. Dlatego zalecane jest u\u017cywanie suplement\u00f3w zamiast rozszerze\u0144.<br \/>\nPoni\u017csza ilustracja przedstawia przyk\u0142ad jednostki biznesowej &#8222;Country&#8221; z dwoma suplementami &#8222;ExtCountry&#8221;, z kt\u00f3rych ka\u017cdy rozszerza g\u0142\u00f3wny obiekt BusinessObject o jeden atrybut.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-7776 size-full aligncenter\" src=\"https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2024\/01\/supplement.png\" alt=\"\" width=\"614\" height=\"348\" srcset=\"https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/supplement.png 614w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/supplement-300x170.png 300w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/supplement-50x28.png 50w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/supplement-600x340.png 600w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/supplement-320x181.png 320w\" sizes=\"auto, (max-width: 614px) 100vw, 614px\" \/><\/p>\n<p><em>Dependent<\/em><\/p>\n<p>Obiekt biznesowy typu <em>Dependent <\/em>stanowi uzupe\u0142nienie nag\u0142\u00f3wka jednostki biznesowej. <em>Dependent <\/em>posiada specjaln\u0105 relacj\u0119 o nazwie \u201e_entity\u201c, kt\u00f3ra wskazuje na powi\u0105zanie z nag\u0142\u00f3wkiem jednostki biznesowej (kardynalno\u015b\u0107 &#8222;1-1&#8221;). Us\u0142uga trwa\u0142o\u015bci systemu ERP wymaga tej (technicznej) relacji, aby zapewni\u0107 obs\u0142ug\u0119 dziennika modyfikacji i informacji o zmianach. W przypadku zmiany <em>Dependent<\/em>, dane te s\u0105 wprowadzane do nag\u0142\u00f3wka jednostki biznesowej i do <em>Dependent<\/em>.<\/p>\n<p>Poni\u017cszy rysunek przedstawia przyk\u0142ad jednostki biznesowej <em>Partner<\/em> z wybranymi elementami <em>Dependent <\/em>&#8222;CommunicationData&#8221; i &#8222;FiscalInformation&#8221;. Dodatkowo pokazana jest relacja elementu <em>Dependent <\/em> &#8222;CommunicationData&#8221; do jednostki biznesowej &#8222;CommunicationMethod&#8221;, kt\u00f3ra nie posiada \u017cadnych element\u00f3w <em>Dependent<\/em>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-7781 size-full\" src=\"https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2024\/01\/Dependent.png\" alt=\"\" width=\"696\" height=\"357\" srcset=\"https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/Dependent.png 696w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/Dependent-300x154.png 300w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/Dependent-50x26.png 50w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/Dependent-600x308.png 600w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/Dependent-320x164.png 320w\" sizes=\"auto, (max-width: 696px) 100vw, 696px\" \/><\/p>\n<p><em>Funkcjonalno\u015bci systemu ERP dla obiekt\u00f3w biznesowych<\/em><\/p>\n<p>Jednostka biznesowa jest centralnym elementem wielu rozwi\u0105za\u0144 funkcjonalnych. Do zarz\u0105dzania ka\u017cd\u0105 jednostk\u0105 biznesow\u0105 s\u0142u\u017cy zazwyczaj dok\u0142adnie jedna aplikacja. System automatycznie obs\u0142uguje specjalne atrybuty, takie jak<br \/>\ntw\u00f3rca i czas utworzenia, ostatni edytor, czas ostatniej zmiany i system oryginalny. Na poziomie obiektu biznesowego<br \/>\nodbywa si\u0119 wersjonowanie instancji i definicje obowi\u0105zywania zale\u017cne od czasu. Dzi\u0119ki dziennikowi modyfikacji system zapewnia przechowywanie historii zmian obiektu biznesowego. Uprawnienia s\u0105 r\u00f3wnie\u017c definiowane na podstawie jednostek biznesowych.<\/p>\n<p>W polach jednostek numer\u00f3w GUI, kt\u00f3re reprezentuj\u0105 jednostk\u0119 biznesow\u0105 w interfejsie aplikacji, dost\u0119pne s\u0105 funkcje specjalne. Korzystaj\u0105c z opcji Drag&amp;Drop mo\u017cna zapisa\u0107 konkretn\u0105 instancj\u0119 obiektu biznesowego w ulubionych lub poprzez przeci\u0105gni\u0119cie jej na ikon\u0119 symbolizuj\u0105c\u0105 dan\u0105 funkcj\u0119 uruchomi\u0107 t\u0119 funkcj\u0119 za pomoc\u0105 tej jednostki jako parametru przeniesienia.\u00a0Z menu kontekstowego pola jednostki u\u017cytkownik przej\u015b\u0107 do odpowiednich aplikacji i uzyska\u0107 dost\u0119p do dalszych w\u0142a\u015bciwo\u015bci jednostki biznesowej.<\/p>\n<h5 id=\"generowane-klasy-java\" ><span class=\"ez-toc-section\" id=\"Generowane_klasy_Java\"><\/span>Generowane klasy Java<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>System generuje co najmniej trzy klasy Java na podstawie definicji obiektu biznesowego<br \/>\ntrzy klasy Java: klasa g\u0142\u00f3wna, klasa <em>state<\/em> i klasa <em>mapper<\/em>.<br \/>\nKlasy Java s\u0105 przechowywane w pakiecie Java odpowiadaj\u0105cym obszarowi nazw pod nazw\u0105 obiektu biznesowego (lub z przyrostkiem &#8222;_State&#8221; lub &#8222;_Mapper&#8221;).<\/p>\n<p>Deweloper u\u017cywa g\u0142\u00f3wnej klasy w aplikacji do uzyskania dost\u0119pu do instancji obiektu biznesowego, podczas gdy klasy <em>state<\/em> i <em>mapper<\/em> s\u0105 wymagane przez us\u0142ug\u0119 trwa\u0142o\u015bci, w celu realizacji dost\u0119pu do bazy danych. Klasa g\u0142\u00f3wna zawiera metody get&#8230;()-, set&#8230;()- lub is&#8230;()-metody (dla Boolean) umo\u017cliwiaj\u0105ce dost\u0119p do atrybut\u00f3w obiektu biznesowego. Odpowiednie metody build..Key() s\u0105 generowane dla zdefiniowanych indeks\u00f3w, kt\u00f3re s\u0105 u\u017cywane do odczytu instancji za pomoc\u0105 unikalnych warto\u015bci klucza z us\u0142ug\u0105 trwa\u0142o\u015bci. Dla wskazanych relacji s\u0105 generowane metody retrieve&#8230;(), kt\u00f3re mo\u017cna wykorzysta\u0107 do wyszukiwania przyporz\u0105dkowanych obiekt\u00f3w biznesowych.<\/p>\n<h5 id=\"atrybuty-daty-i-znacznika-czasu\" ><span class=\"ez-toc-section\" id=\"Atrybuty_daty_i_znacznika_czasu\"><\/span>Atrybuty daty i znacznika czasu<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Daty i godziny przechowywane w systemie ERP,tak zwane CisDates, zawsze odnosz\u0105 si\u0119 do danej strefy czasowej.<br \/>\nStrefa czasowa jest okre\u015blana przez aplikacj\u0119 w momencie wprowadzania. Nie mo\u017cna ju\u017c zmieni\u0107 strefy czasowej\u00a0 wprowadzenia daty i godziny. Sk\u0142adnik daty lub godziny jest zawsze przechowywany w bazie danych w odniesieniu do strefy czasowej GMT.<\/p>\n<p>Okre\u015blenie daty jest zawsze zapisywane w postaci ustandaryzowanej do godziny 0:00. Standaryzacja jest realizowana poprzez pole GUI (CisDateField), a nie automatycznie przez us\u0142ug\u0119 trwa\u0142o\u015bci. W przeciwnym razie jest to zadaniem dewelopera. Istniej\u0105 typy dat: CisObjectDate, CisAttributeDate, CisObjectDateUntil i CisAttributeDateUntil (zob.<br \/>\nobszar nazw <em>com.cisag.pgm.datatype<\/em>).<\/p>\n<p>Okre\u015blenie znacznik\u00f3w czasowych to specyfikacja daty i godziny. Dost\u0119pne typy znacznik\u00f3w czasowych to: CisObjectTimeStamp i CisAttributeTimeStamp.<br \/>\nWizualizacja zawsze odbywa si\u0119 w odniesieniu do strefy czasowej poprzez odpowiednie pole GUI (CisDateField). Tylko je\u015bli strefa czasowa wprowadzenia r\u00f3\u017cni si\u0119 od strefy czasowej kontekstu czasu wykonywania (runtime),<br \/>\nwy\u015bwietlana jest strefa czasowa wprowadzenia.<\/p>\n<p><em>Typy CisDate: CisObjectDate, CisObjectTimeStamp<\/em><\/p>\n<p>Atrybut typu CisObjectDate zapisuje dat\u0119 znormalizowan\u0105 do godziny 0:00 w odniesieniu do strefy czasowej obowi\u0105zuj\u0105cej w momencie wpisu. Logiczny typ danych atrybutu musi zawsze pochodzi\u0107 od logicznego typu danych<br \/>\n<em>com.cisag.pgm.datatype.CisObjectDate.<\/em><\/p>\n<p>Atrybut typu CisObjectTimeStamp zapisuje czas w odniesieniu do strefy czasowej obowi\u0105zuj\u0105cej w momencie wpisu. Logiczny typ danych atrybutu musi zawsze pochodzi\u0107 od logicznego typu danych <em>com.cisag.pgm.datatype.CisObjectTimeStamp<\/em>.<\/p>\n<p>Je\u015bli obiekt biznesowy zawiera atrybut tego typu, atrybut _timeZoneGuid jest automatycznie dodawany do obiektu biznesowego.<br \/>\nPrzechowuje on identyfikator GUID strefy czasowej wprowadzania dla wszystkich atrybut\u00f3w typu<br \/>\ntypu <em>CisObjectDate<\/em> i <em>CisObjectTimeStamp<\/em>. Oznacza to, \u017ce wszystkie te atrybuty musz\u0105 odnosi\u0107 si\u0119 do tej samej strefy czasowej. Atrybut _timeZoneGuid jest uzupe\u0142niany odpowiedni\u0105 warto\u015bci\u0105 przez aplikacj\u0119. Po pierwszym zapisaniu instancji obiektu biznesowego warto\u015b\u0107 tego atrybutu nie mo\u017ce by\u0107 ju\u017c zmieniona.<\/p>\n<p><em>Typy CisDate: CisAttributeDate, CisAttributeTimeStamp<\/em><\/p>\n<p>Atrybut typu <em>CisAttributeDate <\/em>zapisuje dat\u0119 znormalizowan\u0105 do godziny 0:00 w odniesieniu do danej strefy czasowej. Logiczny typ danych atrybutu musi zawsze pochodzi\u0107 od logicznego typu danych<br \/>\n<em>com.cisag.pgm.datatype.CisAttributeDate.<\/em><\/p>\n<p>Atrybut typu <em>CisAttributeTimeStamp<\/em> zapisuje czas w odniesieniu do danej strefy czasowej. Logiczny typ danych atrybutu musi zawsze pochodzi\u0107 od logicznego typu danych <em>com.cisag.pgm.datatype.CisAttributeTimeStamp.<\/em><\/p>\n<p>Logiczne typy danych s\u0105 oparte na specjalnej cz\u0105stce <em>com.cisag.sys.kernel.obj.CisDate<\/em>, kt\u00f3ra opr\u00f3cz informacji o czasie zawiera r\u00f3wnie\u017c identyfikator GUID w\u0142a\u015bciwej strefy czasowej. Oznacza to, \u017ce te atrybuty obiektu biznesowego mog\u0105 odnosi\u0107 si\u0119 do r\u00f3\u017cnych stref czasowych, poniewa\u017c ka\u017cdy z nich zapisa\u0142 w\u0142asn\u0105 stref\u0119 czasow\u0105 wprowadzenia\/wpisu.<\/p>\n<p><em>Typy CisDate: CisObjectDateUntil, CisAttributeDateUntil<\/em><\/p>\n<p>Atrybut typu <em>CisObjectDateUntil<\/em> jest specjalnym atrybutem <em>CisObjectDate<\/em>. Logiczny typ danych atrybutu musi zawsze pochodzi\u0107 od logicznego typu danych <em>com.cisag.pgm.datatype.CisObjectDateUntil<\/em>.<br \/>\nAtrybut typu <em>CisAttributeDateUntil<\/em> jest specjalnym atrybutem <em>CisAttributeDate<\/em>. Logiczny typ danych atrybutu musi zawsze pochodzi\u0107 od logicznego typu danych <em>com.cisag.pgm.datatype.CisAttributeDateUntil<\/em>.<\/p>\n<p>Te typy s\u0105 u\u017cywane do okre\u015blania &#8222;daty do&#8221; w przedziale czasu. Do wskazanej daty jest automatycznie dodawany jeden dzie\u0144, a warto\u015b\u0107 ta jest zapisywana w bazie danych. Natomiast na potrzeby wizualizacji od zapisanej daty odejmowany jest jeden dzie\u0144, przez co u\u017cytkownik nie dostrzega si\u0119 r\u00f3\u017cnicy.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\">Zamkni\u0119ty przedzia\u0142 czasowy od 1.1.2003 do 31.12.2003 jest zapisany w bazie danych jako 1.1.2003 0:00 do 1.1.2004 0:00. Umo\u017cliwia to analiz\u0119 wybor\u00f3w po stronie bazy danych w tym przedziale czasu.<\/div><\/section>\n<p><em>Java-Klasse CisDate<\/em><\/p>\n<p>Atrybut typu <em>CisObjectDate<\/em>, <em>CisObjectTimeStamp<\/em>, <em>CisAttributeDate<\/em> lub <em>CisAttributeTimeStamp<\/em> w wygenerowanych klasach Java obiektu biznesowego posiada typ <em>com.cisag.pgm.datatype.CisDate<\/em> . Instancja <em>CisDate<\/em> reprezentuje konkretn\u0105 warto\u015b\u0107 atrybutu. Za pomoc\u0105 metod <em>getTimeZoneGuid()<\/em> mo\u017cna uzyska\u0107 dost\u0119p do<br \/>\nGUID strefy czasowej wprowadzania, a za pomoc\u0105 metody <em>getDate()<\/em> do warto\u015bci <em>TimeStamp<\/em>.<br \/>\nDla rozwoju aplikacji dost\u0119pne s\u0105 specjalne pola GUI (<em>com.cisag.pgm.gui.CisDateField<\/em> itd.), kt\u00f3re mog\u0105 bezpo\u015brednio obs\u0142ugiwa\u0107 instancje <em>CisDate<\/em>. Klasa pomocnicza<em> com.cisag.pgm.util.CisDateUtility<\/em> udost\u0119pnia metody do tworzenia instancji <em>CisDate<\/em> i wykonywania operacji takich jak zaokr\u0105glanie i przenoszenie na <em>CisDates<\/em>.<\/p>\n<p><em>Primitiver Datentyp TimeStamp<\/em><\/p>\n<p>Techniczne lub bezwzgl\u0119dne specyfikacje czasu nie wymagaj\u0105 definicji strefy czasowej, np. granice przedzia\u0142\u00f3w obowi\u0105zywania lub techniczne punkty w czasie (data i godzina), np. czas zmiany jednostki. Takie atrybuty s\u0105 oparte na prymitywnym typie danych systemu ERP <em>TimeStamp<\/em> i nie zawieraj\u0105 informacji o strefie czasowej. Okre\u015blenie czasu jest konwertowane bezpo\u015brednio na stref\u0119 czasow\u0105 kontekstu czasu wykonywania i wizualizowane bez okre\u015blania strefy czasowej.<\/p>\n<p>Zatem w generowanych klasach Java obiektu biznesowego atrybut posiada typ <em>java.util.Date<\/em>.<\/p>\n<h5 id=\"zaleznosc-czasowa\" ><span class=\"ez-toc-section\" id=\"Zaleznosc_czasowa\"><\/span>Zale\u017cno\u015b\u0107 czasowa<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Atrybuty <em>validFrom<\/em> i <em>validUntil<\/em> obiektu biznesowego zale\u017cnego od czasu mog\u0105 by\u0107 oparte na specyfikacji daty lub punktu w czasie (data i godzina) z uwzgl\u0119dnieniem strefy czasowej. W punkcie &#8222;Zale\u017cny od czasu&#8221; obiektu biznesowego mo\u017cna okre\u015bli\u0107, kt\u00f3ry typ daty b\u0119dzie u\u017cywany dla tych atrybut\u00f3w:<\/p>\n<ul>\n<li>Data ze stref\u0105 czasow\u0105 przez aplikacj\u0119: atrybuty maj\u0105 typ\u00a0<em>CisObjectDate<\/em><\/li>\n<li>Punkt w czasie (data i godzina) ze stref\u0105 czasow\u0105 przez aplikacj\u0119: atrybuty maj\u0105 typ\u00a0<em>CisObjectTimeStamp<\/em><\/li>\n<\/ul>\n<p>Ustawienia te nale\u017cy wybra\u0107 odpowiednio dla obiektu biznesowego, je\u015bli strefa czasowa ma by\u0107 uwzgl\u0119dniana w prezentowanym okresie obowiazywania. Atrybuty <em>validFrom<\/em> i <em>validUntil<\/em> s\u0105 generowane w klasach Java jako <em>java.util.Date<\/em>.<\/p>\n<h5 id=\"data-description-ldt-i-data-description-column\" ><span class=\"ez-toc-section\" id=\"Data-Description-LDT_i_Data-Description-Column\"><\/span><em>Data-Description-LDT<\/em> i <em>Data-Description-Column<\/em><span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Dla <em>Data Description<\/em> istniej\u0105 dwa typy obiekt\u00f3w deweloperskich:<\/p>\n<ul>\n<li>Data Description LDT<\/li>\n<li>Data Description Column<\/li>\n<\/ul>\n<p>Chocia\u017c maj\u0105 one te same w\u0142a\u015bciwo\u015bci, r\u00f3\u017cni\u0105 si\u0119 poziomami odniesienia. <em>Data Description LDT<\/em> tworzy jednostk\u0119 z<br \/>\nlogicznym typem danych (identyczny obszar nazw i identyczna nazwa obiektu deweloperskiego). Opisuje ona zachowanie logicznych typ\u00f3w danych w interfejsie u\u017cytkownika. Poprzez zastosowanie logicznych typ\u00f3w danych typu &#8222;logiczny&#8221;, hierarchia dziedziczenia jest niejawnie mapowana na powi\u0105zane <em>Data Descriptions<\/em>.<br \/>\nW tym celu dla logicznych typ\u00f3w danych musi by\u0107 zdefiniowany\u00a0<em>Data Description LDT<\/em>. Nast\u0119pnie jest on wykorzystywany do okre\u015blenia, czy warto\u015bci maj\u0105 pochodzi\u0107 z dziedziczenia, czy te\u017c maj\u0105 by\u0107 jawnie podane.<\/p>\n<p><em>Data Description Column<\/em> jest przyporz\u0105dkowana dok\u0142adnie jednej \u015bcie\u017cce atrybutu obiektu biznesowego, cz\u0105stki (part) lub rozszerzenia, przy czym r\u00f3wnie\u017c opisuje zachowanie w interfejsie u\u017cytkownika. Mo\u017ce dziedziczy\u0107 od <em>Data Description LDT <\/em>nale\u017c\u0105cego do logicznego typu danych atrybutu. \u015acie\u017cka do atrybutu mo\u017ce zosta\u0107 przeniesiona do element\u00f3w wizualnych. W ten spos\u00f3b\u00a0<em>Data Description Column<\/em> jest realizowana i prezentowana<em>. <\/em>Je\u015bli dla atrybutu nie zdefiniowano <em>Data Description Column<\/em>, stosuje si\u0119 <em>Data Description LDT<\/em> logicznego typu danych atrybutu.<\/p>\n<p>Nazwa obiektu deweloperskiego dla <em>Data Description Column<\/em> ma nast\u0119puj\u0105c\u0105 budow\u0119:<br \/>\n&lt;obszar nazw obiektu biznesowych&gt;.&lt;nazwa obiektu biznesowego<br \/>\n&gt;:&lt;nazwa atrybutu&gt;<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\">com.cisag.app.obj.BusinessObject:description<\/div><\/section>\n<p>Je\u015bli dla atrybutu obiektu biznesowego istniej\u0105 oba typy <em>DataDescription<\/em>, w\u00f3wczas priorytet posiada <em>Data Description Column.<\/em><\/p>\n<h4 id=\"plik\" ><span class=\"ez-toc-section\" id=\"Plik\"><\/span>Plik<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Obiekt deweloperski &#8222;File&#8221; mo\u017ce by\u0107 u\u017cywany do przechowywania r\u00f3\u017cnych plik\u00f3w w bazie danych repozytorium. Te obiekty w formie plik\u00f3w mog\u0105 by\u0107 np. szablonami dokument\u00f3w. Dost\u0119p do nich mo\u017cna uzyska\u0107 za po\u015brednictwem interfejsu PGM com.cisag.pgm.util.FileLogic.<\/p>\n<h4 id=\"zdarzenie\" ><span class=\"ez-toc-section\" id=\"Zdarzenie\"><\/span>Zdarzenie<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Obiekt deweloperski &#8222;Zdarzenie&#8221; jest stosowany w przep\u0142ywie pracy, aby definicje aktywno\u015bci tworzone dla<br \/>\nposzczeg\u00f3lnych zdarze\u0144, mog\u0142y wygenerowa\u0107 aktywno\u015bci, gdy wyst\u0105pi\u0105 poszczeg\u00f3lne zdarzenia. Obiekt deweloperski &#8222;Zdarzenie&#8221; mo\u017ce realizowa\u0107 zdarzenie wynikaj\u0105ce z okre\u015blonego stanu aplikacji, kt\u00f3re jest przetwarzane przez przep\u0142yw pracy. Zdarzenia s\u0105 rejestrowane w repozytorium i definiowane podczas programowania aplikacji. Zdarzenia mog\u0105 by\u0107 wyzwalane za po\u015brednictwem interfejsu programistycznego. W interfejsie<br \/>\n<em>com.cisag.pgm.appserver.CisSystem-Manager<\/em> dost\u0119pne s\u0105 metody o nazwie <em>fireEvent<\/em> z r\u00f3\u017cnymi parametrami, za pomoc\u0105 kt\u00f3rych s\u0105 realizowane zdarzenia. Zdarzenia zawsze maj\u0105 odniesienie do bazy danych.<\/p>\n<h4 id=\"rozszerzenie\" ><span class=\"ez-toc-section\" id=\"Rozszerzenie\"><\/span>Rozszerzenie<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<section class=\"document-alert-box indicator\"><div class=\"document-alert-title\">Wskaz\u00f3wka<\/div><div class=\"document-alert-content\">Obiekty biznesowe typu <em>Supplement<\/em> mog\u0105 by\u0107 u\u017cywane jako alternatywa dla rozszerze\u0144. <em>Supplements <\/em>s\u0142u\u017c\u0105<br \/>\ndo tego samego co rozszerzenia, ale nie rozbudowuj\u0105 tabeli obiektu biznesowego ze standardu.<\/div><\/section>\n<p>Rozszerzenie jest u\u017cywane do wprowadzania przez partner\u00f3w modyfikacji obiekt\u00f3w biznesowych lub<br \/>\ncz\u0105stek (parts) ze standardu (tj. z obszaru nazw <em>com.cisag<\/em>). Poprzez rozszerzenia mo\u017cna uzupe\u0142nia\u0107 o dodatkowe atrybuty definicje cz\u0105stki lub definicje obiektu biznesowego, kt\u00f3e zosta\u0142y utworzone przez Comarch<br \/>\nSoftware und Beratung AG. Dzi\u0119ki temu wygenerowane JavaSources zawieraj\u0105 nie tylko atrybuty zdefiniowane przez Comarch Software und Beratung AG, ale tak\u017ce atrybuty pochodz\u0105ce ze wszystkich powi\u0105zanych rozszerze\u0144. \u0179r\u00f3d\u0142a<br \/>\nrozszerzonego obiektu biznesowego s\u0105 zast\u0119powane nowymi \u017ar\u00f3d\u0142ami, tzn. zmiany s\u0105 dokonywane w katalogu \u017ar\u00f3d\u0142owym w \u015bcie\u017cce &#8222;com.cisag&#8221;. Podczas dodawania atrybut\u00f3w przestrzegana jest konwencja nazewnictwa, tak aby unikn\u0105\u0107 konflikt\u00f3w spowodowanych zduplikowanymi nazwami atrybut\u00f3w z r\u00f3\u017cnych rozszerze\u0144. Nazwa nowego atrybutu jest poprzedzona prefiksem deweloperskim, np. w poni\u017cszym przyk\u0142adzie jest to skr\u00f3t &#8222;ABC_&#8221;. Rozszerzenia<br \/>\ns\u0105 zorganizowane w obszarach nazw, gdzie posiadaj\u0105 unikaln\u0105 nazw\u0119. Obszar nazw rozszerzenia<br \/>\nmie\u015bci si\u0119 poza &#8222;com.cisag&#8230;&#8221; w obszarze nazw prefiksu deweloperskiego.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\">Cz\u0105stka &#8222;com.cisag.app.general.obj.Part1&#8221; posiada zdefiniowanych przez Comarch<br \/>\nSoftware und Beratung AG atrybuty <em>a<\/em> i <em>b<\/em>, ale ma zosta\u0107 rozszerzona dla firmy<br \/>\n&#8222;ABC&#8221; o atrybut <em>c.<\/em> W tym celu zostaje utworzone rozszerzenie &#8222;com.abc.app.general.obj. ExtensionPart1&#8221; oparte na cz\u0105stce \u201ecom.cisag.app.general.obj.Part1\u201c, kt\u00f3ra ma zosta\u0107 rozszerzona. Do rozszerzenia dodany zostaje atrybut o nazwie &#8222;abc_c&#8221;. W wygenerowanych klasach cz\u0105stki wygl\u0105da to tak, jakby Comarch Software und Beratung AG ju\u017c zdefiniowa\u0142 atrybut <em>abc_c<\/em>. Rozszerzona cz\u0105stka jest w pe\u0142ni kompatybilna z cz\u0105stk\u0105 podstawow\u0105. Wszystkie miejsca w aplikacji, kt\u00f3re u\u017cywaj\u0105 atrybut\u00f3w <em>a <\/em>i <em>b<\/em>, nadal dzia\u0142aj\u0105. Partner musi jedynie zaj\u0105\u0107 si\u0119 miejscami, dla kt\u00f3rych<br \/>\nistotny jest atrybut <em>c<\/em>. Miejsca te znajduj\u0105 si\u0119 poza paczkami &#8222;com.cisag&#8230;&#8221;. Aplikacja, kt\u00f3ra ma zosta\u0107 dostosowana przez partnera, znajduje si\u0119 w obszarze nazw z prefiksem &#8222;abc&#8221;. Gdy rozszerzenie jest tworzone lub usuwane, numer wersji podstawowego obiektu biznesowego lub cz\u0105stki przyjmuj\u0119 wy\u017csz\u0105 warto\u015b\u0107 i\u00a0 jest uwzgl\u0119dniany w zadaniu deweloperskim nowego generowania \u017ar\u00f3de\u0142 Java.<\/div><\/section>\n<h4 id=\"obszar-framework\" ><span class=\"ez-toc-section\" id=\"Obszar_Framework\"><\/span>Obszar (Framework)<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Obszary s\u0105 wykorzystywane do tematycznego grupowania aplikacji. Wszystkie licencjonowane obszary s\u0105 widoczne w panelu nawigacji. Aplikacje znajduj\u0105 si\u0119 w odpowiednich obszarach.<\/p>\n<h4 id=\"zdolnosc\" ><span class=\"ez-toc-section\" id=\"Zdolnosc\"><\/span>Zdolno\u015b\u0107<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Zdolno\u015b\u0107 jest kompetencj\u0105 przydzielan\u0105 w systemie ERP na poziomie programowania do obs\u0142ugi okre\u015blonych dzia\u0142a\u0144, widok\u00f3w itp.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><\/p>\n<p>Zdolno\u015b\u0107 usuwania dzia\u0142a\u0144 w przep\u0142ywie pracy.<\/p>\n<pre>CisSystemManager sm = CisEnvironment.getInstance()\n.getSystemManager();\nif (!sm.isAuthorized(\"com.cisag.sys.workflow.DeleteActivities.cap\")){\nmm.sendMessage(\"WFL\", 250);\nreturn;\n}<\/pre>\n<p><\/div><\/section>\n<h4 id=\"funkcja\" ><span class=\"ez-toc-section\" id=\"Funkcja\"><\/span>Funkcja<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>W celu dostosowania proces\u00f3w w systemie ERP bez konieczno\u015bci zmian w aplikacjach, istnieje mo\u017cliwo\u015b\u0107 definiowania funkcji. W aplikacji <em>Konfiguracja<\/em> funkcje mog\u0105 by\u0107 aktywowane i parametryzowane dla ka\u017cdego systemu, ka\u017cdej bazy danych OLTP lub ka\u017cdej jednostki organizacyjnej. Aplikacje u\u017cywaj\u0105 nast\u0119pnie tych ustawie\u0144 jako ustawie\u0144 domy\u015blnych lub nie wy\u015bwietlaj\u0105 niepotrzebnych element\u00f3w, je\u015bli funkcja jest dezaktywowana.<\/p>\n<h4 id=\"obiekt-pomocy\" ><span class=\"ez-toc-section\" id=\"Obiekt_pomocy\"><\/span>Obiekt pomocy<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Pliki pomocy, kt\u00f3re s\u0105 wy\u015bwietlane w pomocy online systemu ERP. Ten obiekt deweloperski obejmuje zar\u00f3wno pliki \u017ar\u00f3d\u0142owe i docelowe.<\/p>\n<h4 id=\"ikona-symbol\" ><span class=\"ez-toc-section\" id=\"Ikona_symbol\"><\/span>Ikona (symbol)<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Definicja w\u0142a\u015bciwo\u015bci ikon u\u017cywanych w elemencie graficznym lub akcji. Nowe ikony powinny by\u0107 tworzone w obszarze nazw .res lub .res2d, ta regu\u0142a nie jest sprawdzana. W przeciwie\u0144stwie do wszystkich innych obiekt\u00f3w deweloperskich nazwa tego obiektu deweloperskiego zaczyna si\u0119 od ma\u0142ej litery i zawiera specyfikacj\u0119 rozmiaru ikony (np. -16&#215;16). System nie sprawdza obszaru nazw, ani nazwy obiektu deweloperskiego pod k\u0105tem wspomnianych ogranicze\u0144. S\u0105 one opcjonalne i s\u0142u\u017c\u0105 zachowaniu czytelno\u015bci.<\/p>\n<h4 id=\"klasa-java\" ><span class=\"ez-toc-section\" id=\"Klasa_Java\"><\/span>Klasa Java<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Obiekt\u00a0<em>Klasa Java\u00a0<\/em>obs\u0142uguje \u017ar\u00f3d\u0142a i klasy Java.<\/p>\n<h4 id=\"klucz-licencyjne\" ><span class=\"ez-toc-section\" id=\"Klucz_licencyjne\"><\/span>Klucz licencyjne<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Klucze licencyjne s\u0142u\u017c\u0105 do dezaktywacji funkcji lub zestawu funkcji. Je\u015bli dla funkcji zostanie wprowadzony klucz licencyjny, kt\u00f3ry nie jest licencjonowany, w\u00f3wczas funkcja nie jest widoczna w aplikacji <em>Konfiguracja<\/em> i nie mo\u017cna z niej korzysta\u0107.<\/p>\n<h4 id=\"logiczny-typ-danych\" ><span class=\"ez-toc-section\" id=\"Logiczny_typ_danych\"><\/span>Logiczny typ danych<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Struktura typ\u00f3w w systemie ERP opiera si\u0119 na logicznych typach danych. Logiczny typ danych odpowiada (w przybli\u017ceniu) <em>typedef<\/em> w j\u0119zyku C lub domenie w obszarze bazy danych. Logiczne typy danych s\u0105 zorganizowane w<br \/>\nobszarach nazw, gdzie posiadaj\u0105 unikaln\u0105 nazw\u0119. Logiczny typ danych zawsze posiada znaczenie techniczne, kt\u00f3re powinno by\u0107 r\u00f3wnie\u017c wyra\u017cone w nazwie. Logiczne typy danych s\u0105 dost\u0119pne jako typy prymitywne, z\u0142o\u017cone i logiczne. Typ danych ka\u017cdego atrybutu obiektu biznesowego jest zdefiniowany poprzez logiczny typ danych.<\/p>\n<h5 id=\"logiczny-typ-danych-typu-prymitywny\" ><span class=\"ez-toc-section\" id=\"Logiczny_typ_danych_typu_prymitywny\"><\/span>Logiczny typ danych typu <em>prymitywny<\/em><span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Logiczny typ danych typu prymitywnego opiera si\u0119 na prymitywnych typach systemu ERP, z kt\u00f3rych ka\u017cdy mo\u017ce przybra\u0107 tylko jedn\u0105 warto\u015b\u0107 elementarn\u0105. W wygenerowanych klasach Java te typy danych s\u0105 zast\u0119powane odpowiednimi typami danych Java. Je\u015bli logiczny typ danych o typie &#8222;prymitywny&#8221; jest u\u017cywany bezpo\u015brednio w definicji atrybutu, w\u00f3wczas atrybut odpowiada dok\u0142adnie jednej kolumnie tabeli w bazie danych.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\">Atrybut <em>number<\/em> (numer artyku\u0142u) obiektu biznesowego <em>com.cisag.app.general.obj.Item<\/em> (artyku\u0142) jest zdefiniowany poprzez logiczny typ danych <em>com.cisag.app.general.Item<\/em>. Jest on prymitywnym typem <em>string<\/em> o maksymalnej d\u0142ugo\u015bci 25. Techniczne znaczenie logicznego typu danych jest wyra\u017cone w jego nazwie. Wygenerowana klasa zawiera atrybut\u00a0<em>item <\/em>z deklaracj\u0105 <em>java.lang.String<\/em>. Kolumna powi\u0105zana z atrybutem<br \/>\nw tabeli bazy danych obiektu biznesowego na przyk\u0142ad w DBMS Oracle mia\u0142aby typ &#8222;NVARCHAR2&#8221;.<\/div><\/section>\n<h5 id=\"logiczny-typ-danych-typu-logiczny\" ><span class=\"ez-toc-section\" id=\"Logiczny_typ_danych_typu_logiczny\"><\/span>Logiczny typ danych typu <em>logiczny<\/em><span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Logiczny typ danych typu <em>logiczny<\/em> jest funkcjonalnym doprecyzowaniem (specjalizacj\u0105) innego logicznego typu danych. Mo\u017ce by\u0107 by\u0107 oparty na wszystkich typach (prymitywny, z\u0142o\u017cony, logicznych); przy czym relacja dziedziczenia nie mo\u017ce by\u0107 cykliczna. Ten logiczny typ danych przyjmuje w\u0142a\u015bciwo\u015bci wyj\u015bciowego logicznego typu danych. Relacja dziedziczenia jest ponadto u\u017cywana do definiowania w\u0142a\u015bciwo\u015bci GUI poprzez przyporz\u0105dkowanie <em>Data Description<\/em>.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\">Atrybut <em>orderCustomerNumber<\/em> obiektu biznesowego <em>com.cisag.app.sales.obj.CustomerInvoice<\/em> jest zast\u0119powany logicznym typem danych <em>com.cisag.app.general.CustomerNumber <\/em>oraz zapisuje <em>Business Key<\/em> klienta. Logiczny typ danych pochodzi z logicznego typu danych <em>com.cisag.app.general.PartnerNumber<\/em> i przyjmuje jego w\u0142a\u015bciwo\u015bci.<\/div><\/section>\n<h5 id=\"logiczny-typ-danych-typu-zlozony\" ><span class=\"ez-toc-section\" id=\"Logiczny_typ_danych_typu_zlozony\"><\/span>Logiczny typ danych typu <em>z\u0142o\u017cony<\/em><span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Logiczny typ danych typu <em>z\u0142o\u017cony<\/em> opiera si\u0119 na definicji <em>PartDefinition<\/em>, kt\u00f3ra opisuje struktur\u0119 danych. W ten spos\u00f3b realizowane s\u0105 z\u0142o\u017cone atrybuty obiektu biznesowego.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\">Atrybut <em>intrastat<\/em> obiektu biznesowego <em>com.cisag.app.general.obj.ItemCountryData<\/em> jest definiowany poprzez z\u0142o\u017cony logiczny typ danych\u00a0<em>com.cisag.app.general.IntrastatItemData<\/em>, kt\u00f3ry opiera si\u0119 na cz\u0105stce <em>com.cisag.app.general.obj.IntrastatItemData<\/em>. Nazwa logicznego typu danych zazwyczaj zawiera nazw\u0119 cz\u0105stki.<\/div><\/section>\n<h4 id=\"komunikat\" ><span class=\"ez-toc-section\" id=\"Komunikat\"><\/span>Komunikat<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Komunikat jest wiadomo\u015bci\u0105 dla u\u017cytkownika. Informuje o wyniku dzia\u0142ania lub o okre\u015blonym statusie aplikacji.<br \/>\nstanu aplikacji. Nazwa obiektu deweloperskiego to numer komunikatu, kt\u00f3ry jest przypisywany automatycznie lub przez u\u017cytkownika podczas tworzenia nowego komunikatu. Numer komunikatu musi by\u0107 unikalny w klasie komunikat\u00f3w.<\/p>\n<p>W kodzie \u017ar\u00f3d\u0142owym komunikaty s\u0105 wywo\u0142ywane przez MessageManager. Komunikaty s\u0105 ustalane i wy\u015bwietlane w systemie za pomoc\u0105 klasy i numeru komunikatu.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><\/p>\n<pre>CisEnvironment env = CisEnvironment.getInstance();\nCisMessageManager mm = env.getMessageManager();\nmm.sendMessage(\u201eAPP\u201c, 100, \u201eParameter1\u201c,\n\u201eParameter2\u201c);<\/pre>\n<p><\/div><\/section>\n<h4 id=\"klasa-komunikatu\" ><span class=\"ez-toc-section\" id=\"Klasa_komunikatu\"><\/span>Klasa komunikatu<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Komunikat jest przyporz\u0105dkowany do klasy komunikat\u00f3w, kt\u00f3ra wskazuje na jej przynale\u017cno\u015b\u0107. Klasa komunikat\u00f3w posiada obszar nazw. Na przyk\u0142ad, istnieje klasa komunikat\u00f3w APP (Application), do kt\u00f3rej nale\u017c\u0105<br \/>\nog\u00f3lne komunikaty dla aplikacji, klasa komunikat\u00f3w SYS (System) dla komunikat\u00f3w systemowych oraz klasa komunikat\u00f3w EDU (Education) dla aplikacji szkoleniowych.<\/p>\n<p>Klasa komunikat\u00f3w jest identyfikowana poprzez obszar nazw i nazw\u0119. Nazwa zazwyczaj sk\u0142ada si\u0119 z trzech wielkich liter. Mo\u017cliwe jest r\u00f3wnie\u017c dodanie opisu kontekstu. Klasa komunikat\u00f3w mo\u017ce by\u0107 traktowana jako alias dla obszaru nazw. Dlatego nazwa mo\u017ce by\u0107 przypisana tylko raz.<\/p>\n<h4 id=\"obszar-nazw\" ><span class=\"ez-toc-section\" id=\"Obszar_nazw\"><\/span>Obszar nazw<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Typ obiektu deweloperskiego <em>Obszar nazw\u00a0<\/em>zosta\u0142 szczeg\u00f3\u0142owo opisany w rozdziale <a href=\"#obszary-nazw\">Obszary nazw<\/a>.<\/p>\n<h4 id=\"wyszukiwanie-oql\" ><span class=\"ez-toc-section\" id=\"Wyszukiwanie_OQL\"><\/span>Wyszukiwanie OQL<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Wyszukiwania OQL s\u0105 stosowane g\u0142\u00f3wnie jako pomoc wyszukiwania warto\u015bci dla p\u00f3l wprowadzania danych. W przypadku ma\u0142ych ilo\u015bci danych zwykle wy\u015bwietlana jest lista wyboru, a w przypadku du\u017cych ilo\u015bci danych &#8211; okno dialogowe.<br \/>\nOpr\u00f3cz tego wyszukiwania OQL mog\u0105 by\u0107 u\u017cywane dla aplikacji zapyta\u0144 np. bezpo\u015brednio w programach, w celu odczytu danych z bazy na podstawie zdefiniowanych kryteri\u00f3w.<br \/>\nPodobnie jak wszystkie inne typy obiekt\u00f3w deweloperskich, r\u00f3wnie\u017c wyszukiwanie OQL jest identyfikowane za pomoc\u0105 kombinacji obszaru nazw i nazwy.<br \/>\nWyszukiwanie OQL definiuje tylko metadane dla wyszukiwania. Dopiero w czasie wykonywania procesu z metadanych jest tworzone OQL dla wyszukiwania.<\/p>\n<p>Metadane wyszukiwania OQL obejmuj\u0105 stosowane obiekty biznesowe, definicj\u0119 relacji mi\u0119dzy obiektami biznesowymi, stosowane atrybuty obiekt\u00f3w biznesowych oraz kryteria wyszukiwania. Dla poszczeg\u00f3lnych atrybut\u00f3w<br \/>\nwyszukiwania mo\u017cna zdefiniowa\u0107, czy maj\u0105 one by\u0107 u\u017cywane jako kryterium wyszukiwania, do wy\u015bwietlania, do zwracania czy do sortowania. Atrybuty s\u0105 sortowane dla ka\u017cdej w\u0142a\u015bciwo\u015bci wed\u0142ug numeracji. Je\u015bli atrybut nie ma numeru dla w\u0142a\u015bciwo\u015bci, w\u00f3wczas ten atrybut nie b\u0119dzie u\u017cywany dla w\u0142a\u015bciwo\u015bci. Do zastosowania jako kryterium wyszukiwania i atrybut wy\u015bwietlania mo\u017cna wskaza\u0107 ka\u017cdy logiczny typ danych, kt\u00f3ry jest u\u017cywany dla poszczeg\u00f3lnych wizualizacji.<\/p>\n<p>Z uwagi na wydajno\u015b\u0107 wyszukiwanie OQL mo\u017ce by\u0107 podzielone na fragment podstawowy i<br \/>\ndowoln\u0105 liczb\u0119 fragment\u00f3w dodatkowych. Fragmenty dodatkowe s\u0105 uwzgl\u0119dniane tylko w OQL, je\u015bli co najmniej jeden zawarty w nim atrybut u\u017cywany jest jako kryterium wyszukiwania lub s\u0142u\u017cy do\u00a0sortowania.<\/p>\n<p>Wyszukiwaniem mo\u017cna manipulowa\u0107 programowo-technicznie za pomoc\u0105 klasy Java Hook. Mo\u017cna sterowa\u0107 interfejsami z obszaru nazw <em>com.cisag.pgm.objsearch<\/em>. Po zaimplementowaniu tych interfejs\u00f3w mo\u017cliwe jest na przyk\u0142ad wy\u015bwietlenie wynik\u00f3w wyszukiwania w postaci listy zamiast zamiast zwyk\u0142ej tabeli.<\/p>\n<p>Je\u015bli wyszukiwanie jest wykonywane w programie, logiczne typy danych, Hook itp. mog\u0105 nie by\u0107 u\u017cywane.<\/p>\n<h4 id=\"widok-oql\" ><span class=\"ez-toc-section\" id=\"Widok_OQL\"><\/span>Widok OQL<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<section class=\"document-alert-box warning\"><div class=\"document-alert-title\">Uwaga<\/div><div class=\"document-alert-content\">Ten typ obiektu deweloperskiego nie jest ju\u017c obs\u0142ugiwany. Mo\u017cna przegl\u0105da\u0107 i edytowa\u0107 istniej\u0105ce obiekty typu <em>Widok OQL<\/em>, ale nie mo\u017cna ju\u017c tworzy\u0107 nowych obiekt\u00f3w deweloperskich tego typu.<\/div><\/section>\n<p>Cz\u0119sto zdarza si\u0119, \u017ce wielokrotnie wymagany jest obiekt biznesowy zawieraj\u0105cy dodatkowe dane, pochodz\u0105ce z innych referencyjnych obiekt\u00f3w biznesowych w aplikacjach. Zamiast pobiera\u0107 obiekt biznesowy i referencyjne obiekty poprzez relacje i wybiera\u0107 odpowiednie atrybuty lub stosowa\u0107 zawsze t\u0119 sam\u0105 instrukcj\u0119 OQL, mo\u017cna zastosowa\u0107 \u0142atwiejsze rozwi\u0105zanie: utworzy\u0107 widok (view) \u017c\u0105danych informacji. Widok ten mo\u017cna stosowa\u0107 w aplikacji jak normalny obiekt biznesowy, z tym ograniczeniem, \u017ce dane s\u0105 tylko do odczytu. Zmiany mo\u017cna wi\u0119c wprowadza\u0107 w centralnej lokalizacji. Widok danych jest okre\u015blany w postaci instrukcji OQL. Nie ma \u017cadnych ogranicze\u0144 dotycz\u0105cych stosowania <i>joins <\/i>i klauzul <em>WHERE<\/em>, dzi\u0119ki czemu mo\u017cliwe jest tworzenie z\u0142o\u017conych instrukcji zapyta\u0144.<\/p>\n<p>Definicja widoku OQL zawiera obszar nazw i nazw\u0119, kt\u00f3re s\u0142u\u017c\u0105 do jednoznacznej identyfikacji widoku. Opis \u017c\u0105danego wyniku tworzony jest za pomoc\u0105 instrukcji SELECT w zapisie OQL, kt\u00f3r\u0105 musi sformu\u0142owa\u0107 programista. Instrukcj\u0119 OQL mo\u017cna przetestowa\u0107 interaktywnie za pomoc\u0105 aplikacji <em>Polecenia OQL<\/em> w obszarze <em>Rozw\u00f3j Oprogramowania<\/em>.<\/p>\n<p>System (narz\u0119dzie crtbo) generuje trzy klasy Java z definicji widoku OQL: trzy klasy Java: klasa g\u0142\u00f3wna, klasa <em>state<\/em> i klasa <em>mapper<\/em>. Klasy te s\u0105 przechowywane w pakiecie Java odpowiadaj\u0105cym obszarowi nazw pod nazw\u0105 widoku OQL (lub z przyrostkiem &#8222;_State&#8221; lub &#8222;_Mapper&#8221;). Deweloper u\u017cywa g\u0142\u00f3wnej klasy w aplikacji, aby uzyska\u0107 dost\u0119p do instancji widoku OQL, podczas gdy klasy <em>state<\/em> i <em>mapper<\/em> s\u0105 wymagane przez us\u0142ug\u0119 trwa\u0142o\u015bci danych do uzyskania dost\u0119pu do baz danych.<\/p>\n<p>Klasa g\u0142\u00f3wna zawiera metody <em>get&#8230;()<\/em> lub <em>is&#8230;()<\/em> (boolean) do uzyskania dost\u0119pu do atrybut\u00f3w widoku oraz metod\u0119 <em>buildPrimaryKey()<\/em> do \u0142adowania instancji za pomoc\u0105 klucza podstawowego. Widok zachowuje si\u0119 w aplikacji podobnie jak obiekt biznesowy, ma jednak tylko mo\u017cliwo\u015b\u0107 odczytu.<\/p>\n<p>Widok bazy danych jest tworzony w bazie danych, przy czym instrukcja OQL jest konwertowana przez system na instrukcj\u0119 SQL, kt\u00f3ra u\u017cywa tego widoku bazy do utworzenia wirtualnej tabeli bazy danych.<\/p>\n<p>Poni\u017cszy rysunek przedstawia przyk\u0142adowy widok OQL. Dostarcza on dla <em>JobDescription<\/em> klucz biznesowy jednostki organizacyjnej (klucz obcy dla obiektu biznesowego <em>Partner<\/em>). Atrybutom zdarze\u0144 przypisywana jest unikalna nazwa poprzez skr\u00f3t <em>as<\/em> lub <em>askey<\/em>. Atrybuty tworz\u0105ce klucz podstawowy widoku OQL s\u0105 oznaczone skr\u00f3tem <em>askey<\/em>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-7813 size-post-mid\" src=\"https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2024\/01\/OQL-View-600x383.png\" alt=\"\" width=\"600\" height=\"383\" srcset=\"https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/OQL-View-600x383.png 600w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/OQL-View-300x192.png 300w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/OQL-View-50x32.png 50w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/OQL-View-320x204.png 320w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/OQL-View.png 717w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<h4 id=\"czesc-part\" ><span class=\"ez-toc-section\" id=\"Czesc_Part\"><\/span>Cz\u0119\u015b\u0107 (Part)<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Definicja cz\u0119\u015bci (w skr\u00f3cie: cz\u0119\u015b\u0107) s\u0142u\u017cy do realizacji z\u0142o\u017conych atrybut\u00f3w obiekt\u00f3w biznesowych. Cz\u0105stka definiuje struktur\u0119 danych, kt\u00f3ra skupia grup\u0119 atrybut\u00f3w pod jedn\u0105 okre\u015blon\u0105 nazw\u0105. Z\u0142o\u017cone atrybuty nie maj\u0105 w\u0142asnego klucza, ale s\u0105 cz\u0119\u015bci\u0105 obiektu biznesowego. Cz\u0119\u015bci umo\u017cliwiaj\u0105 ponowne wykorzystanie raz zamodelowanych struktur danych dla r\u00f3\u017cnych obiekt\u00f3w biznesowych. Definicja cz\u0119\u015bci mo\u017ce r\u00f3wnie\u017c okre\u015bla\u0107 relacje z innymi obiektami biznesowymi. Cz\u0119\u015b\u0107 nie mo\u017ce by\u0107 jednak obiektem docelowym relacji. Podczas modelowania cz\u0119\u015bci mo\u017cna r\u00f3wnie\u017c okre\u015bli\u0107 inn\u0105 cz\u0119\u015b\u0107, z kt\u00f3rej maj\u0105 by\u0107 dziedziczone atrybuty. Definicja obiektu biznesowego r\u00f3wnie\u017c mo\u017ce dziedziczy\u0107 atrybuty z<br \/>\ncz\u0119\u015bci.<\/p>\n<p>Cz\u0119\u015b\u0107 jest okre\u015blona poprzez obszar nazw i nazw\u0119. Mo\u017ce posiada\u0107 jeden lub wi\u0119cej przypisanych atrybut\u00f3w. Nie posiada w\u0142asnej tabeli w bazie danych. Atrybuty cz\u0119\u015bci s\u0105 zapisywane w tabeli obiektu biznesowego.<\/p>\n<p>Dla definicji cz\u0119\u015bci jest generowane wiele klas Java, kt\u00f3re s\u0142u\u017c\u0105 do uzyskania dost\u0119pu do instancji cz\u0119\u015bci w aplikacji:<\/p>\n<ul>\n<li>klasa <i>immutable <\/i>do odczytu atrybut\u00f3w cz\u0119\u015bci<\/li>\n<li>klasa <em>mutable<\/em> do odczytu i zapisu atrybut\u00f3w cz\u0119\u015bci<\/li>\n<\/ul>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><\/p>\n<p>Definicja cz\u0119\u015bci <em>com.cisag.app.general.obj.BankInfo<\/em> opisuje struktur\u0119 informacji bankowej. Zdefiniowano nast\u0119puj\u0105ce atrybuty:<\/p>\n<table style=\"border-collapse: collapse; width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 33.3333%; text-align: center;\"><strong>Atrybut<\/strong><\/td>\n<td style=\"width: 33.3333%; text-align: center;\"><strong>Logiczny typ danych<\/strong><\/td>\n<td style=\"width: 33.3333%; text-align: center;\"><strong>Prymitywny typ danych<\/strong><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">bankCountry<\/td>\n<td style=\"width: 33.3333%;\">..BankInfoBankCountry<\/td>\n<td style=\"width: 33.3333%;\">guid<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">bankCode<\/td>\n<td style=\"width: 33.3333%;\">..BankInfoBankCode<\/td>\n<td style=\"width: 33.3333%;\">guid<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">bankBranch<\/td>\n<td style=\"width: 33.3333%;\">..BankInfoBankBranch<\/td>\n<td style=\"width: 33.3333%;\">guid<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">bankAccount<\/td>\n<td style=\"width: 33.3333%;\">..BankInfoBankAccount<\/td>\n<td style=\"width: 33.3333%;\">str(30)<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">iban<\/td>\n<td style=\"width: 33.3333%;\">..BankInfoIban<\/td>\n<td style=\"width: 33.3333%;\">str(40)<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">swift<\/td>\n<td style=\"width: 33.3333%;\">..BankInfoSwift<\/td>\n<td style=\"width: 33.3333%;\">str(11)<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">accountHolder<\/td>\n<td style=\"width: 33.3333%;\">..BankInfoAccountHolder<\/td>\n<td style=\"width: 33.3333%;\">str(80)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Dodatkowo definicja cz\u0119\u015bci posiada nast\u0119puj\u0105ce relacje:<\/p>\n<table style=\"border-collapse: collapse; width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 33.3333%; text-align: center;\"><strong>Relacja<\/strong><\/td>\n<td style=\"width: 33.3333%; text-align: center;\"><strong>Docelowy obiekt biznesowy<\/strong><\/td>\n<td style=\"width: 33.3333%; text-align: center;\"><strong>Kardynalno\u015b\u0107<\/strong><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">Bank<br \/>\nbankCode<\/td>\n<td style=\"width: 33.3333%;\">com.cisag.app.general.obj.<br \/>\nBank<br \/>\nguid<\/td>\n<td style=\"width: 33.3333%;\">1-1<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">BankBranch<br \/>\nbankBranch<\/td>\n<td style=\"width: 33.3333%;\">com.cisag.app.general.obj.<br \/>\nBankBranch<br \/>\nguid<\/td>\n<td style=\"width: 33.3333%;\">1-1<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">BankCountry<br \/>\nbankCountry<\/td>\n<td style=\"width: 33.3333%;\">com.cisag.app.general.obj.<br \/>\nCountry<br \/>\nguid<\/td>\n<td style=\"width: 33.3333%;\">1-1<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Wygenerowana jest klasa <em>immutable<\/em> <em>com.cisag.app.general.<\/em><em>obj.BankInfo<\/em>, kt\u00f3ra posiada jedynie metody odczytu atrybut\u00f3w, np. <em>getBankCountry()<\/em>, <em>getBankCode()<\/em> itp. Nie ma metod do zmiany warto\u015bci atrybut\u00f3w. Dzi\u0119ki relacjom tej cz\u0119\u015bci istniej\u0105 r\u00f3wnie\u017c metody dla relacji, np. metoda <em>retrieveBank()<\/em>. Istnieje r\u00f3wnie\u017c klasa <em>mutable<\/em> <em>com.cisag.app.<\/em><br \/>\n<em>general.obj.BankInfoMutable<\/em>, kt\u00f3ra dodatkowo posiada metody do zmiany atrybut\u00f3w, np. <em>setBankCountry()<\/em>, <em>setBankCode()<\/em> itp.<\/p>\n<p><\/div><\/section>\n<h4 id=\"stringtable\" ><span class=\"ez-toc-section\" id=\"Stringtable\"><\/span>Stringtable<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Tabela ci\u0105g\u00f3w jest specjalnym obiektem deweloperskim, kt\u00f3ry s\u0142u\u017cy do od\u0142\u0105czania<br \/>\ntekst\u00f3w i kodu \u017ar\u00f3d\u0142owego. Nie zaleca si\u0119 wpisywania tekst\u00f3w bezpo\u015brednio do kodu \u017ar\u00f3d\u0142owego, poniewa\u017c trudno jest przet\u0142umaczy\u0107 teksty wprowadzone w ten spos\u00f3b lub zmieni\u0107 bez konieczno\u015bci ponownej kompilacji \u017ar\u00f3de\u0142. Tabela ci\u0105g\u00f3w obs\u0142uguje teksty u\u017cywane przez aplikacj\u0119.<\/p>\n<section class=\"document-alert-box indicator\"><div class=\"document-alert-title\">Wskaz\u00f3wka<\/div><div class=\"document-alert-content\"><\/p>\n<p>Tabele ci\u0105g\u00f3w stanowi\u0105 jeden ze sposob\u00f3w realizacji tego zadania w systemie ERP. Je\u015bli to mo\u017cliwe, nale\u017cy korzysta\u0107 z dedykowanych obiekt\u00f3w deweloperskich, takich jak logiczne typy danych, akcje i zestawy warto\u015bci. Tabele ci\u0105g\u00f3w powinny by\u0107 u\u017cywane tylko wtedy, gdy wszystkie inne opcje nie s\u0105 nieodpowiednie.<\/p>\n<p><\/div><\/section>\n<p>Do ka\u017cdej sta\u0142ej s\u0105 przyporz\u0105dkowywane teksty. Tekst jest wprowadzany dla sta\u0142ej w aktualnie ustawionym j\u0119zyku programowania, tzn. w jednej sta\u0142ej mo\u017cna wprowadzi\u0107 po jednym tek\u015bcie w ka\u017cdym j\u0119zyku.\u00a0 Aby wprowadzi\u0107 tekst w innym j\u0119zyku programowania, nale\u017cy najpierw zmieni\u0107 j\u0119zyk w ustawieniach u\u017cytkownika. Z regu\u0142y istnieje jeden\u00a0 predefiniowany j\u0119zyk programowania. W kodzie \u017ar\u00f3d\u0142owym, zamiast konkretnego tekstu, okre\u015blana jest odpowiednia sta\u0142a tabeli ci\u0105g\u00f3w. Tekst jest pobierany z zapisanych wpis\u00f3w zgodnie z aktualnie ustawionym j\u0119zykiem wy\u015bwietlania w czasie dzia\u0142ania programu.<\/p>\n<p>Tabela ci\u0105g\u00f3w posiada obszar nazw i nazw\u0119. Je\u015bli tabela ci\u0105g\u00f3w jest u\u017cywana dla jednego okre\u015blonego obszaru tematycznego, to stosowany jest g\u0142\u00f3wny obszar tematyczny (zapisywane s\u0105 teksty dla danego obszaru tematycznego).<br \/>\nNazwa cz\u0119sto pochodzi od obs\u0142ugiwanej jednostki biznesowej, np. <em>Stringtable com.cisag.app.sales.BonusAgreement.<\/em><\/p>\n<p>W podrz\u0119dnym obszarze nazw jest tworzona tabela ci\u0105g\u00f3w, kt\u00f3ra s\u0142u\u017cy jako uzupe\u0142nienie do jednej lub wi\u0119cej okre\u015blonych powi\u0105zanych ze sob\u0105 klas Java, np. z jednej aplikacji.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\">Java-Klasse com.cisag.app.crm.ui.OpportunityMaintenance<br \/>\nStringtable com.cisag.app.crm.ui.OpportunityMaintenance<\/div><\/section>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><\/p>\n<p>Poni\u017cej przedstawiono tabel\u0119 ci\u0105g\u00f3w <em>com.cisag.app.general.partner.ui.PartnerIdentArea<\/em>. Zawiera ona kilka sta\u0142ych, dla kt\u00f3rych zapisane s\u0105 teksty w j\u0119zykach programowania<br \/>\n(niemiecki, angielski, &#8230;).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7817\" src=\"https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2024\/01\/stringtable.png\" alt=\"\" width=\"610\" height=\"207\" srcset=\"https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/stringtable.png 610w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/stringtable-300x102.png 300w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/stringtable-50x17.png 50w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/stringtable-600x204.png 600w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/stringtable-320x109.png 320w\" sizes=\"auto, (max-width: 610px) 100vw, 610px\" \/><\/p>\n<p><\/div><\/section>\n<p>Aby wykona\u0107 zapytanie o tekst dla sta\u0142ej w aktualnie ustawionym j\u0119zyku wy\u015bwietlania, nale\u017cy u\u017cy\u0107 metody <em>getText()<\/em> klasy <em>com.cisag.pgm.util.RepositoryInfo z <\/em>nast\u0119puj\u0105cymi sygnaturami:<\/p>\n<pre>public static String getText(String absPath);\npublic static String getText(String path, String\nconstant);<\/pre>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><\/p>\n<p>getText()<\/p>\n<p>Zapytanie o tekst przez \u015bcie\u017ck\u0119 absolutn\u0105:<\/p>\n<pre>RepositoryInfo.getText(\"com.cisag.app.general.partner.ui.PartnerIdentArea:PRIVATEADDRESS.txt\");<\/pre>\n<p>Zapytanie o tekst przez \u015bcie\u017ck\u0119 wzgl\u0119dn\u0105:<\/p>\n<pre>RepositoryInfo.getText(\"com.cisag.app.general.partner.ui.PartnerIdentArea\", \"PRIVATEADDRESS\");<\/pre>\n<p>Do element\u00f3w GUI przekazywany jest zazwyczaj nie tekst, ale \u015bcie\u017cka tabeli ci\u0105g\u00f3w. Np. GroupBox jest generowane\u00a0w nast\u0119puj\u0105cy spos\u00f3b:<\/p>\n<pre>GroupBox box = new GroupBox(\"0060...8010\",\"absoluteStringTablePath\");<\/pre>\n<p>A nie w ten spos\u00f3b:<\/p>\n<pre>GroupBox box = new GroupBox((\"0060...8010\",getText(\" absoluteStringTablePath \"));<\/pre>\n<p><\/div><\/section>\n<h4 id=\"termin\" ><span class=\"ez-toc-section\" id=\"Termin\"><\/span>Termin<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Obiekt deweloperski\u00a0<em>Termin<\/em> umo\u017cliwia przenoszenie i korzystanie z termin\u00f3w obs\u0142ugiwanych w Trados Multiterm. Terminy s\u0105 importowane do repozytorium za pomoc\u0105 aplikacji <em>Import termin\u00f3w. <\/em>Ten obiekt deweloperski mo\u017cna edytowa\u0107 tylko za pomoc\u0105 aplikacji TradosMultiterm. Terminy s\u0105 zawsze przechowywane w obszarze nazw<br \/>\n<em>com.cisag.app.terminus<\/em>. Nazwa obiektu deweloperskiego jest numerowana (00001 &#8230;).<\/p>\n<h4 id=\"przebieg-testowy-test-run\" ><span class=\"ez-toc-section\" id=\"Przebieg_testowy_Test_Run\"><\/span>Przebieg testowy (Test Run)<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Przebieg testowy to definicja powtarzalnego scenariusza testowania aplikacji. Istniej\u0105 dwie r\u00f3\u017cne mo\u017cliwe definicje przebieg\u00f3w testowych:<\/p>\n<ul>\n<li>Definicja og\u00f3lna &#8211; w tej definicji mo\u017cna wskaza\u0107 obszar nazw. Przebieg testowy uwzgl\u0119dnia wszystkie aplikacje zdefiniowane w tym obszarze nazw. Ten typ definicji jest u\u017cywany do testowania og\u00f3lnej funkcjonalno\u015bci aplikacji.<\/li>\n<li>Definicja konkretna &#8211; zawiera wszystkie aplikacje i testy. Oznacza to, \u017ce zestaw aplikacji<br \/>\ni test\u00f3w jest taki sam podczas rejestracji, jak i podczas wykonywania. Ta definicja mo\u017ce r\u00f3wnie\u017c zawiera\u0107 specjalne testy, kt\u00f3re mo\u017cna zdefiniowa\u0107 dla jednej aplikacji.<\/li>\n<\/ul>\n<h4 id=\"tekst\" ><span class=\"ez-toc-section\" id=\"Tekst\"><\/span>Tekst<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Dla ka\u017cdego obiektu deweloperskiego zawieraj\u0105cego tekst, kt\u00f3ry mo\u017cna przet\u0142umaczy\u0107, istnieje dok\u0142adnie jeden dodatkowy obiekt deweloperski typu <em>Tekst<\/em>.<br \/>\nObiekt tekstowy zawiera wszystkie wprowadzone teksty w poszczeg\u00f3lnych j\u0119zykach. Obszar nazw jest taki sam jak obszar nazw powi\u0105zanego obiektu deweloperskiego. Nazwa obiektu deweloperskiego zawiera typ tekstu<br \/>\ni nazw\u0119 powi\u0105zanego obiektu deweloperskiego (&lt;typ tekstu&gt;_&lt;nazwa obiektu deweloperskiego&gt;). Obiekt tekstowy<br \/>\njest tworzony automatycznie podczas tworzenia powi\u0105zanego obiektu deweloperskiego. Je\u015bli w obiekcie deweloperski, zostanie zmieniony tekst, to automatycznie nast\u0119puje zmiana obiektu tekstowego i blokada w bie\u017c\u0105cym zadaniu deweloperskim. Teksty mog\u0105 by\u0107 r\u00f3wnie\u017c zmieniane za pomoc\u0105 Panelu Redakcja poza repozytorium.<\/p>\n<h4 id=\"zestaw-wartosci-valueset\" ><span class=\"ez-toc-section\" id=\"Zestaw_wartosci_Valueset\"><\/span>Zestaw warto\u015bci (Valueset)<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Zestaw warto\u015bci jest okre\u015blonym zbiorem warto\u015bci podobnym do konstrukcji <em>type<\/em> istniej\u0105cym np. w Pascalu. Uzupe\u0142nieniem s\u0105 elementy <em>ValueSet<\/em>, kt\u00f3re zawieraj\u0105 konkretne specyfikacje zestawu. Ka\u017cdy element sk\u0142ada si\u0119 z warto\u015bci <em>short<\/em>, nazwy i oznaczenia. Domy\u015blnie dla ka\u017cdego zestawu warto\u015bci generowana jest powi\u0105zana klasa Java, w kt\u00f3rej zdefiniowane s\u0105 sta\u0142e (<em>static <\/em><em>final short<\/em>). Nazwa elementu <em>ValueSet <\/em>jest stosowana jako nazwa sta\u0142ej, a warto\u015b\u0107 <em>short<\/em> jako warto\u015b\u0107 sta\u0142ej. Oznaczenie podlega t\u0142umaczeniu i jest u\u017cywane do prezentacji GUI elementu.<\/p>\n<p>Numery stosowane w ID s\u0105 zdefiniowane. System deweloperski partnera mo\u017ce stosowa\u0107 tylko numery z zakresu od 3001 do 3999, a system dostosowa\u0144 klienta od 6001 do 6999, aby unikn\u0105\u0107 nak\u0142adania si\u0119 numer\u00f3w podczas rozszerzania zestawu warto\u015bci.<\/p>\n<p>Sta\u0142e nie powinny by\u0107 u\u017cywane do operacji bitowych, poniewa\u017c partner nie ma wtedy mo\u017cliwo\u015bci rozszerzenia <em>ValueSet<\/em>.<br \/>\nPoni\u017csza tabela prezentuje przyk\u0142adowy zestaw warto\u015bci <em>com.cisag.app.general.CommunicationMedia<\/em>:<\/p>\n<table style=\"border-collapse: collapse; width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 11.2083%; text-align: center;\"><strong>ID<\/strong><\/td>\n<td style=\"width: 55.4583%; text-align: center;\"><strong>Sta\u0142a<\/strong><\/td>\n<td style=\"width: 33.3333%; text-align: center;\"><strong>Oznaczenie<\/strong><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 11.2083%;\">1<\/td>\n<td style=\"width: 55.4583%;\">EMAIL<\/td>\n<td style=\"width: 33.3333%;\">e-mail<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 11.2083%;\">2<\/td>\n<td style=\"width: 55.4583%;\">TELEFAX<\/td>\n<td style=\"width: 33.3333%;\">faks<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 11.2083%;\">3<\/td>\n<td style=\"width: 55.4583%;\">TELEPHONE<\/td>\n<td style=\"width: 33.3333%;\">telefon<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 11.2083%;\">4<\/td>\n<td style=\"width: 55.4583%;\">TELEX<\/td>\n<td style=\"width: 33.3333%;\">teleks<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 11.2083%;\">5<\/td>\n<td style=\"width: 55.4583%;\">URL<\/td>\n<td style=\"width: 33.3333%;\">www<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Odpowiednia klasa Java musi zosta\u0107 wygenerowana dla zestawu warto\u015bci. Odbywa si\u0119 to za pomoc\u0105 narz\u0119dzia crtvs, kt\u00f3re jest wykonywane w wierszu polece\u0144<br \/>\nwiersza polece\u0144 SAS. Okre\u015blaj\u0105c parametr &#8222;-j:nummer&#8221;, generowane s\u0105 wszystkie zestawy warto\u015bci zawarte w zadaniu programistycznym.<br \/>\nGenerowane s\u0105 wszystkie zestawy warto\u015bci zawarte w zadaniu programistycznym:<\/p>\n<p>Do zestawu warto\u015bci musi zosta\u0107 wygenerowana powi\u0105zana klasa Java. S\u0142u\u017cy do tego narz\u0119dzie <em>crtvs<\/em>, kt\u00f3re jest uruchamiane w wierszu polece\u0144 SAS. Poprzez okre\u015blenie parametru &#8222;-j:nummer&#8221; generowane s\u0105 wszystkie zestawy warto\u015bci zawarte w zadaniu deweloperskim:<\/p>\n<pre>crtvs \u2013j:nummer<\/pre>\n<p>Wygenerowana klasa znajduje si\u0119 w paczce odpowiadaj\u0105cej obszarowi nazw zestawu warto\u015bci, w katalogu roboczym zadania deweloperskiego i nosi nazw\u0119 zestawu warto\u015bci.<\/p>\n<h4 id=\"wersje-obiektow-deweloperskich\" ><span class=\"ez-toc-section\" id=\"Wersje_obiektow_deweloperskich\"><\/span>Wersje obiekt\u00f3w deweloperskich<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Podczas przetwarzania obiektu deweloperskiego w ramach zadania deweloperskiego zawsze tworzona jest nowa wersja obiektu. Gdy tworzony jest nowy obiekt deweloperski, powstaje jego pierwsza wersja. Dop\u00f3ki zadanie nie zostanie zako\u0144czone, wersja ta nie jest jeszcze aktywna w systemie, ale istnieje tylko w zadaniu deweloperskim. Taka wersja mo\u017ce zatem zosta\u0107 usuni\u0119ta bez konieczno\u015bci jej archiwizowania. Po aktywacji zadania nowa wersja staje si\u0119 aktywn\u0105 wersj\u0105 w systemie. Po usuni\u0119ciu obiektu deweloperskiego tworzona jest nowa wersja, kt\u00f3ra jest oznaczona znakiem &#8222;+&#8221; na ko\u0144cu numeru wersji jako usuni\u0119ta.<\/p>\n<p>Obiekt deweloperski posiada sze\u015bciocz\u0119\u015bciowy numer wersji. Za nim, oddzielona dwukropkiem, znajduje si\u0119<br \/>\nnazwa systemu, w kt\u00f3rym powsta\u0142a ta wersja. Typ systemu ERP, w kt\u00f3rym obiekt deweloperski zosta\u0142 utworzony lub<br \/>\nlub zmodyfikowany, okre\u015bla, kt\u00f3ra cz\u0119\u015b\u0107 numeru wersji b\u0119dzie zwi\u0119kszana. Do zapisu stosuje si\u0119 zasad\u0119 pomijania zer po prawej stronie. W przypadku starszych wersji mo\u017cliwe jest, \u017ce nazwa systemu nie jest cz\u0119\u015bci\u0105 numeru wersji. Istniej\u0105 nast\u0119puj\u0105ce typy systemu:<\/p>\n<ul>\n<li>Wewn\u0119trzny system deweloperski (etap 1): System w Comarch Software und Beratung AG, w kt\u00f3rym rozwijana jest kolejna wersja wydania. Podczas tworzenia nowych obiekt\u00f3w lub zmiany istniej\u0105cych podnoszona jest pierwsza cz\u0119\u015b\u0107 numeru wersji.<\/li>\n<li>Wewn\u0119trzny system korekt (etap 2): W wewn\u0119trznym systemie korekt nast\u0119puje w\u0142\u0105czenie korekt do\u00a0 wydawanego systemu. System korekt istnieje dla ka\u017cdej wersji wydania tak d\u0142ugo, dop\u00f3ki wersja wydania jest utrzymywana przez Comarch Software und Beratung AG. Podczas tworzenia nowych obiekt\u00f3w lub zmiany istniej\u0105cych podnoszona jest druga cz\u0119\u015b\u0107 numeru wersji.<\/li>\n<li>Rozwi\u0105zanie dla bran\u017c partnera (etap 3): System rozwi\u0105za\u0144 dla bran\u017c partnera jest rozwini\u0119ciem systemu dla konkretnej bran\u017cy. Podczas tworzenia nowych obiekt\u00f3w lub zmiany istniej\u0105cych podnoszona jest trzecia cz\u0119\u015b\u0107 numeru wersji.<\/li>\n<li>System korekt dla bran\u017c partnera (etap 4): W tym systemie implementowane s\u0105 poprawki do wersji wydania dla rozwi\u0105za\u0144 bran\u017cowych partnera. Podczas tworzenia nowych obiekt\u00f3w lub zmiany istniej\u0105cych podnoszona jest czwarta cz\u0119\u015b\u0107 numeru wersji.<\/li>\n<li>System dostosowa\u0144 klienta (etap 5 lub 6): System zawiera konkretne dostosowania rozwi\u0105zania dla bran\u017c partnera lub wersji wydania w Comarch Software und Beratung AG do specyficznych potrzeb klienta. Podczas tworzenia nowych obiekt\u00f3w lub zmiany istniej\u0105cych podnoszona jest sz\u00f3sta cz\u0119\u015b\u0107 numeru wersji.<\/li>\n<li>System produkcyjny (etap 7): System u\u017cywany przez klienta w jego lokalizacji. W systemie produkcyjnym nie mo\u017cna dodawa\u0107, ani zmienia\u0107 \u017cadnych obiekt\u00f3w deweloperskich.<\/li>\n<\/ul>\n<p>Poni\u017csza tabela przedstawia struktur\u0119 numeracji wersji (bez okre\u015blania systemu)<\/p>\n<table style=\"border-collapse: collapse; width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 11.3333%; text-align: center;\"><strong>Pozycja<\/strong><\/td>\n<td style=\"width: 45.4583%; text-align: center;\"><strong>Stosowane przez system <\/strong><strong>typu<\/strong><\/td>\n<td style=\"width: 43.2083%; text-align: center;\"><strong>Wersja obiektu<\/strong><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 11.3333%;\">1<\/td>\n<td style=\"width: 45.4583%;\">System deweloperski Comarch Software und Beratung AG<\/td>\n<td style=\"width: 43.2083%;\">Numer wersji g\u0142\u00f3wnej<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 11.3333%;\">2<\/td>\n<td style=\"width: 45.4583%;\">System korekt Comarch Software und Beratung AG<\/td>\n<td style=\"width: 43.2083%;\">Numer wersji korekt<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 11.3333%;\">3<\/td>\n<td style=\"width: 45.4583%;\">System rozwi\u0105zania dla bran\u017c partnera<\/td>\n<td style=\"width: 43.2083%;\">Numer wersji g\u0142\u00f3wnej<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 11.3333%;\">4<\/td>\n<td style=\"width: 45.4583%;\">System rozwi\u0105zania dla bran\u017c partnera<\/td>\n<td style=\"width: 43.2083%;\">Numer wersji korekt<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 11.3333%;\">5<\/td>\n<td style=\"width: 45.4583%;\">System dostosowa\u0144 klienta<\/td>\n<td style=\"width: 43.2083%;\">Numer wersji dostosowa\u0144 klienta<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 11.3333%;\">6<\/td>\n<td style=\"width: 45.4583%;\">System dostosowa\u0144 klienta<\/td>\n<td style=\"width: 43.2083%;\">Numer wersji dostosowa\u0144 klienta<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Przyk\u0142ad sposobu liczenia wersji dla obiektu biznesowego:<\/p>\n<ul>\n<li>Po utworzeniu obiektu biznesowego w systemie deweloperskim Comarch Software und Beratung AG obiekt ma numer wersji 1.0.0.0.0 (w skr\u00f3cie 1) i zostaje wydany.<\/li>\n<li>Partner rozwija rozwi\u0105zanie bran\u017cowe oparte na tym wydaniu i dostosowuje obiekt biznesowy. Obiekt otrzymuje numer wersji 1.0.1.0.0.0 (w skr\u00f3cie 1.0.1) w opracowanym rozwi\u0105zaniu bran\u017cowym partnera.<\/li>\n<li>Po dw\u00f3ch korektach rozszerzenia przez partnera w systemie korekt rozwi\u0105zania bran\u017cowego do wydanego rozwi\u0105zania bran\u017cowego obiekt biznesowy otrzymuje numer wersji 1.0.1.2.0.0<br \/>\n(w skr\u00f3cie 1.0.1.2).<\/li>\n<li>W systemie dostosowa\u0144 klienta opartym o rozwi\u0105zanie bran\u017cowe partnera, obiekt biznesowy zostaje ponownie zmieniony. W tym systemie otrzymuje numer wersji 1.0.1.2.0.1.<\/li>\n<li>W systemie dostosowa\u0144 klienta opartym na standardowym wydaniu Comarch Software und Beratung AG obiekt biznesowy zostaje zmieniony. Oznacza to, \u017ce w tym systemie jego numer wersji to 1.0.0.0.0.1.<\/li>\n<\/ul>\n<h2 id=\"usluga-trwalosci-danych\" ><span class=\"ez-toc-section\" id=\"Usluga_trwalosci_danych\"><\/span>Us\u0142uga trwa\u0142o\u015bci danych<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Dla aplikacji systemu ERP us\u0142uga trwa\u0142o\u015bci danych jest interfejsem s\u0142u\u017c\u0105cym di wczytywania i zapisywania danych z bazy. Programista aplikacji korzysta g\u0142\u00f3wnie z mened\u017cera transakcji i mened\u017cera obiekt\u00f3w.<\/p>\n<p>Us\u0142uga trwa\u0142o\u015bci danych odpowiada za po\u0142\u0105czenie bazy danych z systemem. Realizuje dost\u0119py do bazy danych wymagane przez aplikacj\u0119 i kapsu\u0142kuj\u0105 przy tym specyficzne cechy u\u017cywanego DBMS. Mened\u017cer obiekt\u00f3w us\u0142ugi trwa\u0142o\u015bci danych umo\u017cliwia aplikacji dwie opcje dost\u0119pu do bazy danych. Po pierwsze zapewnia metody odczytu,<br \/>\ntworzenia, zmiany i usuwania na poziomie obiekt\u00f3w biznesowych. Po drugie za pomoc\u0105 us\u0142ugi trwa\u0142o\u015bci danych aplikacja mo\u017ce wykona\u0107 dowoln\u0105 instrukcj\u0119 OQL, w celu za\u0142adowania lub zmiany danych.<\/p>\n<p>Us\u0142uga trwa\u0142o\u015bci odwzorowuje obiektowy model danych u\u017cywany w aplikacji na relacyjny model bazy danych. Wymagane komendy SQL s\u0105 generowane na podstawie instrukcji OQL. Wszystko to odbywa si\u0119 w spos\u00f3b przejrzysty dla aplikacji. Wszystkie dost\u0119py do bazy danych w aplikacjach odbywaj\u0105 si\u0119 w ramach transakcji zarz\u0105dzanych przez mened\u017cera transakcji.<\/p>\n<p>Pozosta\u0142e istotne zadania us\u0142ugi trwa\u0142o\u015bci danych:<\/p>\n<ul>\n<li>zarz\u0105dzanie blokadami na obiektach biznesowych (Lock Service)<\/li>\n<li>zarz\u0105dzanie pami\u0119ci\u0105 podr\u0119czn\u0105 w celu ograniczenia dost\u0119p\u00f3w do bazy danych (Caching)<\/li>\n<li>zarz\u0105dzanie otwartymi po\u0142\u0105czeniami z baz\u0105 danych (Connection Pooling)<\/li>\n<\/ul>\n<h3 id=\"manager-transakcji\" ><span class=\"ez-toc-section\" id=\"Manager_transakcji\"><\/span>Manager transakcji<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Mened\u017cer transakcji zarz\u0105dza transakcjami w sesji. Pozwala uruchomi\u0107 now\u0105 transakcj\u0119 Top Level lub transakcj\u0119 podrz\u0119dn\u0105 oraz potwierdzi\u0107 lub anulowa\u0107 transakcj\u0119.<\/p>\n<h4 id=\"transakcje-systemu-erp\" ><span class=\"ez-toc-section\" id=\"Transakcje_systemu_ERP\"><\/span>Transakcje systemu ERP<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Transakcja stanowi klamr\u0119 dla operacji zapisu w bazie danych. Sk\u0142ada si\u0119 z jednej lub wi\u0119cej akcji w bazie danych, kt\u00f3re s\u0105 wykonywane w ca\u0142o\u015bci lub wcale (niepodzielno\u015b\u0107). S\u0105 one jawnie otwierane, zamykane lub anulowane. Zmiany s\u0105 widoczne dopiero po pomy\u015blnym zako\u0144czeniu transakcji. Przerwanie powoduje anulowanie wszystkich poprzednich zmian. Transakcja w systemie ERP odpowiada definicji transakcji w relacyjnych bazach danych, czyli wykazuje w\u0142a\u015bciwo\u015bci ACID. System ERP obs\u0142uguje zamkni\u0119te transakcje zagnie\u017cd\u017cone. Oznacza to, \u017ce dla transakcji mo\u017ce istnie\u0107 transakcja podrz\u0119dna o dowolnym stopniu g\u0142\u0119boko\u015bci zagnie\u017cd\u017cenia (g\u0142\u0119boko\u015b\u0107 zagnie\u017cd\u017cenia jest obecnie ograniczona do 20 poziom\u00f3w). Najbardziej zewn\u0119trzna transakcja nazywana jest transakcj\u0105 Top Level. Zmiany w ramach transakcji podrz\u0119dnej b\u0119d\u0105 widoczne po jej pomy\u015blnym zako\u0144czeniu r\u00f3wnie\u017c w odpowiedniej transakcji nadrz\u0119dnej (parent). Zmiany te b\u0119d\u0105 trwa\u0142e dopiero po pomy\u015blnym zako\u0144czeniu transakcji Top Level.<\/p>\n<p>Transakcje zagnie\u017cd\u017cone lub podrz\u0119dne s\u0105 zatem transakcjami, kt\u00f3re rozpoczynaj\u0105 si\u0119 i ko\u0144cz\u0105<br \/>\nw ramach istniej\u0105cej transakcji parent. Transakcje podrz\u0119dne s\u0105 w tym przypadku nieistotne, tzn. anulowanie podrz\u0119dnej nie wymusza anulowania transakcji parent.<\/p>\n<p>Zazwyczaj komponenty oprogramowania s\u0105 skonstruowane w taki spos\u00f3b, aby wykona\u0107 okre\u015blon\u0105, odr\u0119bn\u0105 us\u0142ug\u0119. Z regu\u0142y musi to by\u0107 bezpieczne dla transakcji; komponent mo\u017ce wykona\u0107 us\u0142ug\u0119 w ca\u0142o\u015bci, albo wcale. Oznacza to, \u017ce komponent rozpocznie transakcj\u0119 i wykona operacje w ramach tej transakcji. Zagnie\u017cd\u017cone wywo\u0142ywanie komponent\u00f3w automatycznie oznacza zagnie\u017cd\u017cone transakcje.<\/p>\n<p>Transakcja Top Level i wszystkie jej transakcje podrz\u0119dne mie\u0107 dost\u0119p do odczytu i zapisu tylko do jednej bazy danych.<br \/>\nMened\u017cer transakcji zawsze ma zawsze jedn\u0105 bie\u017c\u0105c\u0105 transakcj\u0119 aplikacji w danym momencie. Je\u015bli transakcja nie zosta\u0142a jawnie uruchomiona, w\u00f3wczas w bazie danych OLTP otwierana jest transakcja dummy. Taka transakcja ma tylko dost\u0119p do odczytu i nie posiada transakcji podrz\u0119dnych.<\/p>\n<p><em>Zarz\u0105dzanie transakcjami w aplikacji<\/em><\/p>\n<p>Mened\u017cer transakcji udost\u0119pnia aplikacji niezb\u0119dne funkcje do uruchamiania, anulowania i zako\u0144czenia transakcji.<\/p>\n<p>Transakcje mog\u0105 by\u0107 otwierane za pomoc\u0105 &#8222;begin&#8221; lub &#8222;create&#8221;. Je\u015bli transakcja jest otwierana za pomoc\u0105 &#8222;create&#8221;, w\u00f3wczas tworzony jest obiekt transakcji, kt\u00f3ry implementuje interfejs &#8222;AutoCloseable&#8221;. W przypadku programowania nowych aplikacji i funkcji, nale\u017cy zastosowa\u0107 opcj\u0119 &#8222;create&#8221; zamiast &#8222;begin&#8221;. Wiele starszych aplikacji u\u017cywa opcji &#8222;begin&#8221;.<\/p>\n<p><em>beginNew() lub createNew()<\/em><\/p>\n<p>beginNew() oraz createNew() s\u0142u\u017c\u0105 do tworzenia nowych transakcji Top Level w aplikacji. Mo\u017cliwe jest przekazanie aliasu bazy danych lub GUID bazy danych w formie parametru. Je\u015bli nie zostanie przekazana \u017cadna baza danych, w\u00f3wczas u\u017cywana jest aktywna baza danych OLTP sesji u\u017cytkownika. Mened\u017cer transakcji udost\u0119pnia dost\u0119pne aliasy baz danych jako sta\u0142e:<\/p>\n<ul>\n<li>CisTransactionManager.OLTP oznacza aktywn\u0105 baz\u0119 danych OLTP sesji<\/li>\n<li>CisTransactionManager.OLAP oznacza aktywn\u0105 baz\u0119 danych OLAP sesji<\/li>\n<\/ul>\n<p>Je\u015bli transakcja zosta\u0142a wygenerowana za pomoc\u0105 funkcji createNew(), to nie wolno jej zamyka\u0107 poprzez mened\u017cera transakcji, ale zamiast tego nale\u017cy u\u017cy\u0107 metod na transakcji.<\/p>\n<p><em>begin() lub create()<\/em><\/p>\n<p>Nowe transakcje s\u0105 generowane za pomoc\u0105 funkcji<em> begin() i create().<\/em> Mo\u017cliwe jest przekazanie aliasu bazy danych lub GUID bazy danych w formie parametru. Je\u015bli istnieje ju\u017c kontekst transakcji dla otwartej transakcji, w\u00f3wczas tworzona jest transakcja podrz\u0119dna. Je\u015bli podana baza danych nie odpowiada bazie danych otwartej transakcji, pojawia si\u0119 wyj\u0105tek. Je\u015bli nie istnieje \u017cadna otwarta transakcja, w\u00f3wczas w podanej bazie danych lub w bazie OLTP sesji (je\u015bli nie przekazano aliasu bazy) generowana jest transakcja Top Level. Transakcja Top Level powinna by\u0107 jednak zawsze tworzona jawnie za pomoc\u0105 beginNew() lub createNew(), zamiast begin(), je\u015bli chcemy mie\u0107 pewno\u015b\u0107, \u017ce zmiany przez commit() zostan\u0105 r\u00f3wnie\u017c zapisane w bazie danych.<\/p>\n<p>Je\u015bli istnieje ju\u017c otwarty kontekst transakcji i zostanie u\u017cyta funkcja<br \/>\nbegin() lub create(), to generowana jest transakcja podrz\u0119dna, kt\u00f3ra zostanie pomy\u015blnie zako\u0144czona za pomoc\u0105 funkcji commit(), ale w\u00f3wczas transakcja parent mo\u017ce zosta\u0107 przerwana, a zmiany transakcji podrz\u0119dnych zostan\u0105 utracone.<\/p>\n<p>Je\u015bli transakcja zosta\u0142a wygenerowana za pomoc\u0105 funkcji create(), nie wolno zamyka\u0107 tej transakcji za pomoc\u0105 mened\u017cera transakcji, ale nale\u017cy u\u017cy\u0107 metod na transakcji.<\/p>\n<p>Transakcje podrz\u0119dne nie zale\u017c\u0105 od tego, czy transakcja nadrz\u0119dna zosta\u0142a otwarta za pomoc\u0105 funkcji &#8222;create&#8221; czy &#8222;begin&#8221;. Oznacza to, \u017ce w ramach transakcji otwartej za pomoc\u0105 begin() lub beginNew() mo\u017cna otwiera\u0107 transakcje podrz\u0119dne za pomoc\u0105 create(), jak r\u00f3wnie\u017c w ramach transakcji otwartej za pomoc\u0105 create() lub createNew() mo\u017cna otwiera\u0107 transakcje podrz\u0119dne za pomoc\u0105 begin().<\/p>\n<p><em>commit()<\/em><\/p>\n<p>Funkcja commit() ko\u0144czy aktualn\u0105 transakcj\u0119. Je\u015bli jest to transakcja Top Level, zarejestrowane obiekty s\u0105 zapisywane w bazie danych lub usuwane. W przypadku transakcji podrz\u0119dnych zarejestrowane obiekty nie s\u0105 jeszcze zapisywane w bazie danych, ale s\u0105 dziedziczone przez transakcj\u0119 parent, tj. umieszczane w lokalnym kontek\u015bcie transakcji, a zatem s\u0105 widoczne dla transakcji r\u00f3wnorz\u0119dnych. Tylko wtedy, gdy powi\u0105zana transakcja Top Level zostanie zako\u0144czona za pomoc\u0105 commit(), obiekty te staj\u0105 si\u0119 trwa\u0142e w bazie danych. Utrzymywane blokady transakcji podrz\u0119dnej s\u0105 dziedziczone przez transakcj\u0119 parent, a blokady transakcji Top Level s\u0105 usuwane.<\/p>\n<p>Je\u015bli transakcja zosta\u0142a wygenerowana za pomoc\u0105 funkcji create() lub createNew(), nale\u017cy zamkn\u0105\u0107 t\u0119 transakcj\u0119 za pomoc\u0105 commit() na transakcji. Nie u\u017cywaj commit() na mened\u017cerze transakcji. Po wykonaniu commit() nale\u017cy koniecznie wywo\u0142a\u0107 r\u00f3wnie\u017c metod\u0119 close() na transakcji.<\/p>\n<p><em>rollback()<\/em><\/p>\n<p>Funkcja rollback() powoduje przerwanie aktualnej transakcji. Oznacza to, \u017ce odrzucone zostan\u0105 wszystkie zmiany przekazane do us\u0142ugi trwa\u0142o\u015bci danych podczas tej transakcji lub jednej z jej transakcji podrz\u0119dnych (np. za pomoc\u0105 putObject lub deleteObject). Przy czym nie ma znaczenia, czy przerwana transakcja jest transakcj\u0105 Top Level, czy transakcj\u0105 podrz\u0119dn\u0105. Je\u015bli anulowana jest transakcja podrz\u0119dna, to lokalny kontekst transakcji parent pozostaje niezmieniony, tzn. taki sam jak w momencie uruchomienia transakcj\u0119 podrz\u0119dnej. Po anulowaniu transakcja parent<br \/>\nstaje si\u0119 ponownie aktualn\u0105 transakcj\u0105. Je\u015bli anulowana jest transakcja Top Level, to transakcj\u0105 aktualn\u0105 staje si\u0119 istniej\u0105ca transakcja dummy fikcyjna. Wszystkie blokady utrzymywane przez anulowan\u0105 transakcj\u0119 zostaj\u0105 zniesione.<\/p>\n<p>Poni\u017cszy rysunek przedstawia transakcj\u0119 Top Level z transakcj\u0105 podrz\u0119dn\u0105, kt\u00f3ra r\u00f3wnie\u017c posiada podrz\u0119dn\u0105 transakcj\u0119.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7838\" src=\"https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2024\/01\/top-level-transaction.png\" alt=\"\" width=\"506\" height=\"324\" srcset=\"https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/top-level-transaction.png 506w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/top-level-transaction-300x192.png 300w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/top-level-transaction-50x32.png 50w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/top-level-transaction-320x205.png 320w\" sizes=\"auto, (max-width: 506px) 100vw, 506px\" \/><\/p>\n<p>Dopiero przy commit() transakcji Top Level zmiany b\u0119d\u0105 trwa\u0142e w bazie danych. Obiekty <em>state<\/em> i pami\u0119\u0107 podr\u0119czna transakcji s\u0142u\u017c\u0105 do izolowania lokalnych kontekst\u00f3w transakcji.<\/p>\n<p>Wszystkie instancje obiekt\u00f3w biznesowych dostarczone przez mened\u017cera obiekt\u00f3w nale\u017c\u0105 do tej transakcji, w kt\u00f3rej zosta\u0142y wczytane lub utworzone. Mog\u0105 by\u0107 u\u017cywane tylko w tej konkretnej transakcji. W przypadku zamkni\u0119cia transakcji, do kt\u00f3rej zosta\u0142y wczytane, instancje obiekt\u00f3w biznesowych s\u0105 nieprawid\u0142owe.<\/p>\n<p>Aby m\u00f3c stosowa\u0107 obiekty biznesowe lub ich atrybuty we wszystkich transakcjach, konieczne jest wygenerowanie z nich niezwi\u0105zanego z transakcj\u0105, przej\u015bciowego obiektu biznesowego (getTransientCopy). Zawarto\u015b\u0107 przej\u015bciowego obiektu biznesowego mo\u017cna wtedy skopiowa\u0107 do innych obiekt\u00f3w biznesowych zwi\u0105zanych z transakcj\u0105 (copyTo).<\/p>\n<p>Je\u015bli transakcja zosta\u0142a wygenerowana za pomoc\u0105 create() lub createNew(), nale\u017cy zamkn\u0105\u0107 transakcj\u0119 za pomoc\u0105 funkcji close() na transakcji. Nie wolno zamyka\u0107 jej za pomoc\u0105 rollback() na mened\u017cerze transakcji.<\/p>\n<h4 id=\"widocznosc-zmian-w-zagniezdzonych-transakcjach\" ><span class=\"ez-toc-section\" id=\"Widocznosc_zmian_w_zagniezdzonych_transakcjach\"><\/span>Widoczno\u015b\u0107 zmian w zagnie\u017cd\u017conych transakcjach<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Widoczno\u015b\u0107 zmian w instancjach obiekt\u00f3w biznesowych, tj. w\u0142a\u015bciwo\u015b\u0107 izolacji transakcji, jest zarz\u0105dzana na trzech poziomach.<\/p>\n<p><em>Aktualna transakcja zawieraj\u0105ca transakcje podrz\u0119dne<\/em><\/p>\n<p>Na poziomie aktualnej transakcji i jej transakcji podrz\u0119dnych zmiany atrybut\u00f3w s\u0105 widoczne tylko w tej w\u0142a\u015bciwej instancji obiektu biznesowego. Dopiero po putObject() staj\u0105 si\u0119 one widoczne dla bie\u017c\u0105cej transakcji i wszystkich kolejnych transakcji podrz\u0119dnych. Oznacza to, \u017ce ponowne getObject() zwraca zmienion\u0105 instancj\u0105 obiektu biznesowego. Za\u0142adowane instancje zmienionego obiektu biznesowego nadal b\u0119d\u0105 mia\u0142y star\u0105 warto\u015b\u0107, dop\u00f3ki nie zostan\u0105 ponownie odczytane za pomoc\u0105 funkcji getObject().<\/p>\n<p><em>Transakcja Parent dla transakcji modyfikuj\u0105cej<\/em><\/p>\n<p>Zmiany atrybut\u00f3w s\u0105 widoczne w transakcji nadrz\u0119dnej dla transakcji modyfikuj\u0105cej tylko wtedy, gdy instancja obiektu biznesowego zosta\u0142a zapisana w transakcji modyfikuj\u0105cej, transakcja ta zosta\u0142a pomy\u015blnie zako\u0144czona za pomoc\u0105 commit(), a instancja obiektu biznesowego zostanie ponownie odczytana za pomoc\u0105 getObject(). Dotyczy to r\u00f3wnie\u017c g\u0142\u0119bszych poziom\u00f3w zagnie\u017cd\u017cenia.<\/p>\n<p><em>Zmiana zawarto\u015bci bazy danych<\/em><\/p>\n<p>Zawarto\u015b\u0107 bazy danych odzwierciedla zmiany (Insert, Update, Delete) tylko wtedy, gdy transakcja Top Level zosta\u0142a pomy\u015blnie zako\u0144czona za pomoc\u0105 commit(). Dopiero w tym momencie zapisywane s\u0105 w bazie danych wszystkie zmiany transakcji Top Level i pomy\u015blnie zako\u0144czonych transakcji podrz\u0119dnych.<\/p>\n<p>Wtedy widoczne s\u0105 one globalnie. Nale\u017cy je ponownie odczyta\u0107, poniewa\u017c instancje obiekt\u00f3w biznesowych odczytane przed transakcj\u0105 modyfikuj\u0105c\u0105 nadal zawieraj\u0105 stare warto\u015bci. Update Statements zawsze pracuj\u0105 na rzeczywistych trwa\u0142ych danych, tj. zmiany wprowadzone w instancjach obiekt\u00f3w biznesowych w tej samej transakcji nie s\u0105 jeszcze widoczne dla zapyta\u0144 OQL.<\/p>\n<h3 id=\"zarzadzanie-pamiecia-podreczna-cache\" ><span class=\"ez-toc-section\" id=\"Zarzadzanie_pamiecia_podreczna_Cache\"><\/span>Zarz\u0105dzanie pami\u0119ci\u0105 podr\u0119czn\u0105 (Cache)<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Us\u0142uga trwa\u0142o\u015bci danych u\u017cywa dw\u00f3ch pami\u0119ci podr\u0119cznych spe\u0142niaj\u0105cych r\u00f3\u017cne zadania.<\/p>\n<h4 id=\"shared-cache\" ><span class=\"ez-toc-section\" id=\"Shared_Cache\"><\/span>Shared Cache<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Wsp\u00f3\u0142dzielona pami\u0119\u0107 podr\u0119czna s\u0142u\u017cy do tymczasowego przechowywania wcze\u015bniej wczytanych instancji obiekt\u00f3w biznesowych w pami\u0119ci g\u0142\u00f3wnej w celu unikni\u0119cia dost\u0119p\u00f3w do bazy danych.<\/p>\n<p>Dzi\u0119ki temu znacz\u0105c\u0105 zwi\u0119ksza si\u0119 wydajno\u015b\u0107 systemu ERP. Je\u015bli aplikacja chce odczyta\u0107 obiekt biznesowy z bazy danych, najpierw sprawdza, czy obiekt biznesowy jest dost\u0119pny w shared cache. Je\u015bli nie, obiekt jest odczytywany z bazy danych. Shared cache jest dost\u0119pna w ka\u017cdym serwerze aplikacji, kt\u00f3ry wykonuje dost\u0119py do bazy danych<br \/>\n(singleton), dok\u0142adnie jeden raz (singleton) i zazwyczaj odzwierciedla najwa\u017cniejsz\u0105 lub ostatnio u\u017cywan\u0105 zawarto\u015b\u0107 bazy danych.<\/p>\n<p>W \u015brodowisku rozproszonym z wi\u0119cej ni\u017c jednym serwerem aplikacji oznacza\u0142oby to niepotrzebny nak\u0142ad, gdyby obiekty we wszystkich wsp\u00f3\u0142dzielonych pami\u0119ciach podr\u0119cznych by\u0142y ca\u0142y czas w tym samym stanie co w bazie danych. Zazwyczaj wystarczy, je\u015bli obiekty w shared cache s\u0105 aktualizowane w okre\u015blonym odst\u0119pie czasu (30 sekund). Ewentualnie zmiany danych podstawowych lub danych konfigurowanych mog\u0105 by\u0107 skuteczne na innych serwerach aplikacji dopiero 30 sekund p\u00f3\u017aniej.<\/p>\n<h4 id=\"transaction-cache\" ><span class=\"ez-toc-section\" id=\"Transaction_Cache\"><\/span>Transaction Cache<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Pami\u0119\u0107 podr\u0119czna transakcji s\u0142u\u017cy do tworzenia lokalnego kontekstu transakcji. Ka\u017cda transakcja Top Level ma swoj\u0105<br \/>\nw\u0142asn\u0105 pami\u0119\u0107 podr\u0119czn\u0105 transakcji. Powstaje ona w momencie wygenerowania nowej transakcji Top Level i jest potrzebna do operacji zapisu (dodanie, zmiana, usuni\u0119cie).<\/p>\n<p>Aby zmieni\u0107 instancj\u0119 obiektu biznesowego, nale\u017cy j\u0105 najpierw wczyta\u0107 do zmiany za pomoc\u0105 getObject. Manager obiekt\u00f3w blokuje instancj\u0119, aby w tym czasie nie mog\u0142a zosta\u0107 do\u0142\u0105czona do \u017cadnej innej pami\u0119ci podr\u0119cznej transakcji.<\/p>\n<p>Je\u015bli nast\u0105pi pr\u00f3ba za\u0142adowania tej samej instancji obiektu biznesowego w ramach innej transakcji, system odczeka ze zwolnieniem, a\u017c do wyst\u0105pienia limitu czasu. Dop\u00f3ki transakcja nie zostanie zako\u0144czona przez commit, obiekty<br \/>\nzarejestrowane do zapisu w ramach tej transakcji za pomoc\u0105 putObject lub deleteObject, b\u0119d\u0105 przechowywane tylko w pami\u0119ci podr\u0119cznej transakcji.<\/p>\n<p>Manager obiekt\u00f3w wyszukuje \u017c\u0105dane obiekty w odpowiedniej pami\u0119ci podr\u0119cznej transakcji za pomoc\u0105 getObject. Dzi\u0119ki temu obiekty zarejestrowane wcze\u015bniej do zapisu s\u0105 zwracane w takim stanie, w jakim zosta\u0142y zarejestrowane, a nie w jakim znajduj\u0105 si\u0119 w shared cache lub w bazie danych (izolacja). Pami\u0119\u0107 podr\u0119czna transakcji zostaje rozwi\u0105zana przez commit()\/rollback() dla transakcji Top Level:<\/p>\n<ul>\n<li>w wyniku commit() zmiany s\u0105 pobierane do bazy danych. Domy\u015blnie s\u0105 one r\u00f3wnie\u017c przesy\u0142ane do shared cache. Blokady zostaj\u0105 zniesione.<\/li>\n<li>w wyniku rollback() odrzucone zostaj\u0105 wszystkie zamiany, tzn. nie s\u0105 one pobierana ani do bazy danych, ani do shared cache.<\/li>\n<\/ul>\n<p>Poni\u017csza ilustracja przedstawia wsp\u00f3\u0142dzia\u0142anie pami\u0119ci podr\u0119cznej transakcji, pami\u0119ci wsp\u00f3\u0142dzielonej i bazy danych.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7842\" src=\"https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2024\/01\/Transaction.png\" alt=\"\" width=\"534\" height=\"321\" srcset=\"https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/Transaction.png 534w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/Transaction-300x180.png 300w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/Transaction-50x30.png 50w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/Transaction-320x192.png 320w\" sizes=\"auto, (max-width: 534px) 100vw, 534px\" \/><\/p>\n<p>Je\u015bli obiektu nie mo\u017cna znale\u017a\u0107 w transaction cache, w\u00f3wczas dost\u0119p do odczytu na bazie danych zazwyczaj odbywa si\u0119 za po\u015brednictwem shared cache. Je\u015bli instancja obiektu biznesowego nie zostanie znaleziona w shared cache, jest pobierana z bazy danych, zapisywana w shared cache i w transaction cache. Transakcje podrz\u0119dne maj\u0105 sw\u00f3j w\u0142asny obszar w transaction cache, w kt\u00f3rym przechowywane s\u0105 wczytane i zarejestrowane do zapisu instancje obiekt\u00f3w biznesowych. Je\u015bli transakcja podrz\u0119dna zostanie zako\u0144czona przez commit, instancje obiekt\u00f3w biznesowych zarejestrowane do zapisu s\u0105 przenoszone do transaction cache transakcji parent. W przypadku commit transakcji Top Level zarejestrowane do zapisu instancje obiekt\u00f3w biznesowych s\u0105 zapisywane w bazie danych i aktualizowane w shared cache. Nast\u0119pnie transaction cache zako\u0144czonej transakcji jest anulowana.<\/p>\n<p>Shared cache mo\u017cna ca\u0142kowicie pomin\u0105\u0107, u\u017cywaj\u0105c odpowiedniego trybu dost\u0119pu (IGNORE_SHARED_CACHE, BYPASS_CACHE). W\u00f3wczas instancja obiektu biznesowego (je\u015bli jest dost\u0119pna) jest wczytywana bezpo\u015brednio z bazy danych bez wzgl\u0119du na zawarto\u015b\u0107 pami\u0119ci podr\u0119cznej, ani bez jej aktualizowania. Jest to przydatne w testach sprawdzaj\u0105cych zawarto\u015b\u0107 bazy danych i jest u\u017cywane podczas synchronizacji shared cache z zawarto\u015bci\u0105 bazy danych. O strony aplikacji mo\u017ce to by\u0107 przydatne do poprawy wydajno\u015bci, je\u015bli obiekty biznesowe do odczytu lub zapisu na pewno nie powinny by\u0107 buforowane (&#8222;cached&#8221;), np. w tabelach tymczasowych.<\/p>\n<p>Poniewa\u017c pami\u0119\u0107 g\u0142\u00f3wna dost\u0119pna dla serwera aplikacji jest ograniczona, nie wszystkie obiekty mog\u0105 by\u0107 jednocze\u015bnie przechowywane w pami\u0119ci podr\u0119cznej. Dlatego dla ka\u017cdej definicji obiektu biznesowego przydzielany jest priorytet pami\u0119ci podr\u0119cznej. W przypadku konflikt\u00f3w priorytet decyduje, kt\u00f3ry obiekt pozostanie w pami\u0119ci podr\u0119cznej, a kt\u00f3ry zostanie z niej usuni\u0119ty. Priorytety obejmuj\u0105 zakres od &#8222;nie przechowuj w pami\u0119ci podr\u0119cznej&#8221; (np. dla dziennik\u00f3w) do<br \/>\n&#8222;zawsze przechowuj w pami\u0119ci podr\u0119cznej&#8221; (np. metadane). Podczas tworzenia nowego obiektu biznesowego nale\u017cy pami\u0119ta\u0107 o prawid\u0142owym ustawieniu przechowywania w pami\u0119ci podr\u0119cznej.<\/p>\n<h3 id=\"manager-obiektow\" ><span class=\"ez-toc-section\" id=\"Manager_obiektow\"><\/span>Manager obiekt\u00f3w<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Manager obiekt\u00f3w jest interfejsem dla aplikacji, w kt\u00f3rych mo\u017cna wykonywa\u0107 nast\u0119puj\u0105ce akcje:<\/p>\n<ul>\n<li>wczytywanie lub generowanie obiekt\u00f3w biznesowych (metoda getObject())<\/li>\n<li>generowanie iteracji obiekt\u00f3w biznesowych (metoda getObjectIterator ())<\/li>\n<li>wykonywanie dowolnych instrukcji OQL odczytu (SELECT) (metoda getResultSet()),<\/li>\n<li>rejestracja do zapisu obiekt\u00f3w biznesowych na bie\u017c\u0105cej transakcji (metoda putObject()),<\/li>\n<li>rejestracja do usuni\u0119cia obiekt\u00f3w biznesowych na bie\u017c\u0105cej transakcji (metoda deleteObject()),<\/li>\n<li>wykonywanie dowolnych instrukcji OQL odczytu (SELECT) (metoda getResultSet())<\/li>\n<\/ul>\n<p>Wszystkie obiekty biznesowe u\u017cywane w systemie ERP s\u0105 wczytywane, generowane, zapisywane lub usuwane za pomoc\u0105 managera obiekt\u00f3w. Dost\u0119p do instancji obiektu biznesowego uzyskuje si\u0119 za pomoc\u0105 klucza technicznego sk\u0142adaj\u0105cego si\u0119 z GUID bazy danych, GUID klasy obiektu biznesowego i klucza identyfikacyjnego instancji (np. klucz podstawowy\/business key). Klasa Java wygenerowana dla obiektu biznesowego posiada metody do generowania klucza (build&#8230;Key()) i wykonywania zapyta\u0144 (get&#8230;Key()). Klucze techniczne s\u0105 definiowane jako Byte Array (byte[]). Wygenerowana klasa Java dla obiektu biznesowego pochodzi z klasy &#8222;CisObject&#8221;, co zapewnia jednolite zachowanie.<\/p>\n<p>W aplikacji jest zawsze niejawnie otwarta transakcja dummy dla aktywnego mandanta (firmy g\u0142\u00f3wej), przy czym dopuszcza ona tylko dost\u0119p do odczytu. Dost\u0119p do zapisu (np. zapisywanie, usuwanie) jest dozwolony tylko w ramach jawnie otwartej transakcji. Trwa\u0142e instancje obiekt\u00f3w biznesowych zawsze nale\u017c\u0105 do transakcji, w kt\u00f3rej zosta\u0142y za\u0142adowane lub zmienione, z ko\u0144cem transakcji staj\u0105 si\u0119 nieaktualne. Obiekty niezale\u017cne od transakcji<br \/>\n(transient) mog\u0105 by\u0107 generowane za pomoc\u0105 metody getTransientCopy(), kt\u00f3r\u0105 posiadaj\u0105 wszystkie klasy obiekt\u00f3w biznesowych.<\/p>\n<h4 id=\"metoda-getobject\" ><span class=\"ez-toc-section\" id=\"Metoda_getObject\"><\/span>Metoda getObject()<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Instancj\u0119 obiektu biznesowego mo\u017cna wczyta\u0107 za pomoc\u0105 funkcji getObject(), przy czym uwzgl\u0119dniany jest lokalny kontekst transakcji. Jako parametry przewidywane s\u0105: klucz techniczny i opcjonalnie tryb dost\u0119pu. Dodatkowo mo\u017cna predefiniowa\u0107 j\u0119zyk tre\u015bci dla wczytywanego obiektu, tzn. wszystkie mo\u017cliwe do zlokalizowania atrybuty obiektu<br \/>\nbiznesowego s\u0105 wype\u0142niane tekstami w j\u0119zyku tre\u015bci. Je\u015bli atrybut nie posiada t\u0142umaczenia, w\u00f3wczas stosowany jest j\u0119zyk bazy danych dla tego atrybutu.<\/p>\n<h4 id=\"metoda-getobjectiterator\" ><span class=\"ez-toc-section\" id=\"Metoda_getObjectIterator\"><\/span>Metoda getObjectIterator()<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Za pomoc\u0105 metody getObjectIterator() mo\u017cna wczyta\u0107 zbi\u00f3r instancji obiekt\u00f3w biznesowych. Metoda<br \/>\nzwraca iterator dla zbioru wynik\u00f3w dla okre\u015blonego zapytania OQL. Podobnie jak w przypadku<br \/>\ngetObject() mo\u017cna okre\u015bli\u0107 j\u0119zyk tre\u015bci dla wczytywanych instancji. Je\u015bli dla obiekt\u00f3w biznesowych zale\u017cnych czasowo nie zastosowano w instrukcji OQL ani validFrom ani validUntil, w\u00f3wczas zwracane s\u0105 tylko aktualnie obowi\u0105zuj\u0105ce instancje. Je\u015bli validFrom lub validUntil jest u\u017cywane w dowolnej cz\u0119\u015bci instrukcji OQL, w\u00f3wczas zwracane s\u0105 wszystkie dost\u0119pne wersje, do kt\u00f3rych odnosi si\u0119 warunek instrukcji OQL. Poniewa\u017c iterator obiektu to &#8222;AutoClosable&#8221;, to &#8211; je\u015bli zosta\u0142 przypisany w <em>try &#8211; <\/em>b\u0119dzie on automatycznie zamykany podczas opuszczania blok\u00f3w <em>try<\/em> bez konieczno\u015bci wyboru \u201efinally\u201c.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><\/p>\n<p>Zastosowanie iteratora obiekt\u00f3w bez przypisania w <em>try<\/em>:<\/p>\n<pre>CisObjectIterator iter&lt;Book&gt;= om.getObjectIterator(\u201eselect from\ncom.cisag.app.edu.obj.Book o where o:title\nlike ?\u201c);\nom.setString(1, \u201e%Ringe%\u201c);\ntry {\nwhile (om.hasNext()) {\nBook book= iter.next();\n...\n}\n} finally {\niter.close();\n}<\/pre>\n<p><\/div><\/section>\n<p>Iterator obiektu jest zamykany po odczytaniu ostatniego elementu iteratora lub gdy zostanie wywo\u0142ana funkcja close().<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><\/p>\n<p>Zastosowanie iteratora obiekt\u00f3w z create() i <em>try<\/em>:<\/p>\n<pre>try (CisObjectIterator&lt;Book&gt; iter= om.getObjectIterator(\"select from\ncom.cisag.app.edu.obj.Book o where o:title\nlike ?\")) {\nom.setString(1, \"%Ringe%\");\nwhile (om.hasNext()) {\nBook book= iter.next();\n...\n}\n}<\/pre>\n<p>Klasa &#8222;CisObjectIterator&#8221; jest klas\u0105 &#8222;AutoClosable&#8221;, dlatego mo\u017ce by\u0107 u\u017cywana z try. Iterator jest automatycznie zamykany za pomoc\u0105 funkcji close() na ko\u0144cu bloku try.<\/p>\n<p><\/div><\/section>\n<h4 id=\"metoda-getresultset\" ><span class=\"ez-toc-section\" id=\"Metoda_getResultSet\"><\/span>Metoda getResultSet()<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Zapytania o atrybuty obiekt\u00f3w biznesowych mo\u017cna wykonywa\u0107 za pomoc\u0105 metody getResultSet(). Metoda zwraca zestaw <em>result<\/em> zawieraj\u0105cy wynik zapytania OQL. OQL w du\u017cej mierze odpowiada standardowemu SQL. R\u00f3\u017cnice przedstawiono poni\u017cej:<\/p>\n<ul>\n<li>jako nazwa tabeli u\u017cywana jest pe\u0142na nazwa obiektu biznesowego (z obszarem nazw), dla kt\u00f3rej musi byc przypisana nazwa aliasu tabeli<\/li>\n<li>jako nazwy kolumny u\u017cywane s\u0105 pe\u0142ne \u015bcie\u017cki atrybut\u00f3w, np. &#8222;holdQuantity[0].amount&#8221;<\/li>\n<li>ka\u017cda nazwa kolumny musi by\u0107 kwalifikowana za pomoc\u0105 aliasu tabeli. Alias tabeli jest oddzielony od nazwy kolumny znakiem &#8222;:&#8221;<\/li>\n<\/ul>\n<p>Instrukcja OQL przekazana jako parametr mo\u017ce zawiera\u0107 symbole zast\u0119pcze dla warto\u015bci, kt\u00f3re s\u0105 oznaczone symbolem &#8222;?&#8221;, tak jak w SQL. Nie jest uwzgl\u0119dniana ani zale\u017cno\u015b\u0107 czasowa, ani atrybuty lokalne. Zapytanie jest przypi\u0119te do bie\u017c\u0105cej transakcji.<\/p>\n<p>Wynikiem zapytania jest zestaw <em>result<\/em>. W tym zestawie musz\u0105 zosta\u0107 ustawione<br \/>\nwolne parametry okre\u015blone w ci\u0105gu OQL. Analiza zapytania odbywa si\u0119 podczas pierwszego wyszukiwania<br \/>\nwyniku za pomoc\u0105 funkcji next(). Zestaw <em>result<\/em> mo\u017ce by\u0107 ponownie u\u017cyty z nowymi parametrami po zastosowaniu metody close().<\/p>\n<p>Dop\u00f3ki zestaw <em>result<\/em> nie zostanie zamkni\u0119ty, po\u0142\u0105czenie z baz\u0105 danych jest u\u017cywane wy\u0142\u0105cznie w tym celu. Dlatego wa\u017cne jest, aby zawsze zamyka\u0107 te\u017c zestaw <em>result<\/em>. Zestaw <em>result <\/em>powinien by\u0107 zawsze u\u017cywany w bloku try\/catch. W bloku finally, je\u015bli nadal jest otwarty, zestaw powinien zosta\u0107 zamkni\u0119ty za pomoc\u0105 funkcji close(). Poniewa\u017c zestaw <em>result<\/em> to &#8222;AutoClosable&#8221;, to &#8211; je\u015bli zosta\u0142 przypisany w <em>try &#8211; <\/em>b\u0119dzie automatycznie zamykany podczas opuszczania blok\u00f3w <em>try<\/em> bez konieczno\u015bci wyboru \u201efinally\u201c. Komenda rollback() lub commit() lub close() na transakcji zamyka niejawnie wszystkie zestawy <em>result<\/em>, kt\u00f3re zosta\u0142y otwarte w transakcji.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><\/p>\n<p>Zastosowanie zestawu <em>result<\/em> bez przypisania w <em>try<\/em>:<\/p>\n<pre>...\nCisResultSet rs= om.getResultSet(\u201eselect\no:guid, o:number from\ncom.cisag.app.edu.obj.Book o where o:title\nlike ?\u201c);\ntry {\nrs.setString(1, \u201e%Ringe%\u201c);\nwhile (rs.next()) {\nbyte[] guid= rs.getGuid(1);\nString number= rs.getString(2);\n...\n}\n}\nfinally {\nif (rs != null &amp;&amp; !rs.isClosed()) {\nrs.close();\n}\n}\n...\n\n<\/pre>\n<p>Zastosowanie zestawu <em>result<\/em> z przypisaniem w <em>try<\/em>:<\/p>\n<pre>try (CisResultSet rs= om.getResultSet(\n\"select o:guid, o:number from\ncom.cisag.app.edu.obj.Book o where\no:title like ?\")) {\nrs.setString(1, \"%Ringe%\");\nwhile (rs.next()) {\nbyte[] guid= rs.getGuid(1);\n\nString number= rs.getString(2);\n...\n}\n}\n...<\/pre>\n<p><\/div><\/section>\n<h4 id=\"metoda-putobject\" ><span class=\"ez-toc-section\" id=\"Metoda_putObject\"><\/span>Metoda putObject()<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Metoda putObject() s\u0142u\u017cy do rejestracji instancji obiektu biznesowego w transakcji do zapisu. Wprowadzone zmiany<br \/>\ns\u0105 widoczne w bie\u017c\u0105cym kontek\u015bcie lokalnym transakcji. Po wykonaniu commit transakcji rejestracja jest przenoszona do kontekstu transakcji parent i tam jest r\u00f3wnie\u017c widoczna dla kolejnych transakcji podrz\u0119dnych. Je\u015bli obiekt biznesowy zawiera informacje o aktualizacji (atrybut UpdateInformation), w\u00f3wczas podczas tego wywo\u0142ania s\u0105 aktualizowane czas i u\u017cytkownik ostatniej modyfikacji.<\/p>\n<h4 id=\"metoda-deleteobject\" ><span class=\"ez-toc-section\" id=\"Metoda_deleteObject\"><\/span>Metoda deleteObject()<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Metoda deleteObject() s\u0142u\u017cy do rejestracji instancji obiektu biznesowego w transakcji do usuni\u0119cia i finalnego usuni\u0119cia z bie\u017c\u0105cego kontekstu lokalnego transakcji. Widoczno\u015b\u0107 usuni\u0119cia jest takie jak w metodzie putObject().<\/p>\n<h4 id=\"wspoldzialanie-managera-obiektow-i-pamieci-podrecznej\" ><span class=\"ez-toc-section\" id=\"Wspoldzialanie_managera_obiektow_i_pamieci_podrecznej\"><\/span>Wsp\u00f3\u0142dzia\u0142anie managera obiekt\u00f3w i pami\u0119ci podr\u0119cznej<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Je\u015bli instancja obiektu biznesowego jest wczytywana w aplikacji za pomoc\u0105 getObject(), mened\u017cer obiekt\u00f3w najpierw wyszukuje instancj\u0119 w transaction cache bie\u017c\u0105cej transakcji. Je\u015bli tam nie zostanie znaleziona, druga pr\u00f3ba polega na za\u0142adowaniu instancji z shared cache. Je\u015bli tam r\u00f3wnie\u017c nie mo\u017cna znale\u017a\u0107 instancji, nast\u0119puje dost\u0119p odczytu do bazy danych. Przy zapisie za pomoc\u0105 putObject() instancja obiektu biznesowego jest zapisywana w transaction cache bie\u017c\u0105cej transakcji aplikacji. Gdy transakcja Top Level zostanie zako\u0144czona za pomoc\u0105 commit(), instancja jest<br \/>\nzapisywana w shared cache i staje si\u0119 trwa\u0142a w bazie danych. Poni\u017cszy rysunek przedstawia zwi\u0105zek mi\u0119dzy managerem obiekt\u00f3w a pami\u0119ci\u0105 podr\u0119czn\u0105.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7865\" src=\"https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2024\/01\/Zusammenspiel-von-Objektmanager-und-Caches.png\" alt=\"\" width=\"515\" height=\"339\" srcset=\"https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/Zusammenspiel-von-Objektmanager-und-Caches.png 515w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/Zusammenspiel-von-Objektmanager-und-Caches-300x197.png 300w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/Zusammenspiel-von-Objektmanager-und-Caches-50x33.png 50w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/Zusammenspiel-von-Objektmanager-und-Caches-320x211.png 320w\" sizes=\"auto, (max-width: 515px) 100vw, 515px\" \/><\/p>\n<h4 id=\"update-statements\" ><span class=\"ez-toc-section\" id=\"Update_Statements\"><\/span>Update Statements<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Za pomoc\u0105 OQL UPDATE, INSERT lub DELETE mo\u017cliwe jest wykonywanie instrukcji. Pozwala to na zmian\u0119, wstawienie lub usuni\u0119cie wielu instancji obiektu biznesowego za pomoc\u0105 jednego polecenia.<\/p>\n<p>Instrukcja update jest wykonywana dopiero przy commit transakcji top level. Wcze\u015bniej instrukcja update nie wp\u0142ywa na dane, kt\u00f3re maj\u0105 zosta\u0107 wczytane w transakcji. Podczas commit transakcji top level instrukcje aktualizacji s\u0105 zawsze wykonywane jako pierwsze. Nie mog\u0105 one odnosi\u0107 si\u0119 do tych samych obiekt\u00f3w biznesowych, kt\u00f3re zosta\u0142y zarejestrowane w ramach tej samej transakcji do zmiany\/usuni\u0119cia za pomoc\u0105 putObject()\/deleteObject().<\/p>\n<p>Instrukcja aktualizacji blokuje ca\u0142\u0105 tabel\u0119, na kt\u00f3rej wykonywana jest instrukcja; \u017cadna inna transakcja nie mo\u017ce wczyta\u0107 instancji obiektu biznesowego tego typu. Efektywno\u015b\u0107, np. podczas usuwania wielu rekord\u00f3w danych, jest znacznie wy\u017csza przez OQL delete ni\u017c za po\u015brednictwem us\u0142ugi trwa\u0142o\u015bci danych.<\/p>\n<p>Niestety korzystanie z instrukcji aktualizacji ma powa\u017cny wp\u0142yw na og\u00f3ln\u0105 wydajno\u015b\u0107 systemu. Po zastosowaniu instrukcji aktualizacji wszystkie instancje danego obiektu biznesowe tej bazie danych s\u0105 usuwane ze wszystkich wsp\u00f3\u0142dzielonych pami\u0119ci podr\u0119cznych w ca\u0142ym systemie. Je\u017celi inne zastosowania zale\u017c\u0105 od tego, czy instancje obiektu biznesowego s\u0105 przechowywane w pami\u0119ci podr\u0119cznej, wydajno\u015b\u0107 b\u0119dzie znacznie zmniejszona. Instrukcje aktualizacji s\u0105 zatem odpowiednie przede wszystkim dla nast\u0119puj\u0105cych przypadk\u00f3w zastosowania:<\/p>\n<ul>\n<li>modyfikacja\/usuwanie obiekt\u00f3w biznesowych nieprzechowywanych w pami\u0119ci podr\u0119cznej<\/li>\n<li>usuwanie tymczasowych danych<\/li>\n<\/ul>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><\/p>\n<p>Przyk\u0142ad dla beginNew<\/p>\n<pre>tm.beginNew();\ntry {\nCisUpdateStatement s = om.getUpdateStatement(\"DELETE FROM com.cisag.app.edu.obj.Book\no\");\nom.putUpdateStatement(s);\ntm.commit();\n}\ncatch (Exception e) {\ntm.rollback();\n}<\/pre>\n<p><\/div><\/section>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><\/p>\n<p>Przyk\u0142ad dla createNew<\/p>\n<pre>Try (CisTransaction txn=tm.createNew()) {\nCisUpdateStatement s = om.getUpdateStatement(\"DELETE FROM com.cisag.app.edu.obj.Book\no\");\nom.putUpdateStatement(s);\ntxn.commit();\n}<\/pre>\n<p><\/div><\/section>\n<h4 id=\"tryb-dostepu\" ><span class=\"ez-toc-section\" id=\"Tryb_dostepu\"><\/span>Tryb dost\u0119pu<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Dost\u0119p do instancji obiekt\u00f3w biznesowych jest kontrolowany poprzez tryb dost\u0119pu. Ponadto podczas wywo\u0142ywania odpowiedniej metody mo\u017cna zastosowa\u0107 flag\u0119 wskazuj\u0105c\u0105 na tryb dost\u0119pu. Aby tworzy\u0107, zmienia\u0107 i usuwa\u0107 obiekty biznesowe, nale\u017cy u\u017cy\u0107 w\u0142a\u015bciwego trybu dost\u0119pu. Je\u015bli nie ustawiono trybu dost\u0119pu, domy\u015blnie u\u017cywany jest tryb READ.<\/p>\n<p>Tryb dost\u0119pu READ udost\u0119pnia instancje obiekt\u00f3w biznesowych tylko do odczytu, bez mo\u017cliwo\u015bci modyfikacji.<\/p>\n<ul>\n<li>Tryb dost\u0119pu READ_UPDATE udost\u0119pnia instancje obiekt\u00f3w biznesowych, kt\u00f3re mo\u017cna dowolnie zmienia\u0107 lub usuwa\u0107.<\/li>\n<li>Tryb dost\u0119pu READ_WRITE zachowuje si\u0119 tak samo jak READ_UPDATE. Je\u015bli jednak instancja, do kt\u00f3rej ma zosta\u0107 uzyskany dost\u0119p, nie istnieje, zwracana jest nowa instancja. Je\u015bli nowa instancja zawiera atrybut UpdateInformation, w\u00f3wczas do UpdateInformation wprowadzany jest czas utworzenia i u\u017cytkownik.<\/li>\n<li>Tryb dost\u0119pu CACHE_ONLY umo\u017cliwia wyszukiwanie instancji obiekt\u00f3w biznesowych tylko w pami\u0119ci podr\u0119cznej. Je\u015bli nie s\u0105 dost\u0119pne w tym miejscu, wyszukiwanie zwraca jest zero, nawet je\u015bli instancje s\u0105 one dost\u0119pne w bazie danych.<\/li>\n<li>Tryb dost\u0119pu BYPASS_CACHE powoduje, \u017ce instancje obiekt\u00f3w biznesowych s\u0105 odczytywane bezpo\u015brednio z bazy danych. Zar\u00f3wno wsp\u00f3\u0142dzielona pami\u0119\u0107 podr\u0119czna, jak i pami\u0119\u0107 podr\u0119czna transakcji s\u0105 ignorowane.<\/li>\n<li>Tryb dost\u0119pu IGNORE_SHARED_CACHE ma taki sam efekt jak jak BYPASS_CACHE, z t\u0105 r\u00f3\u017cnic\u0105, \u017ce instancje obiekt\u00f3w biznesowych po odczycie nie s\u0105 zapisywane we wsp\u00f3\u0142dzielonej pami\u0119ci podr\u0119cznej . Zapobiega to zast\u0119powaniu wa\u017cniejszych obiekt\u00f3w w pami\u0119ci podr\u0119cznej przez odczytywane obiekty.<\/li>\n<li>Tryb dost\u0119pu READ_PARALLEL jest przydatny w sytuacji, kiedy u\u017cytkownik chce u\u017cy\u0107 do odczytu transakcji dummy z poziomu innej transakcji. Umo\u017cliwia to przypisanie obowi\u0105zywania iterator\u00f3w obiekt\u00f3w i zastaw\u00f3w result do transakcji dummy, a nie do bie\u017c\u0105cej transakcji. W bazie danych transakcja dummy musi by\u0107 otwarta. Dlatego<br \/>\nta opcja dzia\u0142a tylko na mandancie (firmie g\u0142\u00f3wnej), przypisanym do u\u017cytkownika.<\/li>\n<li>Tryb dost\u0119pu READ_REPEATABLE ustawia blokad\u0119 odczytu na obiekcie biznesowym i w ten spos\u00f3b zapobiega jego zmianom przez inne transakcje. Ten tryb dost\u0119pu gwarantuje zatem sp\u00f3jno\u015b\u0107 danych, nawet je\u015bli kilka serwer\u00f3w aplikacji pracuje na OLTP DB. Nie jest to mo\u017cliwe w przypadku normalnej flagi READ, poniewa\u017c synchronizacja pami\u0119ci podr\u0119cznej mi\u0119dzy serwerami odbywa si\u0119 tylko co 30 sekund, a zatem obiekt biznesowy z nieaktualnymi warto\u015bciami atrybut\u00f3w\u00a0mo\u017ce znajdowa\u0107 si\u0119 w pami\u0119ci podr\u0119cznej.<\/li>\n<li>Tryb dost\u0119pu INSERT dezaktywuje sprawdzanie istnienia obiektu i generuje nowy nietrwa\u0142y obiekt niezale\u017cnie od zawarto\u015bci bazy danych. Je\u015bli tworzone s\u0105 nowe obiekty biznesowe, a z logiki programu wynika, \u017ce obiekty te nie istniej\u0105 jeszcze w bazie danych, nie jest konieczne sprawdzanie ich istnienia w bazie danych przez us\u0142ug\u0119 trwa\u0142o\u015bci danych. Je\u015bli natomiast, wbrew temu za\u0142o\u017ceniu, obiekt biznesowy istnieje w bazie danych, w\u00f3wczas wyst\u0105pi b\u0142\u0105d, gdy transakcja top level zostanie zako\u0144czona za pomoc\u0105 funkcji commit().<\/li>\n<li>Tryb dost\u0119pu NEW_VERSION powoduje, \u017ce tworzona jest zawsze nowa, pusta instancja obiektu biznesowego, bez uwzgl\u0119dnienia pami\u0119ci podr\u0119cznej czy bazy danej. Ta opcja jest u\u017cyteczna tylko w trybie Insert Only dla obiekt\u00f3w zale\u017cnych od czasu.<\/li>\n<\/ul>\n<h4 id=\"jezyk-tresci-content-language\" ><span class=\"ez-toc-section\" id=\"Jezyk_tresci_Content_Language\"><\/span>J\u0119zyk tre\u015bci (Content Language)<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>J\u0119zyk tre\u015bci umo\u017cliwia zarz\u0105dzanie j\u0119zykiem, w kt\u00f3rym wczytywana s\u0105 atrybuty z mo\u017cliwo\u015bci\u0105 lokalizacji (atrybuty NLS). Je\u015bli nie zostanie okre\u015blony j\u0119zyk dla wykonywanego zapytania, w\u00f3wczas stosowany jest j\u0119zyk tre\u015bci ustawiony w sesji zalogowanego u\u017cytkownika. Domy\u015blnym j\u0119zykiem dla sesji jest j\u0119zyk tre\u015bci u\u017cytkownika z konfiguracji.<\/p>\n<h4 id=\"informacje-o-modyfikacjach-specjalistyczne-usuwanie\" ><span class=\"ez-toc-section\" id=\"Informacje_o_modyfikacjach_%E2%80%9Especjalistyczne%E2%80%9D_usuwanie\"><\/span>Informacje o modyfikacjach \/ &#8222;specjalistyczne&#8221; usuwanie<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Je\u015bli w metadanych obiektu biznesowego ustawiona jest flaga maintainUpdateInfo, to do obiektu biznesowego dodawany jest atrybut UpdateInformation wskazuj\u0105cy u\u017cytkownika, kt\u00f3ry utworzy\u0142, ostatnio zmieni\u0142 lub &#8222;specjalistycznie&#8221; usun\u0105\u0142 obiekt oraz czas tych operacji. Znacznik &#8222;specjalistycznego&#8221; usuni\u0119cia nie jest analizowany przez us\u0142ug\u0119 trwa\u0142o\u015bci danych, to zadanie nale\u017cy do aplikacji. Je\u015bli flaga maintainUpdateInformation jest ustawiona na odpowiedniej definicji obiektu biznesowego, j\u0105dro systemu operacyjnego zapisuje dat\u0119 utworzenia, zmiany lub usuni\u0119cia obiektu. Modyfikacje na obiektach zale\u017cnych (dependents) s\u0105 wprowadzane dla przyporz\u0105dkowanego podmiotu biznesowego. Czas usuni\u0119cia jest w tym przypadku tylko flag\u0105, tzn. obiekt biznesowy z dat\u0105 usuni\u0119cia nie jest fizycznie usuwany, a jedynie oznaczony jako usuni\u0119ty, tak aby zosta\u0142o to uwzgl\u0119dnione w aplikacji.<\/p>\n<h4 id=\"zaleznosc-czasowa\" ><span class=\"ez-toc-section\" id=\"Zaleznosc_czasowa-2\"><\/span>Zale\u017cno\u015b\u0107 czasowa<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Wszystkie operacje odczytu managera obiekt\u00f3w pracuj\u0105 na bie\u017c\u0105cym rekordzie danych obiektu biznesowego. W przypadku obiekt\u00f3w biznesowych zale\u017cnych od czasu, ta instancja jest bie\u017c\u0105ca, w kt\u00f3rej przedziale obowi\u0105zywania (validFrom, validUntil) znajduje si\u0119 aktualna data i godzina. Przy czym czas validFrom nale\u017cy do okresu obowi\u0105zywania,<br \/>\na czas okre\u015blony przez validUntil ju\u017c nie. Us\u0142uga trwa\u0142o\u015bci danych zak\u0142ada, \u017ce przedzia\u0142y obowi\u0105zywania wszystkich zapisanych instancji obiekt\u00f3w biznesowych z tym samym kluczem podstawowym s\u0105 ci\u0105g\u0142e i nie nak\u0142adaj\u0105 si\u0119.<\/p>\n<p>Do utrzymania danych zale\u017cnych od czasu us\u0142uga trwa\u0142o\u015bci wykorzystuje tryb Insert Only i tryb Update. Instancje obiekt\u00f3w biznesowych zale\u017cnych od czasu mog\u0105 by\u0107 zapisywane lub usuwane w taki sam spos\u00f3b, jak wszystkie inne obiekty: za pomoc\u0105 metod putObject() i deleteObject(). Przypisanie do danej instancji atrybut\u00f3w validFrom i validUntil reguluje, w kt\u00f3rym z tych tryb\u00f3w obs\u0142ugiwana jest zale\u017cno\u015b\u0107 czasowa.<\/p>\n<h5 id=\"tryb-insert-only\" ><span class=\"ez-toc-section\" id=\"Tryb_Insert_Only\"><\/span>Tryb Insert Only<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Ten tryb s\u0142u\u017cy do tworzenia nowej wersji. W tym celu nale\u017cy za pomoc\u0105 us\u0142ugi trwa\u0142o\u015bci danych wygenerowa\u0107 now\u0105 instancj\u0119 z flag\u0105 NEW_VERSION. Przed zapisaniem instancji za pomoc\u0105 putObject, atrybuty validFrom i validUntil nale\u017cy ustawi\u0107 na zero, poniewa\u017c atrybuty te s\u0105 obliczane przez us\u0142ug\u0119 trwa\u0142o\u015bci danych. Wygenerowana w ten spos\u00f3b instancja posiada czas obowi\u0105zywania od bie\u017c\u0105cej daty (validFrom) do daty maksymalnej. Data validUntil poprzedniej wersji jest ustawiana jako data validFrom nowej wersji, je\u015bli nast\u0119puje po tej dacie, tak aby zachowa\u0107 ci\u0105g\u0142o\u015b\u0107. Je\u015bli jednak przypada przed dat\u0105 validFrom nowej wersji, to nie jest ona zmieniana i powstaje luka. Dzia\u0142anie tej funkcji ilustruje poni\u017cszy rysunek:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7877\" src=\"https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2024\/01\/tryb-insert-only-1.png\" alt=\"\" width=\"567\" height=\"254\" srcset=\"https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/tryb-insert-only-1.png 567w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/tryb-insert-only-1-300x134.png 300w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/tryb-insert-only-1-50x22.png 50w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/tryb-insert-only-1-320x143.png 320w\" sizes=\"auto, (max-width: 567px) 100vw, 567px\" \/><\/p>\n<h5 id=\"tryb-update\" ><span class=\"ez-toc-section\" id=\"Tryb_Update\"><\/span>Tryb Update<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Tryb Update s\u0142u\u017cy do wstawiania nowej wersji pomi\u0119dzy istniej\u0105ce wersje danej instancji obiektu biznesowego. Pocz\u0105tek okresu obowi\u0105zywania (validFrom) wersji, kt\u00f3ra ma zosta\u0107 wstawiona, jest podany, a atrybut validUntil musi by\u0107 ustawiony na zero. W tym przypadku j\u0105dro systemu operacyjnego automatycznie ogranicza maksymalny okres obowi\u0105zywania (validUntil) aktualnie obowi\u0105zuj\u0105cej wersji i ustawia odpowiedni\u0105 warto\u015b\u0107 atrybutu validUntil wstawianej wersji. Je\u015bli w danym momencie \u017cadna wersja nie jest obowi\u0105zuj\u0105ca, powstaje luka.<\/p>\n<p>Podczas korzystania z trybu Update instancja powinna by\u0107 za\u0142adowana z flag\u0105 READ_WRITE i kluczem Time Depend, tak, aby uwzgl\u0119dni\u0107 ewentualnie istniej\u0105c\u0105 wersj\u0119 instancji obiektu biznesowego.<\/p>\n<p>Dzia\u0142anie tej funkcji ilustruje poni\u017cszy rysunek:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7876\" src=\"https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2024\/01\/tryb-Update.png\" alt=\"\" width=\"572\" height=\"266\" srcset=\"https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/tryb-Update.png 572w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/tryb-Update-300x140.png 300w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/tryb-Update-50x23.png 50w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/tryb-Update-320x149.png 320w\" sizes=\"auto, (max-width: 572px) 100vw, 572px\" \/><\/p>\n<p>Je\u015bli dla obiektu biznesowego ustawione s\u0105 validFrom i validUntil, tzn. warto\u015b\u0107 jest r\u00f3\u017cna od zera, us\u0142uga trwa\u0142o\u015bci danych nie wykonuje \u017cadnych dalszych operacji w celu utrzymania sp\u00f3jno\u015bci okres\u00f3w obowi\u0105zywania. W takim przypadku wykonywana jest dok\u0142adnie ta operacja, kt\u00f3r\u0105 okre\u015bla aplikacja, bez wzgl\u0119du na ewentualne niesp\u00f3jne stany (nak\u0142adaj\u0105ce si\u0119 przedzia\u0142y czasowe, luki) b\u0119d\u0105ce wynikiem tej operacji.<\/p>\n<h3 id=\"zarzadzanie-blokadami\" ><span class=\"ez-toc-section\" id=\"Zarzadzanie_blokadami\"><\/span>Zarz\u0105dzanie blokadami<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Zarz\u0105dzanie blokadami s\u0142u\u017cy do synchronizacji transakcji zapisu na instancjach obiekt\u00f3w biznesowych. Instancja<br \/>\njest zablokowana dla bie\u017c\u0105cej transakcji, je\u015bli wykonano odczyt za pomoc\u0105 funkcji getObject() (flagi READ_WRITE, READ_UPDATE). Zmiana lub usuni\u0119cie jest mo\u017cliwe tylko w bie\u017c\u0105cej transakcji; inna transakcja mo\u017ce tylko odczyta\u0107 obiekt biznesowy z jego star\u0105 warto\u015bci\u0105. Je\u015bli inna transakcja pr\u00f3buje za\u0142adowa\u0107 do zapisu obiekt biznesowy zablokowany w ten spos\u00f3b, w\u00f3wczas nast\u0119puje przekroczenie limitu czasu po up\u0142ywie 60 sekund. W rezultacie pojawia jest wyj\u0105tek, kt\u00f3ry powinien zosta\u0107 odpowiednio obs\u0142u\u017cony przez programist\u0119. Standardow\u0105 procedur\u0105 jest wys\u0142anie wyj\u0105tku do kolejki komunikat\u00f3w aplikacji (mm.sendMessage()), gdzie w centralnej lokalizacji okre\u015blone typy wyj\u0105tk\u00f3w s\u0105 generycznie konwertowane na odpowiednie komunikaty. W tym przypadku zosta\u0142by wygenerowany nast\u0119puj\u0105cy komunikat: &#8222;Obiekt jest zablokowany przez &#8230;&#8221;. Blokady transakcji podrz\u0119dnych s\u0105 dziedziczone przez transakcj\u0119 nadrz\u0119dn\u0105 (parent) niezale\u017cnie od commit() lub rollback(). Blokady s\u0105 anulowane dopiero przy commit() lub rollback() transakcji Top Level.<\/p>\n<p>Blokowanie odbywa si\u0119 za pomoc\u0105 klucza podstawowego. W przeciwie\u0144stwie do klucza biznesowego (business key) nie mo\u017cna bezpo\u015brednio zmieni\u0107 istniej\u0105cego klucza podstawowego (mo\u017cna usun\u0105\u0107 i utworzy\u0107 nowy).<\/p>\n<p>Aplikacje powinny przetwarza\u0107 swoje operacje bazodanowe w blokach ograniczaj\u0105c dost\u0119py do bazy danych (tak rzadko, jak to mo\u017cliwe i tylko tak d\u0142ugo, jak to konieczne). Oznacza to, \u017ce:<\/p>\n<ul>\n<li>podczas d\u0142u\u017cszego przetwarzania (np. w aplikacji GUI) \u017cadna transakcja nie jest otwarta, a zatem \u017cadna instancja obiektu biznesowego nie jest zablokowana dla innych aplikacji<\/li>\n<li>dane s\u0105 utrzymywane w odpowiedniej strukturze danych np. za pomoc\u0105 instancji przej\u015bciowej (niezale\u017cnej od transakcji) jako kopii za\u0142adowanej instancji obiektu biznesowego<\/li>\n<li>transakcje powinny by\u0107 jak najkr\u00f3cej otwarta. Dlatego w transakcji powinien by\u0107 realizowany tylko absolutnie niezb\u0119dny kod programu (otwarcie transakcji, odczyt obiektu z flagami zapisu, zastosowanie zmian, potwierdzenie transakcji).<\/li>\n<\/ul>\n<h2 id=\"praca-na-obiektach-biznesowych\" ><span class=\"ez-toc-section\" id=\"Praca_na_obiektach_biznesowych\"><\/span>Praca na obiektach biznesowych<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<h3 id=\"aktualizacje-baz-danych\" ><span class=\"ez-toc-section\" id=\"Aktualizacje_baz_danych\"><\/span>Aktualizacje baz danych<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Tworzenie lub zmiana schematu definicji obiektu biznesowego prowadzi do utworzenia nowej tabeli w bazie danych. Je\u015bli schemat zosta\u0142 zmieniony, nowa tabela ma inn\u0105 struktur\u0119 ni\u017c dotychczasowa. Nowe atrybuty mog\u0142y zosta\u0107 dodane lub usuni\u0119te albo zosta\u0142 zmieniony typ danych atrybutu. Aby nie utraci\u0107 \u017cadnych danych, konieczne jest przeniesienie danych danych z poprzedniej tabeli bazy danych obiektu biznesowego do nowej tabeli.<\/p>\n<p>Ze wzgl\u0119du na wspomniane zmiany strukturalne koniecznym mo\u017ce okaza\u0107 si\u0119 przekonwertowanie danych podczas ich przenoszenia ze starej do nowej tabeli. Dla nowo dodanych atrybut\u00f3w nale\u017cy ustawi\u0107 warto\u015bci domy\u015blne, w celu zdefiniowania stanu pocz\u0105tkowego. Przy zmianie danych atrybutu wymagane s\u0105 funkcje pozwalaj\u0105ce na konwertowanie warto\u015bci atrybutu ze starego na nowy typ danych. W tym celu programista musi zapisa\u0107 program aktualizacji dla danego obiektu biznesowego, kt\u00f3ry jest stosowany przez system do przesy\u0142ania danych pomi\u0119dzy star\u0105 i now\u0105 tabel\u0105 bazy danych oraz do konwersji danych.<\/p>\n<p>W przypadku wi\u0119kszych zmian strukturalnych dotycz\u0105cych wielu obiekt\u00f3w biznesowych lub w przypadku zmiany semantyki atrybut\u00f3w wymagane jest okre\u015blenie bardziej z\u0142o\u017conych regu\u0142 konwersji, w celu korekty lub migracji danych.<br \/>\nS\u0142u\u017cy do tego specjalny typ aplikacji w systemie ERP, aktualizacje danych.<\/p>\n<h4 id=\"generowanie-obiektow-biznesowych\" ><span class=\"ez-toc-section\" id=\"Generowanie_obiektow_biznesowych\"><\/span>Generowanie obiekt\u00f3w biznesowych<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Przebieg procesu generowania jest \u015bci\u015ble zwi\u0105zany ze statusem przynale\u017cnego zadania deweloperskiego.<\/p>\n<p>Aby utworzy\u0107 lub edytowa\u0107 obiekt biznesowy, musi on by\u0107 uwzgl\u0119dniony w istniej\u0105cym zadaniu deweloperskim. Po zmianie schematu obiektu biznesowego, np. dodaniu nowego atrybutu, rozpoczyna si\u0119 faza generowania, w kt\u00f3rej nale\u017cy uruchomi\u0107 odpowiednie narz\u0119dzia za pomoc\u0105 wiersza polece\u0144 SAS.<\/p>\n<p>Obiekt biznesowy jest generowany przez wywo\u0142anie narz\u0119dzi z odpowiednimi parametrami w kilku etapach, kt\u00f3re musz\u0105 by\u0107 wykonane w okre\u015blonej kolejno\u015bci. Dla ka\u017cdego wywo\u0142ania nale\u017cy poda\u0107 numer zadania deweloperskiego za pomoc\u0105 parametru &#8222;-j:nummer&#8221; lub ewentualnie nazw\u0119 obiektu biznesowego (parametr -o:).<\/p>\n<h5 id=\"etap-1-wygenerowanie-obiektu-biznesowego\" ><span class=\"ez-toc-section\" id=\"Etap_1_%E2%80%93_wygenerowanie_obiektu_biznesowego\"><\/span>Etap 1 &#8211; wygenerowanie obiektu biznesowego<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Etap 1 jest podzielony na nast\u0119puj\u0105ce cz\u0119\u015bci:<\/p>\n<p>\u2022 Schema<br \/>\n\u2022 Source<br \/>\n\u2022 Generate<\/p>\n<p>S\u0105 one po\u0142\u0105czone w poni\u017cszym wywo\u0142aniu narz\u0119dzia:<\/p>\n<pre>crtbo \u2013j:nummer<\/pre>\n<p><em>Schema<\/em><\/p>\n<p>W tej cz\u0119\u015bci etapu tworzony jest szablon do generowania tabel w bazie danych (Table Description) na podstawie wprowadzonych metadanych obiektu biznesowego.<\/p>\n<p><em>Source<\/em><\/p>\n<p>W tej cz\u0119\u015bci etapu generowane s\u0105 klasy obiektu biznesowego i klasy mapuj\u0105ce w celu uzyskania dost\u0119pu do zmodyfikowanego schematu tabeli. Wygenerowane klasy Java s\u0105 przechowywane w katalogu roboczym wskazanego zadania deweloperskiego. Dla ka\u017cdego atrybutu NLS generowany jest obiekt biznesowy i klasy mapuj\u0105ce, poniewa\u017c tre\u015bci w j\u0119zyku dodatkowym jest przechowywana w oddzielnych tabelach bazy danych.<\/p>\n<p>Katalog roboczy zadania deweloperskiego, zawieraj\u0105cego nowe \u017ar\u00f3d\u0142a obiektu biznesowego, musi by\u0107 zintegrowany ze \u015brodowiskiem programistycznym, np. &#8222;Eclipse&#8221; i skompilowany. Lokalnie uruchomiony SAS musi uwzgl\u0119dnia\u0107 skompilowane Class Files dla kolejnych etap\u00f3w (patrz etap 2 i 3).<\/p>\n<p>Przebieg procesu generowania jest \u015bci\u015ble zwi\u0105zany ze statusem przynale\u017cnego zadania deweloperskiego. Aby utworzy\u0107 lub edytowa\u0107 obiekt biznesowy, musi on by\u0107 uwzgl\u0119dniony w istniej\u0105cym zadaniu deweloperskim. Po zmianie schematu obiektu biznesowego, np. dodaniu nowego atrybutu, rozpoczyna si\u0119 faza generowania, w kt\u00f3rej nale\u017cy uruchomi\u0107 odpowiednie narz\u0119dzia za pomoc\u0105 wiersza polece\u0144 SAS.<\/p>\n<p><em>Generate<\/em><\/p>\n<p>W tej cz\u0119\u015bci etapu generowana jest tymczasowa tabela bazy danych dla nowego opisu tabeli (Table Description) w bazie danych. Powielane s\u0105 tylko tabele, kt\u00f3rych obiekty biznesowe znajduj\u0105 si\u0119 w zadaniu (a nie ca\u0142a baza danych dla ka\u017cdego zadania). Przyk\u0142adowo, je\u015bli obiekt biznesowy typu &#8222;Entity&#8221; znajduje si\u0119 w zadaniu deweloperskim, ale bez powi\u0105zanych element\u00f3w zale\u017cnych, w\u00f3wczas przy tworzenia nowej instancji jednostki nale\u017cy zapisa\u0107 j\u0105 w nowej tabeli tymczasowej, a powi\u0105zane instancje zale\u017cne w ich starych aktywnych tabelach. Wszyscy inni u\u017cytkownicy w systemie zapisuj\u0105 nowe instancje jednostek tylko do aktywnych tabel ze starymi aktywnymi mapperami. Oznacza to, \u017ce w bazie danych generowane s\u0105 niesp\u00f3jne stany. Nale\u017cy mie\u0107 tego \u015bwiadomo\u015b\u0107 podczas testowania wi\u0119kszych jednostek. Tabele tymczasowe s\u0105 zabezpieczone przed zapisem i przy pr\u00f3bie wpisu do tabeli pojawia si\u0119 wyj\u0105tek. To zachowanie mo\u017cna zmieni\u0107 za pomoc\u0105 parametru pocz\u0105tkowego &#8222;-writeConvertedTables&#8221; serwera aplikacji. Parametr ten mo\u017ce by\u0107 zastosowany, je\u015bli np. zmieniony obiekt biznesowy nie posiada dependents, a programista chce edytowa\u0107 aplikacj\u0119 w tym samym zadaniu co obiekt biznesowy.<\/p>\n<h5 id=\"etap-2-klasy-update\" ><span class=\"ez-toc-section\" id=\"Etap_2_%E2%80%93_Klasy_Update\"><\/span>Etap 2 &#8211; Klasy Update<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>W tym etapie nast\u0119puje programowanie klas aktualizacji, kt\u00f3re zapewniaj\u0105 poprawny transfer danych z aktywnej tabeli systemu do nowej tabeli tymczasowej.<br \/>\nObiekty biznesowe atrybut\u00f3w NLS posiadaj\u0105 r\u00f3wnie\u017c w\u0142asne klasy aktualizacji s\u0142u\u017c\u0105ce konwersji tre\u015bci w j\u0119zyku dodatkowym mi\u0119dzy star\u0105 a now\u0105 tabel\u0105 NLS.<br \/>\nWi\u0119cej informacji na temat klas aktualizacji mo\u017cna znale\u017a\u0107 w rozdziale Rozw\u00f3j klas Update.<\/p>\n<h5 id=\"etap-3-konwersja-obiektu-biznesowego\" ><span class=\"ez-toc-section\" id=\"Etap_3_%E2%80%93_Konwersja_obiektu_biznesowego\"><\/span>Etap 3 &#8211; Konwersja obiektu biznesowego<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Ten etap obejmuje przeniesienie danych ze starej tabeli aktywnej w systemie do nowej tabeli tymczasowej. W tym celu nale\u017cy zastosowa\u0107 nast\u0119puj\u0105ce wywo\u0142anie narz\u0119dzia:<\/p>\n<pre>cnvbo -j:number<\/pre>\n<p>System pobiera i konwertuje dane ze starej do nowej tabeli bazy danych przy u\u017cyciu nowych klas aktualizacji. Nale\u017cy upewni\u0107 si\u0119, \u017ce nowe klasy aktualizacji znajduj\u0105 si\u0119 w \u015bcie\u017cce klas serwera aplikacji, na kt\u00f3rym przeprowadzana jest konwersja.<\/p>\n<p>W przypadku b\u0142\u0119d\u00f3w konwersji danych, proces jest anulowany i powinien zosta\u0107 powt\u00f3rzony z poprawionymi klasami aktualizacji. Ten krok mo\u017cna powtarza\u0107 dowoln\u0105 ilo\u015b\u0107 razy, poniewa\u017c tabela tymczasowa jest ca\u0142kowicie czyszczona przed konwersj\u0105.<\/p>\n<h5 id=\"etap-4-rozwoj-i-testy\" ><span class=\"ez-toc-section\" id=\"Etap_4_%E2%80%93_Rozwoj_i_testy\"><\/span>Etap 4 &#8211; Rozw\u00f3j i testy<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>W tym etapie wykonywane s\u0105 testy konwersji, dalszy rozw\u00f3j programu i testy. Po zmianie schematu w obiekcie biznesowym powinno si\u0119 r\u00f3wnie\u017c odpowiednio dostosowa\u0107 aplikacje, kt\u00f3re wykorzystuj\u0105 ten obiekt biznesowy. Na koniec nale\u017cy zaewidencjonowa\u0107 (check in) \u017ar\u00f3d\u0142a w systemie za pomoc\u0105 aplikacji &#8222;Zadania deweloperskie&#8221;.<\/p>\n<p><em>Dost\u0119p do tabeli tymczasowych<\/em><\/p>\n<p>W celu uzyskania dost\u0119pu do tabeli bazy danych obiektu biznesowego lokalny SAS u\u017cywa nowo wygenerowanych klas mappera, kt\u00f3re uzyskuj\u0105 dost\u0119p do tabeli tymczasowej. Dla aplikacji dzia\u0142aj\u0105cych na tym SAS, nowa wersja jest wersj\u0105 aktywn\u0105 i dlatego dzia\u0142aj\u0105 w\u0142a\u015bnie na niej. Inne SAS-y, kt\u00f3re nie zintegrowa\u0142y nowych klas obiekt\u00f3w biznesowych,<br \/>\ndzia\u0142aj\u0105 na starej aktywnej wersji.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7884\" src=\"https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2024\/01\/tabele-tymczasowe.png\" alt=\"\" width=\"471\" height=\"296\" srcset=\"https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/tabele-tymczasowe.png 471w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/tabele-tymczasowe-300x189.png 300w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/tabele-tymczasowe-50x31.png 50w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/tabele-tymczasowe-320x201.png 320w\" sizes=\"auto, (max-width: 471px) 100vw, 471px\" \/><\/p>\n<p><em>Widoki tymczasowe<\/em><\/p>\n<p>R\u00f3wnie\u017c widoki s\u0105 najpierw tworzone tymczasowo, aby programista mia\u0142 mo\u017cliwo\u015b\u0107 przetestowania zmienionego widoku przed jego aktywacj\u0105. Widok mo\u017ce r\u00f3wnie\u017c uzyskiwa\u0107 dost\u0119p do tymczasowych tabel obiekt\u00f3w biznesowych, kt\u00f3re znajduj\u0105 si\u0119 w tym samym zadaniu deweloperskim co sam widok.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7886\" src=\"https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2024\/01\/tabele-widoki.png\" alt=\"\" width=\"403\" height=\"281\" srcset=\"https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/tabele-widoki.png 403w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/tabele-widoki-300x209.png 300w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/tabele-widoki-50x35.png 50w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/tabele-widoki-320x223.png 320w\" sizes=\"auto, (max-width: 403px) 100vw, 403px\" \/><\/p>\n<p><em>Usuwanie obiektu biznesowego z zadania<\/em><\/p>\n<p>Obiektu biznesowego nie mo\u017cna usun\u0105\u0107 z zadania deweloperskiego za pomoc\u0105 aplikacji &#8222;Obiekty deweloperskie&#8221;. Aby<br \/>\nusun\u0105\u0107 obiekt biznesowy, cz\u0119\u015b\u0107 lub widok, nale\u017cy u\u017cy\u0107 narz\u0119dzia &#8222;rmvbo&#8221;:<\/p>\n<pre>rmvbo \u2013o:Objektname<\/pre>\n<p>Narz\u0119dzie usuwa tabele tymczasowe z bazy danych i usuwa obiekt biznesowy z zadania deweloperskiego razem z utworzonymi dla niego \u017ar\u00f3d\u0142ami.<\/p>\n<h5 id=\"etap-5-zwolnienie-zadania-deweloperskiego\" ><span class=\"ez-toc-section\" id=\"Etap_5_%E2%80%93_Zwolnienie_zadania_deweloperskiego\"><\/span>Etap 5 &#8211; Zwolnienie zadania deweloperskiego<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Po edycji obiektu biznesowego i innych obiekt\u00f3w deweloperskich nale\u017cy zwolni\u0107 zadanie deweloperskie, w ramach kt\u00f3rego naniesiono zmiany. Po zwolnieniu zadania nie ma ju\u017c mo\u017cliwo\u015bci dalszej edycji obiektu biznesowego i innych obiekt\u00f3w deweloperskich.<\/p>\n<h5 id=\"etap-6-aktywacja-obiektu-biznesowego\" ><span class=\"ez-toc-section\" id=\"Etap_6_%E2%80%93_Aktywacja_obiektu_biznesowego\"><\/span>Etap 6 &#8211; Aktywacja obiektu biznesowego<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Ten etap ko\u0144czy proces generowania. Aktywne tabele s\u0105 zast\u0119powane nowymi tabelami tymczasowymi, a zawarto\u015b\u0107 jest przenoszona do nowej tabeli przy u\u017cyciu klas Update:<\/p>\n<pre>actbo \u2013j:nummer<\/pre>\n<h5 id=\"etap-7-aktywacja-zadania-deweloperskiego\" ><span class=\"ez-toc-section\" id=\"Etap_7_%E2%80%93_Aktywacja_zadania_deweloperskiego\"><\/span>Etap 7 &#8211; Aktywacja zadania deweloperskiego<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Ostatnim etapem procesu rozwoju jest aktywowanie zadania deweloperskiego.<\/p>\n<h4 id=\"rozwoj-klas-update\" ><span class=\"ez-toc-section\" id=\"Rozwoj_klas_Update\"><\/span>Rozw\u00f3j klas Update<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Klasy aktualizacji zawieraj\u0105 logik\u0119 do konwersji danych starszej wersji obiektu biznesowego na wersj\u0119 aktywn\u0105. Klasy aktualizacji zawieraj\u0105 informacje dla ka\u017cdej zmienionej kolumny obiektu biznesowego informacje o tym, w jaki spos\u00f3b ma by\u0107 obs\u0142ugiwana zmiana w kolumnie.<\/p>\n<p>Klasy aktualizacji sk\u0142adaj\u0105 si\u0119 z nast\u0119puj\u0105cych klas Java:<\/p>\n<ul>\n<li>UpdateBase &#8211; jest generowana podczas tworzenia obiektu biznesowego. W klasie UpdateBase generowana jest metoda abstrakcyjna dla ka\u017cdego utworzenia nowej kolumny, zmiany lub usuni\u0119cia kolumny. Klasa UpdateBase nie mo\u017ce by\u0107 dostosowywana.<\/li>\n<li>UpdateLogic &#8211; jest tworzona jednorazowo z klas\u0105 UpdateBase, p\u00f3\u017aniej nie jest ju\u017c ponownie generowana. Klasa<br \/>\nUpdateLogic dziedziczy po UpdateBase i mo\u017ce zosta\u0107 rozszerzona w przypadku zmian model\u00f3w danych. Nale\u017cy zaimplementowa\u0107 wszystkie metody abstrakcyjne, ale nie nadpisywa\u0107 metod nieabstrakcyjnych w celu zapisu innej implementacji. Klasa UpdateLogic powinna by\u0107 zmieniana tylko w tym systemie, w kt\u00f3rym zosta\u0142 utworzony lub modyfikowany powi\u0105zany obiekt biznesowy lub rozszerzenie.<\/li>\n<\/ul>\n<p>Dla ka\u017cdego obiektu biznesowego i ka\u017cdego rozszerzenia istniej\u0105 oddzielne klasy aktualizacji. Ka\u017cda z klas odpowiada za atrybuty przypisanego obiektu. Klasy aktualizacji nale\u017c\u0105 do obszaru nazw &#8222;com.&lt;prefiks deweloperski&gt;.upd&#8221;, np. &#8222;com.cisag.upd.app&#8230;&#8221;.<\/p>\n<p>Zmiany modelu danych s\u0105 opracowywane oddzielnie dla ka\u017cdej kolumny. Ka\u017cde utworzenie nowego elementu, zmiana lub usuni\u0119cie jest odpowiednio oznaczone w kolumnie, aby by\u0142o wiadomo, jak i z kt\u00f3r\u0105 wersj\u0105 kolumna zosta\u0142a zmieniona. Podczas normalnej edycji wszystkie zmiany kolumn s\u0105 zapisywane w standardowym dzia\u0142aniu, kt\u00f3re mo\u017ce zosta\u0107 zmienione\/nadpisane przez programist\u0119. W miar\u0119 mo\u017cliwo\u015bci zmiany s\u0105 przeprowadzane w tej samej kolejno\u015bci, co podczas programowania.<\/p>\n<p>Klasy aktualizacji obs\u0142uguj\u0105 nast\u0119puj\u0105ce operacje:<\/p>\n<ul>\n<li>inicjalizacja nowej kolumny (metoda Init)\n<ul>\n<li>sta\u0142e warto\u015bci pocz\u0105tkowe<\/li>\n<li>wyliczone warto\u015bci pocz\u0105tkowe<\/li>\n<\/ul>\n<\/li>\n<li>usuwanie kolumny (znacznik usuwania na metodzie Init)<\/li>\n<li>zmiana typu danych dla istniej\u0105cych kolumn (metoda ChangeDatatype)\n<ul>\n<li>kompatybilna zmiana typu danych<\/li>\n<li>niekompatybilna zmiana typu danych<\/li>\n<\/ul>\n<\/li>\n<li>podstawowe korekty danych<\/li>\n<\/ul>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><\/p>\n<p>Funkcjonowanie klas aktualizacji<\/p>\n<p>Pogrubiona czcionk\u0105 zaznaczone s\u0105 zmiany w obiekcie biznesowym i stosowane metody klas aktualizacji<\/p>\n<p><figure id=\"attachment_7890\" aria-describedby=\"caption-attachment-7890\" style=\"width: 658px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-7890 size-full\" src=\"https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2024\/01\/DatabaseModifications_Standarddevelopment.png\" alt=\"\" width=\"658\" height=\"136\" srcset=\"https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/DatabaseModifications_Standarddevelopment.png 658w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/DatabaseModifications_Standarddevelopment-300x62.png 300w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/DatabaseModifications_Standarddevelopment-50x10.png 50w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/DatabaseModifications_Standarddevelopment-600x124.png 600w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/DatabaseModifications_Standarddevelopment-320x66.png 320w\" sizes=\"auto, (max-width: 658px) 100vw, 658px\" \/><figcaption id=\"caption-attachment-7890\" class=\"wp-caption-text\">Klasy aktualizacji dla zmian w standardzie<\/figcaption><\/figure><\/p>\n<p>Obiekt biznesowy &#8222;Item&#8221; jest zmieniany dwukrotnie. Najpierw atrybut &#8222;description&#8221; jest skracany ze 100 do 80 znak\u00f3w, a nast\u0119pnie dodawany jest atrybut &#8222;unit&#8221;.<\/p>\n<ul>\n<li>metoda <em>changeDatatype\u20acdescription\u20acstr100_str80<\/em> oblicza niekompatybiln\u0105 zmian\u0119 typu danych atrybutu &#8222;description&#8221;<\/li>\n<li>metoda <em>init\u20acunit\u20acGUID<\/em> oblicza warto\u015b\u0107 pocz\u0105tkow\u0105 dla nowego atrybutu &#8222;unit&#8221;.<\/li>\n<\/ul>\n<p>Metody te s\u0105 wywo\u0142ywane podczas konwersji.<\/p>\n<p><\/div><\/section>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><\/p>\n<p>Programowanie partnera<\/p>\n<p><figure id=\"attachment_7891\" aria-describedby=\"caption-attachment-7891\" style=\"width: 650px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-7891 size-full\" src=\"https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2024\/01\/DatabaseModifications_Partnerdevelopment.png\" alt=\"\" width=\"650\" height=\"189\" srcset=\"https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/DatabaseModifications_Partnerdevelopment.png 650w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/DatabaseModifications_Partnerdevelopment-300x87.png 300w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/DatabaseModifications_Partnerdevelopment-50x15.png 50w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/DatabaseModifications_Partnerdevelopment-600x174.png 600w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/01\/DatabaseModifications_Partnerdevelopment-320x93.png 320w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><figcaption id=\"caption-attachment-7891\" class=\"wp-caption-text\">Utworzenie Extension i implementacja rozszerzenia standardu<\/figcaption><\/figure><\/p>\n<p>Najpierw tworzone jest rozszerzenie dla obiektu biznesowego &#8222;Item&#8221; z atrybutami abc_type i abc_color, a nast\u0119pnie<br \/>\nimplementowana jest wersja 1.1 obiektu &#8222;Item&#8221;. Dzi\u0119ki rozszerzeniu nie jest konieczna r\u0119czna obs\u0142uga konflikt\u00f3w na klasach aktualizacji obiektu biznesowego.<\/p>\n<ul>\n<li>metoda <em>init\u20acabc_type\u20acVS<\/em> oblicza warto\u015b\u0107 pocz\u0105tkow\u0105 dla kolumny <em>abc_type<\/em><\/li>\n<li>metoda <em>init\u20acabc_color\u20acVS<\/em> oblicza warto\u015b\u0107 pocz\u0105tkow\u0105 dla kolumny <em>abc_color<\/em><\/li>\n<\/ul>\n<p>Podczas tworzenia rozszerzenia wywo\u0142ywane s\u0105 metody klas aktualizacji dla rozszerzenia. Podczas zmiany<br \/>\nodno\u015bnego obiektu biznesowego &#8222;Item&#8221; nie musz\u0105 by\u0107 zmieniane klasy aktualizacji, nie s\u0105 te\u017c wywo\u0142ywane \u017cadne metody klasy aktualizacji dla rozszerzenia.<\/p>\n<p><\/div><\/section>\n<p><em>Metoda Init<\/em><\/p>\n<p>Za pomoc\u0105 metody <em>Init<\/em> obliczana jest warto\u015b\u0107 pocz\u0105tkowa podczas tworzenia nowej kolumny. Warto\u015b\u0107 pocz\u0105tkowa jest wymagana w sytuacji, gdy kolumna istnieje w nowej wersji obiektu biznesowego, ale nie istnieje w starej wersji. W zale\u017cno\u015bci od metody aktualizacji, metoda <em>Init<\/em> jest u\u017cywana w r\u00f3\u017cny spos\u00f3b.<\/p>\n<p>Metoda <em>Init<\/em> jest generowana w klasie &#8222;UpdateBase&#8221; ze sta\u0142\u0105 warto\u015bci\u0105 pocz\u0105tkow\u0105. Metoda <em>Init<\/em> mo\u017ce zosta\u0107 nadpisana w klasie &#8222;UpdateLogic&#8221; przez inn\u0105 metod\u0119 aktualizacji w celu obliczenia innej warto\u015bci pocz\u0105tkowej.<\/p>\n<p>Nazwa metody <em>Init<\/em> sk\u0142ada si\u0119 z nast\u0119puj\u0105cych element\u00f3w:\\<\/p>\n<p>&lt;Java-Datatype&gt; init\u20ac&lt;AttributePath&gt;\u20ac<br \/>\n&lt;Datatype&gt;(CisGenericObject object)<\/p>\n<p>\u015acie\u017cka atrybutu kolumny odpowiada nazwie kolumny w j\u0119zyku OQL. Nawiasy kwadratowe &#8222;[]&#8221; i kropka &#8222;.&#8221; s\u0105 zast\u0119powane przez znak dolara &#8222;$&#8221;, tak aby \u015bcie\u017cka atrybutu mog\u0142a by\u0107 u\u017cywana jako identyfikator metody.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\">Je\u015bli \u015bcie\u017cka atrybutu w OQL to &#8222;discounts[1].discountType&#8221;, to w nazwie metody wykorzystany zostanie ci\u0105g znak\u00f3w &#8222;discounts$1$$discountType&#8221;.<\/div><\/section>\n<p>Parametr <em>object<\/em> zawiera stan instancji przed inicjalizacj\u0105 nowej kolumny. W przypadku metody aktualizacji CONSTANT i metody aktualizacji DATABASE warto\u015b\u0107 parametru <em>object<\/em> wynosi zero.<\/p>\n<p>W przypadku atrybutu cz\u0119\u015bci (part), opr\u00f3cz metod <em>init<\/em> dla powi\u0105zanych kolumn, generowana jest r\u00f3wnie\u017c metoda <em>init<\/em> dla kolumny boolean cz\u0119\u015bci. Jej \u015bcie\u017ck\u0105 atrybutu jest \u015bcie\u017cka atrybutu cz\u0119\u015bci. Zwracana warto\u015b\u0107 metody wskazuje, czy warto\u015b\u0107 cz\u0119\u015bci jest prawid\u0142owa czy nie. Aby inicjowa\u0107 atrybut cz\u0119\u015bci z warto\u015bci\u0105, metoda <em>init<\/em> dla kolumny boolean cz\u0119\u015bci musi zosta\u0107 nadpisana w ten spos\u00f3b, aby zwraca\u0142a warto\u015b\u0107 <em>true<\/em>.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><\/p>\n<p>Obliczenie warto\u015bci pocz\u0105tkowej kolumny &#8222;description&#8221; z typem danych &#8222;String&#8221; i d\u0142ugo\u015bci\u0105 100.<br \/>\nTa kolumna zosta\u0142a utworzona w wersji 7.3 w wydaniu 5 (release).]<\/p>\n<p>Klasa UpdateBase<\/p>\n<pre>@History(created={\u201c7.3:5.0.0\u201c)\n@Update(method=CONSTANT)\nString init\u20acdescription\u20acstr100(CisGenericObject object) {\nreturn \u201c\u201d;\n}<\/pre>\n<p>Klasa UpdateLogic<\/p>\n<pre>@override\n@Update(method=INSTANCE)\nString init\u20acdescription\u20acstr100(CisGenericObject object) {\nreturn \u201cArtikel \u201c+object.getString(\u201cnumber\u201d);\n}<\/pre>\n<p><\/div><\/section>\n<p><em>Metoda ChangeDatatype<\/em><\/p>\n<p>Typ danych kolumny mo\u017cna zmieni\u0107. Aby przekonwertowa\u0107 zawarto\u015b\u0107 kolumny ze starego na nowy typ danych, wymagane jest obliczenie. Odbywa si\u0119 ono metod\u0105 ChangeDatatype, kt\u00f3ra jest generowana w klasie UpdateBase:<\/p>\n<pre>&lt;Java-TargetDatatype&gt;\nchangeDatatype\u20ac&lt;AttributePath&gt;\u20ac&lt;SourceDatatype&gt;_&lt;TargetDatatype&gt;(CisGenericObject object)<\/pre>\n<p>Na metodzie ChangeDatatype adnotacja <em>history<\/em> z w\u0142a\u015bciwo\u015bci\u0105 <em>created <\/em>wskazuje, z kt\u00f3r\u0105 wersj\u0105 zmieniony zosta\u0142 typ danych.<\/p>\n<p>Zmiana modelu danych jest kompatybilna, je\u015bli prymitywny typ danych nie zosta\u0142 zmieniony, a d\u0142ugo\u015b\u0107 typu danych zosta\u0142a zwi\u0119kszona. Wszystkie inne zmiany s\u0105 niekompatybilne.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\">Zmiana ci\u0105gu 80 na ci\u0105g 100 jest kompatybilna.<br \/>\nZmiana ci\u0105gu 100 na ci\u0105g 90 jest niekompatybilna.<br \/>\nZmiana Boolean na ValueSet jest niekompatybilna.<\/div><\/section>\n<p>Je\u015bli zmiana typu danych by\u0142a niekompatybilna, w\u00f3wczas metody ChangeDatatype w klasie &#8222;UpdateBase&#8221; s\u0105 generowane abstrakcyjnie i musz\u0105 zosta\u0107 zaimplementowane przez programist\u0119. Niekompatybilne zmiany modelu danych zawsze posiadaj\u0105 &#8222;UpdateMethod INSTANCE&#8221; i dlatego musz\u0105 by\u0107 obliczane dla ka\u017cdej instancji.<\/p>\n<p>Je\u015bli zmiana typu danych by\u0142a kompatybilna, w\u00f3wczas metody ChangeDatatype w klasie &#8222;UpdateBase&#8221; s\u0105 generowane jako ostateczne i nie mog\u0105 zosta\u0107 nadpisane przez programist\u0119. Kompatybilne zmiany modelu danych zawsze posiadaj\u0105 &#8222;UpdateMethod CONSTANT&#8221; i dlatego mog\u0105 by\u0107 obliczane na bazie danych.<\/p>\n<section class=\"document-alert-box indicator\"><div class=\"document-alert-title\">Wskaz\u00f3wka<\/div><div class=\"document-alert-content\">Nie mo\u017cna zmieni\u0107 metody aktualizacji dla metody ChangeDatatype. Niekompatybilne zmiany zwi\u0119kszaj\u0105 koszty zwi\u0105zane z rozwi\u0105zywaniem konflikt\u00f3w w kolejnych systemach. Nale\u017cy unika\u0107 niekompatybilnych zmian modelu danych. Niekompatybilne zmiany model\u00f3w danych s\u0105 szczeg\u00f3lnie problematyczne w przypadku r\u00f3wnoleg\u0142ej konserwacji (double maintenance)<\/div><\/section>\n<p>Klasa UpdateBase<\/p>\n<pre>@History(created={\u201c7.1:5.0.0\u201c})\n@Update(method=UpdateMethod.CONSTANT)\nfinal String changeDatatype\u20acdescription\u20acstr80_str100(CisGenericObject object) {\nreturn object.getString(\u201cdescription\u201d);\n}\n@History(created={\u201c8.1:5.0.0\u201c})\n@Update(method=UpdateMethod.INSTANCE)\nabstract String changeDatatype\u20acdescription\u20acstr100_str90(CisGenericObject object);<\/pre>\n<p>Klasa UpdateLogic<\/p>\n<pre>@override\nString changeDatatype\u20acdescription\u20acstr100_str90(CisGenericObject object) {\nString value = object.getString(\u201cdescription\u201d);\nif (value.length()&lt;=90) {\nreturn value;\n} else {\nreturn value.substring(0,87)+\u201d\u2026\u201d;\n}\n}<\/pre>\n<p><em>Usuwanie instancji<\/em><\/p>\n<p>Je\u015bli instancja ma zosta\u0107 usuni\u0119ta, a nie przekonwertowana, w\u00f3wczas jedna z wywo\u0142anych metod modyfikacji musi zawiera\u0107 metod\u0119 <em>delete()<\/em>. Powoduje to anulowanie konwersji bie\u017c\u0105cej instancji i jej odrzucenie.<br \/>\nPo wykonaniu metody delete() nale\u017cy zamkn\u0105\u0107 metod\u0119 modyfikacji za pomoc\u0105 <em>return<\/em>. Po delete() nie mo\u017ce ju\u017c by\u0107 \u017cadnych innych komend.<\/p>\n<p><em>Adnotacja Update<\/em><\/p>\n<p>Adnotacja aktualizacji okre\u015bla, czy konwersja kolumny musi by\u0107 wywo\u0142ywana dla ka\u017cdej instancji lub czy wszystkie instancje danej bazy danych mog\u0105 by\u0107 obs\u0142ugiwane w ten sam spos\u00f3b. W\u0142a\u015bciwo\u015b\u0107 <em>method<\/em> adnotacji aktualizacji precyzuje kontekst wywo\u0142ania, zwany w dalszej cz\u0119\u015bci dokumentu &#8222;metod\u0105 aktualizacji&#8221;.<\/p>\n<p><em>Metoda aktualizacji CONSTANT <\/em><\/p>\n<p>W przypadku metody aktualizacji CONSTANT nie jest przekazywana \u017cadna konkretna instancja obiektu biznesowego. Metoda nie ma mo\u017cliwo\u015bci dost\u0119pu do \u017cadnych obiekt\u00f3w w \u017cadnej bazie danych. Wynik metody jest stosowany do dowolnej liczby instancji w dowolnej bazie danych.<\/p>\n<p>Sk\u0142adnia:<\/p>\n<pre>@Update(method=UpdateMethod.CONSTANT)<\/pre>\n<p><em>Metoda aktualizacji DATABASE<\/em><\/p>\n<p>W przypadku metody aktualizacji DATABASE \u017cadna konkretna instancja obiektu biznesowego nie jest do niej przekazywana. Metoda mo\u017ce uzyska\u0107 generyczny dost\u0119p do obiekt\u00f3w bazy danych. Wynik metody jest stosowany do wszystkich instancji w danej bazie danych.<\/p>\n<p>Sk\u0142adnia:<\/p>\n<pre>@Update(method=UpdateMethod.DATABASE)<\/pre>\n<p><em>Metoda aktualizacji INSTANCE<\/em><\/p>\n<p>W przypadku metody aktualizacji INSTANCE przekazywana jest okre\u015blona instancja obiektu biznesowego.<br \/>\nDla tej instancji musi zosta\u0107 wyliczona konwersja. Metoda mo\u017ce uzyska\u0107 generyczny dost\u0119p do obiekt\u00f3w bazy danych.<br \/>\nWynik metody jest stosowany tylko dla tej przekazanej instancji.<\/p>\n<p>Zastosowanie co najmniej jednej metody poprzez metod\u0119 aktualizacji INSTANCE zawsze skutkuje konwersj\u0105 instancja po instancji. Nale\u017cy pami\u0119ta\u0107, \u017ce metoda jest wywo\u0142ywana dla ka\u017cdej instancji. W przypadku wykonywania z\u0142o\u017conych oblicze\u0144 w tej metodzie, konwersja danych w kolejnych systemach mo\u017ce potrwa\u0107 do\u015b\u0107 d\u0142ugo.<\/p>\n<p>Sk\u0142adnia:<\/p>\n<pre>@Update(method=UpdateMethod.INSTANCE)<\/pre>\n<p><em>Generyczny dost\u0119p do obiekt\u00f3w biznesowych<\/em><\/p>\n<p>Klasa com.cisag.pgm.datatype.CisGenericObject umo\u017cliwia generyczny dost\u0119p do dowolnej wersji obiektu biznesowego. Kolumny generycznego obiektu biznesowego mog\u0105 by\u0107 wyszukiwane poprzez \u015bcie\u017ck\u0119 atrybutu. Dla ka\u017cdego prymitywnego typu danych, jak r\u00f3wnie\u017c dla\u00a0<em>special parts <\/em>istniej\u0105 odpowiednie metody<em> get <\/em>i<em> set.<\/em><\/p>\n<p><em><section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><\/em><\/p>\n<p>Zapytanie o kolumn\u0119 ci\u0105gu\u00a0<em>description<\/em>:<\/p>\n<pre>object.getString(\u201ddescription\u201c);<\/pre>\n<p><em><\/div><\/section><\/em><\/p>\n<p><em>Dost\u0119p us\u0142ugi trwa\u0142o\u015bci danych<\/em><\/p>\n<p>Za pomoc\u0105 zwyk\u0142ych mapper\u00f3w obiekt\u00f3w biznesowych nie jest mo\u017cliwy dost\u0119p do obiekt\u00f3w biznesowych w klasach aktualizacji. Ka\u017cdy dost\u0119p us\u0142ugi trwa\u0142o\u015bci, np. getObject, kt\u00f3ry w innym przypadku zwr\u00f3ci\u0142by instancj\u0119 BusinessObject, w klasach aktualizacji zwraca obiekt generyczny.<\/p>\n<p>W dost\u0119pie generycznym do obiekt\u00f3w biznesowych mo\u017cna korzysta\u0107 ze wszystkich metod dost\u0119pu managera obiekt\u00f3w, tj. getObject, getObjectIterator, getResultSet, itp. Manager obiektu zawsze uzyskuje dost\u0119p do aktywnej wersji obiektu biznesowego w bazie danych. Mo\u017cna u\u017cy\u0107 generycznego dost\u0119pu do stanu bazy danych przed zmian\u0105 modelu danych. Nie mo\u017cna u\u017cywa\u0107 \u017cadnych metod managera obiekt\u00f3w, kt\u00f3re s\u0105 s\u0142u\u017c\u0105 do zapisu do bazy danych.<\/p>\n<p>Za pomoc\u0105 metody <em>buildPrimaryKey <\/em>mo\u017cna wygenerowa\u0107 klucz podstawowy lub uzale\u017cniony czasowo klucz podstawowy obiektu biznesowego.<\/p>\n<p><em><section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><\/em><\/p>\n<p>Przyk\u0142adowe zastosowanie <em>CisGenericObjects<\/em> przy pomocy <em>CisObjectManager<\/em>:<\/p>\n<pre>CisGenericObject item = (CisGenericObject)om.getObject(CisGenericObject.buildPrimaryKey(\u201dcom.cisag.app.general.obj.Item\u201c,ite\nmGuid)\noldDescription=item.getString(\u201ddescription\u201c);<\/pre>\n<p><em><\/div><\/section><\/em><\/p>\n<p><em>Inicjalizacja<\/em><\/p>\n<p>W celu konwersji danych obiektu biznesowego w bazie danych generowana jest jedna lub wi\u0119cej instancji klas aktualizacji. Klasy aktualizacji konwertuj\u0105 dane wersji \u017ar\u00f3d\u0142owej, tj. aktywnej\u00a0wersji w bazie danych, na wersj\u0119 docelow\u0105, tj. wersj\u0119 zablokowan\u0105 dla programisty w zadaniu deweloperskim.<\/p>\n<p>Zapytanie o schemat wersji \u017ar\u00f3d\u0142owej i docelowej mo\u017cna wykona\u0107 za pomoc\u0105 nast\u0119puj\u0105cych metod:<\/p>\n<pre>CisObjectSchema getFromSchema()\nCisObjectSchema getToSchema()<\/pre>\n<p>Metoda initialize() \u00a0klasy aktualizacji jest wywo\u0142ywana przed zastosowaniem na ka\u017cdej instancji. Metoda <em>initialize<\/em> mo\u017ce<br \/>\nzosta\u0107 nadpisana w klasie<em> UpdateLogic<\/em> w celu zainicjowania instancji klasy aktualizacji do zastosowania na bazie danych. W tej metodzie mo\u017cna uzyska\u0107 dost\u0119p odczytu do obiekt\u00f3w biznesowych za po\u015brednictwem dost\u0119pu generycznego.<\/p>\n<p>W metodzie <em>initialize<\/em> dla ka\u017cdej inicjalizacji nale\u017cy sprawdzi\u0107 za pomoc\u0105 metody <em>getFromSchema()<\/em>, czy jest ona wymagana. W celu weryfikacji nale\u017cy u\u017cy\u0107 schematu wersji \u017ar\u00f3d\u0142owej.<\/p>\n<section class=\"document-alert-box warning\"><div class=\"document-alert-title\">Uwaga<\/div><div class=\"document-alert-content\">W przypadku wykonywania z\u0142o\u017conych oblicze\u0144 w metodzie <em>initialize<\/em> bez warunku, obliczenia te b\u0119d\u0105 wykonywane przy ka\u017cdej zmianie modelu danych i mog\u0105 negatywnie wp\u0142yn\u0105\u0107 na czas wykonywania kolejnych zmian modelu danych.<\/div><\/section>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><\/p>\n<p>Dla metody <em>Init<\/em> kolumny &#8222;myUnit&#8221; warto\u015b\u0107 domy\u015blna jest obliczana w metodzie <em>initialize<\/em>. Warto\u015b\u0107 domy\u015blna jest wymagana tylko wtedy, gdy kolumna &#8222;myUnit&#8221; nie istnieje w wersji \u017ar\u00f3d\u0142owej.<\/p>\n<pre>byte[] myUnitDefault;\nvoid initialize() {\n\nif (getFromSchema().getColumn(\"myUnit\")==null) {\nmyUnitDefault=\u2026\n}\n}\n@override\n@Update(method=DATABASE)\nbyte[] init$myUnit$guid(CisGenericObject\nobject) {\nreturn myUnitDefault;\n}<\/pre>\n<p><\/div><\/section>\n<h4 id=\"aktualizacja-danych\" ><span class=\"ez-toc-section\" id=\"Aktualizacja_danych\"><\/span>Aktualizacja danych<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Programy aktualizacji, odnosz\u0105ce si\u0119 zawsze do obiektu biznesowego, mog\u0105 okaza\u0107 si\u0119 niewystarczaj\u0105ce. W\u00f3wczas wymagana jest specjalna aplikacja typu Aktualizacja danych, kt\u00f3ra przeprowadza korekt\u0119 lub migracj\u0119 danych.<br \/>\nTaka sytuacja mo\u017ce nast\u0105pi\u0107 w nast\u0119puj\u0105cych przypadkach:<\/p>\n<ul>\n<li>wprowadzono z\u0142o\u017cone zmiany schemat\u00f3w dla wielu obiekt\u00f3w biznesowych, w kt\u00f3rych dane s\u0105 ze sob\u0105 logicznie powi\u0105zane. Aby mo\u017cliwe by\u0142o okre\u015blenie prawid\u0142owych warto\u015bci, konwersja danych jednego obiektu biznesowego wymaga zdefiniowanego stanu wszystkich powi\u0105zanych obiekt\u00f3w deweloperskich. W takich przypadkach zmiany schematu s\u0105 najpierw aktywowane i, je\u015bli to konieczne, wcze\u015bniej pisane programy aktualizuj\u0105ce dla poszczeg\u00f3lnych obiekt\u00f3w biznesowych. Potem nast\u0119puje aktualizacja danych na zdefiniowanym stanie klasy.<\/li>\n<li>je\u015bli do konwersji danych maj\u0105 zosta\u0107 u\u017cyte zaimplementowane ju\u017c funkcje logiczne, nale\u017cy to zrobi\u0107 w aktualizacji danych, poniewa\u017c w programach aktualizacji nie mo\u017cna u\u017cywa\u0107 zewn\u0119trznych klas logicznych.<\/li>\n<li>musz\u0105 zosta\u0107 poprawione b\u0142\u0119dy czysto logiczne, a nie by\u0142o \u017cadnych zmian w schemacie. Programy aktualizuj\u0105ce s\u0105 wykonywane tylko w przypadku zmian w schemacie.<\/li>\n<li>w celu konwersji u\u017cytkownik musi jeszcze r\u0119cznie wprowadzi\u0107 dane<\/li>\n<\/ul>\n<p><em>Wady<\/em><\/p>\n<p>Je\u017celi to mo\u017cliwe, nale\u017cy zawsze u\u017cywa\u0107 program\u00f3w aktualizuj\u0105cych do korekty danych, poniewa\u017c s\u0105 one wykonywane automatycznie, gdy aktywowana jest nowa wersja obiektu biznesowego. Dzi\u0119ki temu zachowana jest prawid\u0142owa kolejno\u015b\u0107 przy wi\u0119kszej ilo\u015bci wersji. Mo\u017ce jednak okaza\u0107 si\u0119 konieczne r\u0119czne wykonanie niekt\u00f3rych aktualizacji danych po zainstalowaniu aktualizacji oprogramowania. Nie wolno o tym zapomnie\u0107, bo skutkiem by\u0142aby praca aplikacji na niepoprawnych danych, a w najgorszym przypadku wygenerowanie bezu\u017cytecznych danych. Poniewa\u017c aktualizacja danych wymaga zdefiniowanego statusu, istnieje ryzyko, \u017ce nie b\u0119dzie ona ju\u017c p\u00f3\u017aniej mo\u017cliwa, poniewa\u017c zostan\u0105 zainstalowane kolejne aktualizacje oprogramowania, a obiekty biznesowe, kt\u00f3rych dotyczy aktualizacja, s\u0105 dost\u0119pne w innych wersjach. Aktualizacje danych, kt\u00f3re wymagaj\u0105 r\u0119cznej interwencji, oznaczaj\u0105 wi\u0119cej pracy dla partnera, poniewa\u017c musi on przeprowadzi\u0107 ten proces na ka\u017cdym systemie, w kt\u00f3rym zaimplementowano aktualizacj\u0119 danych.<\/p>\n<p><em>Typy aktualizacji danych<\/em><\/p>\n<p>Istniej\u0105 r\u00f3\u017cne typy aktualizacji danych, kt\u00f3re r\u00f3\u017cni\u0105 si\u0119 sposobem ich wykonywania, przez co posiadaj\u0105 okre\u015blone zalety i wady. Istniej\u0105 nast\u0119puj\u0105ce typy:<\/p>\n<ul>\n<li>aktualizacja danych w dialogu<\/li>\n<li>aktualizacja danych wykonywana automatycznie podczas instalacji aktualizacji oprogramowania<\/li>\n<li>aktualizacja danych wykonywana w tle<\/li>\n<\/ul>\n<h3 id=\"dostep-odczytu-przez-managera-obiektow\" ><span class=\"ez-toc-section\" id=\"Dostep_odczytu_przez_managera_obiektow\"><\/span>Dost\u0119p odczytu przez managera obiekt\u00f3w<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Manager obiekt\u00f3w (klasa com.cisag.pgm.appserver.CisObjectManager) zapewnia deweloperowi metody dost\u0119pu do odczytu: <em>getObject(), getObjectArray(), getObjectIterator() <\/em>oraz <em>getResultSet()<\/em>. Zapytania mog\u0105 by\u0107 wykonywane na aktualnym \u015brodowisku:<\/p>\n<p>CisEnvironment env= CisEnvironment.getInstance();<br \/>\nCisObjectManager om= env.getObjectManager();<\/p>\n<section class=\"document-alert-box warning\"><div class=\"document-alert-title\">Uwaga<\/div><div class=\"document-alert-content\">Te metody s\u0105 przestarza\u0142e i nie powinny by\u0107 ju\u017c u\u017cywane w nowych programach: <em>public CisObjectIterator getObjectIterator(Stringmapper, String oqlString, int flags) i public CisResultSet getResultSet (String<\/em><br \/>\n<em>mapper, String oqlString)<\/em><\/div><\/section>\n<h4 id=\"metoda-getobject\" ><span class=\"ez-toc-section\" id=\"Metoda_getObject-2\"><\/span>Metoda <em>getObject()<\/em><span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Metoda <em>getObject()<\/em> odczytuje dok\u0142adnie jedn\u0105 instancj\u0119 obiektu biznesowego dla danego klucza us\u0142ugi trwa\u0142o\u015bci. Odczytywana jest zawsze ca\u0142a instancja ze wszystkimi atrybutami. Klucz us\u0142ugi trwa\u0142o\u015bci wymagany do identyfikacji wczytywanej instancji jest generowany przy u\u017cyciu odpowiedniej statycznej metody klasy obiektu biznesowego:<\/p>\n<ul>\n<li>Metoda s\u0142u\u017c\u0105ca do generowania klucza us\u0142ugi trwa\u0142o\u015bci z klucza podstawowego obiektu biznesowego: <em>buildPrimaryKey()<\/em><\/li>\n<li>Metoda <em>build&#8230;Key()<\/em> s\u0142u\u017cy do generowania klucza us\u0142ugi trwa\u0142o\u015bci z klucza funkcjonalnego lub innego klucza pomocniczego dla obiektu biznesowego, gdzie &#8222;&#8230;&#8221; odpowiada nazwie przekazanego klucza.<\/li>\n<\/ul>\n<p>Sygnatura metody to:<\/p>\n<pre>public &lt;T extends CisObject&gt; &lt;T&gt; getObject(byte[]\nkey, int flags)<\/pre>\n<p>Parametr\u00a0<em>key\u00a0<\/em>jest generowanym kluczem us\u0142ugi trwa\u0142o\u015bci. Parametr <em>flag <\/em>okre\u015bla zachowanie dost\u0119pu.<\/p>\n<p><em>Spos\u00f3b dzia\u0142ania getObject()<\/em><\/p>\n<p>Najpierw programista generuje klucz us\u0142ugi trwa\u0142o\u015bci za pomoc\u0105 odpowiedniej metody statycznej <em>build&#8230;Key()<\/em> klasy obiektu biznesowego. Nast\u0119pnie wywo\u0142ywana jest metoda <em>getObject()<\/em> na managerze obiekt\u00f3w z kluczem us\u0142ugi trwa\u0142o\u015bci i flagami dost\u0119pu jako parametrami. Manager obiekt\u00f3w pr\u00f3buje odczyta\u0107 instancj\u0119 obiektu biznesowego z pami\u0119ci podr\u0119cznej transakcji. Je\u015bli nie zostanie tam znaleziona, nast\u0119puje wyszukiwanie we wsp\u00f3\u0142dzielonej pami\u0119ci podr\u0119cznej. Je\u015bli i tam wyszukiwanie b\u0119dzie bezskuteczne, w\u00f3wczas nast\u0119puje dost\u0119p do bazy danych. Wykonywane jest nast\u0119puj\u0105ce zapytanie SQL, kt\u00f3re jako wynik zwraca jeden wiersz lub brak wiersza:<\/p>\n<pre>SELECT * FROM table WHERE keyAttributes='?'<\/pre>\n<p>Manager obiekt\u00f3w generuje instancj\u0119 klasy obiektu biznesowego, mapuje wynik zapytania na atrybuty i zwraca instancj\u0119 do aplikacji jako obiekt <em>CisObject<\/em>. Tutaj musi nast\u0105pi\u0107 <em>TypeCast<\/em> z og\u00f3lnej klasy <em>CisObject<\/em> na konkretn\u0105 klas\u0119 odczytywanego obiektu biznesowego. Je\u015bli nie uzyskano \u017cadnego wyniku z bazy danych, w\u00f3wczas zwracana jest warto\u015b\u0107 <em>null<\/em>.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><\/p>\n<p>Poni\u017cszy fragment kodu \u017ar\u00f3d\u0142owego \u0142aduje instancj\u0119 obiektu biznesowego\u00a0Item za pomoc\u0105 klucza podstawowego:<\/p>\n<pre>byte[] guid = ...;\nbyte[] primKey = Item.buildPrimaryKey( guid\n);\nItem item = om.getObject(primKey, CisObjectManager.READ);<\/pre>\n<p>Nast\u0119pny fragment kodu \u017ar\u00f3d\u0142owego \u0142aduje instancj\u0119 obiektu biznesowego Item za pomoc\u0105 klucza funkcjonalnego <em>number<\/em>:<\/p>\n<pre>String number = ...;\nbyte[] busKey = Item.buildByNumberKey( number );\nCisObject obj = om.getObject(busKey, CisObjectManager.READ);\nItem item = (Item) obj;<\/pre>\n<p>Je\u015bli obiekt biznesowy jest zale\u017cny od czasu i powinna zosta\u0107 za\u0142adowana inna wersja ni\u017c wersja aktywna, w\u00f3wczas stosowana jest metoda <em>buildTimeDependentKey()<\/em>. Jako parametry przekazywane s\u0105 atrybuty klucza podstawowego i atrybut <em>validFrom<\/em>:<\/p>\n<pre>byte[] guid = ...;\nDate validFrom = ...;\nbyte[] primKey = Item.buildTimeDependentKey(guid,\nvalidFrom);\nItem item = om.getObject(primKey, CisObjectManager.READ);<\/pre>\n<p><\/div><\/section>\n<h4 id=\"metoda-getobjectarray\" ><span class=\"ez-toc-section\" id=\"Metoda_getObjectArray\"><\/span>Metoda <em>getObjectArray()<\/em><span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Metoda <em>getObjectArray()<\/em> odczytuje wiele instancji jednego obiektu biznesowego dla podanych kluczy. Zawsze odczytywana jest ca\u0142a instancja ze wszystkimi atrybutami. Wymagany klucz us\u0142ugi trwa\u0142o\u015bci jest generowany przy u\u017cyciu odpowiedniej metody statycznej klasy obiektu biznesowego, na przyk\u0142ad <em>buildPrimaryKey()<\/em>, je\u015bli u\u017cywany jest klucz podstawowy. Mo\u017cna zastosowa\u0107 wszystkie unikalne klucze obiektu biznesowego.<\/p>\n<p>Sygnatury metody:<\/p>\n<pre>CisObject[] getObjectArray(byte[][] persKeys, int\nflags)\nCisObject[] getObjectArray(java.util.List persKeys, int flags)<\/pre>\n<p>Parametr <em>persKeys<\/em> jest tablic\u0105 lub list\u0105 kluczy us\u0142ugi trwa\u0142o\u015bci wygenerowanych z warto\u015bci kluczy instancji dla wczytywanych obiekt\u00f3w biznesowych.\u00a0Parametr <em>flags<\/em> okre\u015bla zachowanie dost\u0119pu.<\/p>\n<p><em>Spos\u00f3b dzia\u0142ania getObjectArray()<\/em><\/p>\n<p>Najpierw nale\u017cy wygenerowa\u0107 klucze us\u0142ugi trwa\u0142o\u015bci z kluczy podstawowych wczytywanych instancji obiekt\u00f3w biznesowych z zastosowaniem statycznej metody<em> buildPrimaryKey()<\/em> klasy obiekt\u00f3w biznesowych. Nast\u0119pnie na managerze obiekt\u00f3w wywo\u0142ywana jest metoda <em>getObjectArray()<\/em>, kt\u00f3ra jako parametry otrzymuje tablic\u0119 byte z kluczami us\u0142ugi trwa\u0142o\u015bci i flagami dost\u0119pu. Manager obiekt\u00f3w pr\u00f3buje odczyta\u0107 instancje obiektu biznesowego z pami\u0119ci podr\u0119cznej transakcji. Instancje, kt\u00f3re nie zosta\u0142y znalezione, s\u0105 wyszukiwane we wsp\u00f3\u0142dzielonej pami\u0119ci podr\u0119cznej. Pozosta\u0142e instancje, kt\u00f3rych r\u00f3wnie\u017c tam nie znaleziono, wyszukiwane s\u0105 w bazie danych za pomoc\u0105 zapytania SQL: <em>SELECT * FROM table WHERE primaryKeyAttributes IN<\/em><br \/>\n<em>(&#8217;?&#8217;,&#8230;,&#8217;?&#8217;)<\/em><\/p>\n<p>Manager obiekt\u00f3w generuje instancje klasy obiektu biznesowego, mapuje wynik zapytania na atrybuty i zwraca instancje do aplikacji jako tablic\u0119 CisObject. W tym miejscu musi nast\u0105pi\u0107 Type Cast z og\u00f3lnej klasy CisObject na konkretn\u0105 klas\u0119 odczytanych obiekt\u00f3w biznesowych. Je\u015bli nie znaleziono \u017cadnej instancji dla klucza, w\u00f3wczas odpowiednia pozycja w tablicy CisObject otrzymuje warto\u015b\u0107 zero. Je\u015bli nie znaleziono \u017cadnego wyniku, zwracana jest pusta tablica CisObject.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><\/p>\n<p>Poni\u017cszy fragment kodu \u017ar\u00f3d\u0142owego wczytuje obiektu biznesowego Item za pomoc\u0105 kluczy podstawowych:<\/p>\n<pre>byte[] primKey1 = Item.buildPrimaryKey( guid1\n);\n...\nbyte[] primKeyN = Item.buildPrimaryKey( guidN\n);\nbyte[][] primaryKeys = new byte[][]{primKey1,\n...., primKeyN};\nCisObject[] objects = om.getObjectArray(primaryKeys, CisTransactionManager.READ);\nfor (int i=0; i&lt; objects.length;i++) {\n\/\/ Position in objects entspricht Position\nin primaryKeys\nItem item = (Item) objects[i];\n...\n}<\/pre>\n<p><\/div><\/section>\n<h4 id=\"metody-getobjectlist\" ><span class=\"ez-toc-section\" id=\"Metody_getObjectList\"><\/span>Metody getObjectList()<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Podobnie jak w przypadku metody getObjectArray(), r\u00f3wnie\u017c metoda getObjectList() odczytuje wiele instancji obiektu biznesowego dla podanych kluczy. Funkcja getObjectList() i getObjectArray() jest identyczna, ale getObjectList() zwraca list\u0119 obiekt\u00f3w biznesowych, podczas gdy getObjectArray() zwraca tablic\u0119 \u00a0z obiektami biznesowymi. Rozmiar listy odpowiada liczbie przekazanych kluczy.<\/p>\n<p>Sygnatura metody:<\/p>\n<pre>&lt;T extends CisObject&gt; List&lt;T&gt; getObjectList(CisList persKeys, int flags)<\/pre>\n<p>Typ danych <em>List<\/em> jest jako zwracana warto\u015b\u0107 umo\u017cliwia prosty Type Cast na list\u0119 z faktycznie wczytanymi obiektami biznesowymi.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><\/p>\n<p>Poni\u017cszy fragment kodu \u017ar\u00f3d\u0142owego wczytuje instancje obiektu biznesowego Item za pomoc\u0105 kluczy podstawowych:<\/p>\n<pre>CisList primaryKeys = new CisArrayList();\nprimaryKeys.add(Item.buildPrimaryKey( guid1\n));\n...\nprimaryKeys.add(Item.buildPrimaryKey( guidN\n));\nList&lt;Item&gt; items = om.getObjectArray(primaryKeys,\nCisTransactionManager.READ);\nfor (Item item : items) {\n\/\/Position in items entspricht Position in\nprimaryKeys\n...\n}<\/pre>\n<p><\/div><\/section>\n<h4 id=\"metoda-getobjectiterator\" ><span class=\"ez-toc-section\" id=\"Metoda_getObjectIterator-2\"><\/span>Metoda getObjectIterator()<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Metoda getObjectIterator() odczytuje wiele instancji obiektu biznesowego. Odczytywana jest zawsze ca\u0142a instancja<br \/>\nze wszystkimi atrybutami. Metoda otrzymuje instrukcj\u0119 SELECT w j\u0119zyku OQL, kt\u00f3ra opisuje instancje do za\u0142adowania.<\/p>\n<p>Sygnatura metody:<\/p>\n<pre>&lt;T extends CisObject&gt; CisObjectIterator&lt;T&gt;\ngetObjectIterator(String oqlString, int flags)<\/pre>\n<p>Parametr oqlString zawiera ci\u0105g OQL, parametr flags okre\u015bla zachowanie dost\u0119pu.<\/p>\n<p><em>Spos\u00f3b dzia\u0142ania getObjectIterator()<\/em><\/p>\n<p>Najpierw nale\u017cy wygenerowa\u0107 iterator (CisObjectIterator) poprzez wywo\u0142anie metody getObjectIterator() na managerze obiekt\u00f3w i przekazanie ci\u0105gu OQL oraz flag dost\u0119pu. Ci\u0105g OQL zezwala na Sub Selects w klauzuli WHERE. Joins nie s\u0105 obs\u0142ugiwane. Metoda zwraca iterator, kt\u00f3ry jest u\u017cywany w aplikacji do \u0142adowania instancji obiekt\u00f3w biznesowych. Nast\u0119pnie ustawiane s\u0105 parametry OQL podane w ci\u0105gu OQL jako symbol zast\u0119pczy &#8222;?&#8221;. Pierwsze wywo\u0142anie <em>hasNext()<\/em> lub <em>next()<\/em> na iteratorze wyzwala dost\u0119p do bazy danych. Metoda <em>hasNext()<\/em> sprawdza, czy mo\u017cna jeszcze przesy\u0142a\u0107\u00a0 instancje. Metoda <em>next() <\/em>dostarcza nast\u0119pn\u0105 instancj\u0119 do aplikacji. Je\u015bli obiekt biznesowy jest przechowywany w pami\u0119ci podr\u0119cznej, w\u00f3wczas jako pierwsze \u0142adowane s\u0105 warto\u015bci klucza podstawowego:<\/p>\n<pre>SELECT primkeyAttr FROM table [WHERE ...]<\/pre>\n<p>Instancje obiekt\u00f3w biznesowych s\u0105 generowane przy u\u017cyciu wewn\u0119trznie wywo\u0142ywanej metody getObjectArray(), kt\u00f3ra \u0142aduje instancje blok po bloku za pomoc\u0105 klucza podstawowego. Domy\u015blny rozmiar bloku to 16. Je\u015bli instancja obiektu biznesowego jest oznaczona jako usuni\u0119ta w aktualnej Transaction Cache, to zostanie odfiltrowana i nie zwr\u00f3cona jako wynik. Iterator obiekt\u00f3w nigdy nie zwraca zera. W aplikacji musi nast\u0105pi\u0107 Type Cast z og\u00f3lnej klasy CisObject na konkretn\u0105 klas\u0119 odczytywanych obiekt\u00f3w biznesowych.<\/p>\n<p>Je\u015bli obiekt biznesowy nie jest przechowywany w pami\u0119ci podr\u0119cznej, wszystkie atrybuty s\u0105 odczytywane bezpo\u015brednio z bazy danych i generowane s\u0105 instancje obiektu biznesowego.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><\/p>\n<p>Poni\u017cszy fragment kodu \u017ar\u00f3d\u0142owego wczytuje instancje obiektu biznesowego Item, do kt\u00f3rych przypisana jest okre\u015blona jednostka miary (Business Object UnitOfMeasure). Ich klucz podstawowy typu &#8222;guid&#8221; jest ustawiany jako parametry w iteratorze za pomoc\u0105 metody setGuid().<\/p>\n<p>Parametry OQL:<\/p>\n<pre>try (CisObjectIterator&lt;Item&gt; iter = om.getObjectIterator( \"SELECT FROM\ncom.cisag.app.general.obj.Item i WHERE\ni:uom=?\")) {\niter.setGuid(1, uomGuid);\nwhile (iter.hasNext()) {\nItem item = iter.next();\n...\n}\n}<\/pre>\n<p>Poni\u017cszy fragment kodu \u017ar\u00f3d\u0142owego wczytuje instancje obiektu biznesowego SupplierProposalDetail &#8230;<\/p>\n<p>Sub Select:<\/p>\n<pre>String oql = \"SELECT FROM\ncom.cisag.app.purchasing.obj.SupplierProposalDetail spd WHERE spd:deliverySupplier &lt;&gt;\n(SELECT delInfo:supplierData.supplier FROM\ncom.cisag.app.purchasing.obj.PurchaseOrderDeliveryInfo delInfo WHERE delInfo:header=spd:header AND delInfo:detail=spd:guid)\";\ntry (CisObjectIterator &lt;SupplierProposalDetail&gt; iter = om.getObjectIterator(oql)){\nwhile (iter.hasNext()) {\nSupplierProposalDetail spd = iter.next();\n...\n}\n}<\/pre>\n<p><\/div><\/section>\n<section class=\"document-alert-box indicator\"><div class=\"document-alert-title\">Wskaz\u00f3wka<\/div><div class=\"document-alert-content\">Wynik wyra\u017cenia OQL jest obliczany bezpo\u015brednio na danych w bazie danych. Obiekty zmienione w tym samym kontek\u015bcie transakcji nie s\u0105 uwzgl\u0119dniane, poniewa\u017c zmiany te nie s\u0105 jeszcze zarejestrowane w bazie danych. Stan\u0105 si\u0119 trwa\u0142e dopiero po zako\u0144czeniu transakcji Top Level. Oznacza to, \u017ce iterator obiekt\u00f3w mo\u017ce dostarczy\u0107 nieprawid\u0142owe dane, je\u015bli jego instrukcja OQL oddzia\u0142uje na zmienione obiekty. Nowo utworzone obiekty nie s\u0105 uwzgl\u0119dniane, a usuni\u0119te obiekty mog\u0105 zosta\u0107 odfiltrowane za pomoc\u0105 klucza podstawowego.<\/div><\/section>\n<h4 id=\"metoda-getresultset\" ><span class=\"ez-toc-section\" id=\"Metoda_getResultSet-2\"><\/span>Metoda\u00a0getResultSet()<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Metoda getResultSet() odczytuje wybrane atrybuty z jednego lub wielu obiekt\u00f3w biznesowych. Atrybuty wynik\u00f3w mo\u017cna dowolnie \u0142\u0105czy\u0107 za pomoc\u0105 instrukcji SELECT w OQL. Z bazy danych nie s\u0105 odczytywane kompletne instancje obiekt\u00f3w biznesowych. Zestaw wynik\u00f3w (Result Set) wykorzystuje ca\u0142kowicie po\u0142\u0105czenie z baz\u0105 danych do momentu jego jawnego zamkni\u0119cia. Dlatego niezwykle wa\u017cne jest, aby zminimalizowa\u0107 czas otwarcia zestawu wynik\u00f3w, poniewa\u017c liczba dost\u0119pnych po\u0142\u0105cze\u0144 z baz\u0105 danych jest ograniczona. Z\u0142o\u017cone lub d\u0142ugie operacje powinno si\u0119 wykonywa\u0107 dopiero po zamkni\u0119ciu zbioru wynik\u00f3w. Wa\u017cne jest r\u00f3wnie\u017c, aby ka\u017cdy z zagnie\u017cd\u017conych zestaw\u00f3w wynik\u00f3w u\u017cywa\u0142 w\u0142asnego po\u0142\u0105czenia z baz\u0105 danych, czyli liczba dost\u0119pnych po\u0142\u0105cze\u0144 z baz\u0105 danych ogranicza g\u0142\u0119boko\u015b\u0107 zagnie\u017cd\u017cenia. Dlatego zaleca si\u0119 utrzymywa\u0107 jak najmniejsz\u0105 g\u0142\u0119boko\u015b\u0107 zagnie\u017cd\u017cenia.<\/p>\n<p><em>Spos\u00f3b dzia\u0142ania getResultSet()<\/em><\/p>\n<p>Najpierw nale\u017cy wygenerowa\u0107 zestaw wynik\u00f3w (CisResultSet) poprzez wywo\u0142anie metody <em>getResultSet()<\/em> w managerze obiekt\u00f3w i przekazanie ci\u0105gu OQL, w kt\u00f3rym dozwolone s\u0105 Joins i Sub Selects. Metoda zwraca zestaw wynik\u00f3w, kt\u00f3ry<br \/>\njest u\u017cywany w aplikacji do \u0142adowania atrybut\u00f3w. Nast\u0119pnie ustawiane s\u0105 parametry OQL, kt\u00f3re w ci\u0105gu OQL zosta\u0142y wprowadzone jako symbol zast\u0119pczy &#8222;?&#8221;. Pierwsze wywo\u0142anie metody <em>next()<\/em> na zestawie wynik\u00f3w uruchamia dost\u0119p do bazy danych. Metoda <em>next()<\/em> zwraca nast\u0119pny zestaw atrybut\u00f3w do aplikacji. Wykonywane jest nast\u0119puj\u0105ce zapytanie SQL:<\/p>\n<pre>SELECT attr1[, attr2, ...] FROM table1 [JOIN\ntable2 ON ... [JOIN ...]] [WHERE ...]<\/pre>\n<p>Aplikacja musi odebra\u0107 atrybuty odczytanego rekordu z zestawu wynik\u00f3w przy u\u017cyciu w\u0142a\u015bciwej metody (w zale\u017cno\u015bci od typu). Nale\u017cy upewni\u0107 si\u0119, \u017ce zestaw wynik\u00f3w jest zamykany jawnie za pomoc\u0105 <em>close()<\/em>, aby m\u00f3c zwolni\u0107 po\u0142\u0105czenie bazy danych, je\u015bli transakcja dummy jest u\u017cywana do odczytu. W przypadku wywo\u0142ania <em>commit()<\/em> lub <em>rollback()<\/em> dla bie\u017c\u0105cej transakcji, wszystkie otwarte zestawy wynik\u00f3w s\u0105 zamykane niejawnie. Poniewa\u017c zestaw wynik\u00f3w jest &#8222;AutoClosable&#8221;, to zestaw przypisany w<em> try<\/em> jest zamykany automatycznie, nawet bez &#8222;finally, po opuszczeniu bloku <em>try<\/em>.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><\/p>\n<p>Poni\u017cszy fragment kodu \u017ar\u00f3d\u0142owego \u0142aduje tylko atrybuty &#8222;guid&#8221; (klucz podstawowy) i &#8222;number&#8221; (klucz funkcjonalny) instancji obiektu biznesowego, do kt\u00f3rych przypisana jest okre\u015blona jednostka miary (obiekt biznesowy UnitOfMeasure).<br \/>\nIch klucz podstawowy typu &#8222;guid&#8221; jest ustawiany jako parametr w zestawie wynik\u00f3w za pomoc\u0105 metody setGuid()<br \/>\n(pasuj\u0105c\u0105 do typu), do kt\u00f3rej jako parametry przeniesiona jest pozycja w instrukcji OQL i warto\u015b\u0107. Blok try catch finally gwarantuje, \u017ce zestaw wynik\u00f3w zostanie zamkni\u0119ty, nawet je\u015bli wyst\u0105pi wyj\u0105tek.<\/p>\n<pre>byte[] uomGuid = ... ;\nCisResultSet rs = om.getResultSet(\"SELECT\ni:guid, i:number\nFROM com.cisag.app.general.obj.Item i\nWHERE i:uom=?\");\ntry {\nrs.setGuid(1, uomGuid);\nwhile (rs.next()) {\n\/\/read next\nbyte[] guid = rs.getGuid(1);\nString number = rs.getString(2);\n...\n}\n}\nfinally {\nrs.close();\n}<\/pre>\n<p><\/div><\/section>\n<h4 id=\"wytyczne-dotyczace-uzytkowania\" ><span class=\"ez-toc-section\" id=\"Wytyczne_dotyczace_uzytkowania\"><\/span>Wytyczne dotycz\u0105ce u\u017cytkowania<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Poni\u017csze zestawienie zawiera wskaz\u00f3wki dotycz\u0105ce stosowania opisanych metod w celu osi\u0105gni\u0119cia w\u0142a\u015bciwej wydajno\u015bci.<\/p>\n<ul>\n<li>Metoda <em>getObjectArray() (ArrayFetch)<\/em> nie jest nigdy wykonywana wolniej ni\u017c n razy metoda <em>getObject()<\/em>,<br \/>\nale cz\u0119sto szybciej. Wymaga najwy\u017cej jednego zapytania do bazy danych w przeciwie\u0144stwie do maksymalnie n zapyta\u0144 do bazy bazy. Kolejn\u0105 zalet\u0105 jest to, \u017ce mapping atrybut\u00f3w mi\u0119dzy OQL, SQL i Java musi by\u0107 ustalone tylko jeden raz.<\/li>\n<li>Je\u015bli dla wczytywanego obiektu biznesowego jest aktywowany caching, metody <em>getObject(), getObjectArray() <\/em>i<br \/>\n<em>getObjectIterator()<\/em> zawsze najpierw odczytuj\u0105 Shared Cache.<br \/>\nDodaj\u0105 one r\u00f3wnie\u017c instancje za\u0142adowane z bazy danych do pami\u0119ci podr\u0119cznej. W przypadku cz\u0119sto u\u017cywanych obiekt\u00f3w biznesowych (np. dane podstawowe) metody te s\u0105 przydatne, poniewa\u017c podczas dost\u0119pu zawsze uwzgl\u0119dniaj\u0105 pami\u0119\u0107 podr\u0119czn\u0105. Natomiast bez u\u017cycia odpowiednich flag dost\u0119pu nie s\u0105 one odpowiednie dla<br \/>\nmasowych operacji na danych transakcyjnych (np. zapytanie o dost\u0119pno\u015b\u0107 artyku\u0142\u00f3w), poniewa\u017c mog\u0105 one wypiera\u0107 z pami\u0119ci Shared Cache inne cz\u0119sto u\u017cywane dane, mimo \u017ce dodane dane prawie nigdy nie zostan\u0105 u\u017cyte. Dlatego takie dane powinny by\u0107 zaczytane z flag\u0105 dost\u0119pu IGNORE_SHARED_CACHE. Tworzenie wielu obiekt\u00f3w Java, kt\u00f3re s\u0105 potrzebne tylko tymczasowo, jest r\u00f3wnie\u017c bardzo czasoch\u0142onne i zajmuje du\u017co miejsca w pami\u0119ci g\u0142\u00f3wnej.<\/li>\n<\/ul>\n<p>Za pomoc\u0105 metody <em>getResultSet()<\/em> mo\u017cna jest wczytywa\u0107 tylko te atrybuty, kt\u00f3re s\u0105 potrzebne, a nie ca\u0142\u0105 instancj\u0119 obiektu biznesowego z dziesi\u0105tkami atrybut\u00f3w. Pozwala to utrzyma\u0107 ilo\u015b\u0107 danych na odpowiednio niskim poziomie, r\u00f3wnie\u017c dlatego, \u017ce w Javie tworzonych jest mniej obiekt\u00f3w. W przypadku getResultSet() na programi\u015bcie spoczywa znacznie wi\u0119ksza odpowiedzialno\u015b\u0107, poniewa\u017c otwarty zestaw ResultSet wy\u0142\u0105cznie zajmuje po\u0142\u0105czenie z baz\u0105 danych. Ponadto programista sam odpowiada za mapowanie wynik\u00f3w z zestawu na atrybuty Java.<\/p>\n<h4 id=\"wczytywanie-za-pomoca-relacji\" ><span class=\"ez-toc-section\" id=\"Wczytywanie_za_pomoca_relacji\"><\/span>Wczytywanie za pomoc\u0105 relacji<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Je\u015bli dla obiektu biznesowego s\u0105 zdefiniowane relacje, powi\u0105zane instancje mog\u0105 by\u0107 mog\u0105 by\u0107 wczytywane za pomoc\u0105 metod relacji <em>retrieve&#8230;()<\/em>. Dost\u0119p do odczytu poprzez managera obiekt\u00f3w (getObject() lub getObjectIterator()) odbywa si\u0119 w spos\u00f3b przejrzysty dla deweloper\u00f3w. Wynikiem relacji &#8222;1 do 1&#8221; jest <em>null<\/em>, je\u015bli jeden z atrybut\u00f3w relacji ma warto\u015b\u0107 <em>null<\/em>. Wynik relacji &#8222;1 do n&#8221; nie jest sortowany. Wewn\u0119trznie stosowana jest instrukcja OQL (patrz <em>Metoda getObjectIterator()<\/em>).<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><\/p>\n<p>\u0141adowanie za pomoc\u0105 relacji \u201e do 1\u201c:<br \/>\nPoni\u017cszy fragment kodu \u017ar\u00f3d\u0142owego pokazuje \u0142adowanie powi\u0105zanej instancji obiektu biznesowego <em>Country<\/em> za pomoc\u0105 metody relacyjnej <em>retrieveCountry()<\/em> obiektu biznesowego <em>Region<\/em>.<\/p>\n<pre>Region region = (Region)om.getObject(primKey);\nCountry country = region.retrieveCountry();<\/pre>\n<p>\u0141adowanie za pomoc\u0105 relacji \u201e1 do n\u201c:<br \/>\nPoni\u017cszy fragment kodu \u017ar\u00f3d\u0142owego pokazuje \u0142adowanie powi\u0105zanych instancji obiektu biznesowego <i>Region <\/i>za pomoc\u0105 metody relacyjnej <em>retrieveRegions()<\/em>\u00a0obiektu biznesowego <em>Country <\/em>bez przyporz\u0105dkowania w <em>Try<\/em>.<\/p>\n<pre>CisObjectIterator&lt;Region&gt; iter = country.retrieveRegions();\ntry {\nwhile (iter.hasNext()) {\nRegion region = iter.next();\n}\n} finally {\niter.close();\n}<\/pre>\n<p>Ten sam przyk\u0142ad z przyporz\u0105dkowaniem w <em>Try:<\/em><\/p>\n<pre>try (CisObjectIterator&lt;Region&gt; iter = country.retrieveRegi-ons()) {\nwhile (iter.hasNext()) {\nRegion region = iter.next();\n}\n}<\/pre>\n<p><\/div><\/section>\n<h3 id=\"dostepy-zapisu-przez-managera-obiektow\" ><span class=\"ez-toc-section\" id=\"Dostepy_zapisu_przez_managera_obiektow\"><\/span>Dost\u0119py zapisu przez managera obiekt\u00f3w<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Do zmiany lub usuni\u0119cia instancji obiektu biznesowego s\u0142u\u017c\u0105 metody mened\u017cera obiekt\u00f3w <em>putObject() <\/em>i<em> deleteObject()<\/em>.<\/p>\n<h4 id=\"metody-putobject\" ><span class=\"ez-toc-section\" id=\"Metody_putObject\"><\/span>Metody putObject()<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Metoda <em>putObject()<\/em> rejestruje do zapisu w bazie danych instancj\u0119 obiektu biznesowego. Zostaje ona zapisana w pami\u0119ci podr\u0119cznej transakcji bie\u017c\u0105cej i staje si\u0119 trwa\u0142a dopiero po wykonaniu <em>commit()<\/em> dla transakcji.<\/p>\n<p>Aby utworzy\u0107 lub zmieni\u0107 instancj\u0119 obiektu biznesowego, nale\u017cy najpierw otworzy\u0107 transakcj\u0119 Top Level. Nast\u0119pnie<br \/>\ninstancja jest wczytywana za pomoc\u0105 <em>getObject() z okre\u015bleniem <\/em>\u017c\u0105danego trybu dost\u0119pu. Tryb dost\u0119pu READ_UPDATE dostarcza instancje, kt\u00f3re mo\u017cna dowolnie zmieni\u0107 lub usun\u0105\u0107. Tryb dost\u0119pu READ_WRITE dzia\u0142a w taki sam spos\u00f3b. Je\u015bli jednak nie istnieje instancja \u017c\u0105danego obiektu, jest on tworzony na nowo. W takim przypadku READ_UPDATE zwraca warto\u015b\u0107 <em>null<\/em>. Odczytana instancja obiektu biznesowego jest zablokowana dla innych transakcji przez us\u0142ug\u0119 trwa\u0142o\u015bci danych. Je\u015bli inna transakcja chce odczyta\u0107 t\u0119 sam\u0105 instancj\u0119 obiektu biznesowego, po okre\u015blonym czasie mo\u017ce wyst\u0105pi\u0107 przekroczenie limitu czasu. Zmiany atrybut\u00f3w s\u0105 dokonywane za pomoc\u0105 metod <em>set&#8230;()<\/em> danego obiektu biznesowego. Wywo\u0142anie metody <em>putObject()<\/em> z instancj\u0105 obiektu biznesowego jako parametrem przenosi zmiany do bie\u017c\u0105cej pami\u0119ci Transaction Cache. Ponowne<em> getObject()<\/em> w tej transakcji zwraca tym razem zmienion\u0105 instancj\u0119 obiektu biznesowego. Przy <em>commit()<\/em> transakcji brane s\u0105 pod uwag\u0119 tylko zmiany zarejestrowane za pomoc\u0105 <em>putObject()<\/em>. Zarejestrowane zmiany stan\u0105 si\u0119 trwa\u0142e w bazie danych dopiero po wykonaniu <em>commit()<\/em> transakcji Top Level. W przypadku wyst\u0105pienia b\u0142\u0119du przed lub podczas wykonywania <em>commit()<\/em> dla bie\u017c\u0105cej transakcji, nale\u017cy wywo\u0142a\u0107 jawny <em>rollback()<\/em>, je\u015bli transakcja zosta\u0142a otwarta za pomoc\u0105 <em>beginNew()<\/em>, a nie za pomoc\u0105 <em>createNew()<\/em>.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><\/p>\n<p>Poni\u017cszy fragment kodu \u017ar\u00f3d\u0142owego \u0142aduje instancj\u0119 obiektu biznesowego\u00a0UnitOfMeasure z bazy danych lub<br \/>\ntworzy now\u0105 instancj\u0119 za pomoc\u0105 <em>beginNew()<\/em>.<\/p>\n<pre>tm.beginNew();\ntry {\nbyte[] key = UnitOfMeasure.buildByCodeKey(code);\n\/\/ Laden der Instanz zum \u00c4ndern\/Anlegen\nUnitOfMeasure unitOfMeasure = (UnitOfMeasure)\nom.getObject(key, CisObjectManager.READ_WRITE);\n\/\/ Setzen der Attribute\nunitOfMeasure.setDescription(description);\n...\n\/\/ Registrieren der \u00c4nderungen im Transaction-Cache\nom.putObject(unitOfMeasure);\n\/\/ Beenden der Transaktion, Schreiben der\n\u00c4nderungen\ntm.commit();\n} catch (RuntimeException e) {\n\/\/ explizites Rollback bei Fehler\ntm.rollback();\nthrow e;\n}<\/pre>\n<p>Poni\u017cszy fragment kodu \u017ar\u00f3d\u0142owego \u0142aduje instancj\u0119 obiektu biznesowego\u00a0UnitOfMeasure z bazy danych lub<br \/>\ntworzy now\u0105 instancj\u0119 za pomoc\u0105 <em>createNew()<\/em>.<\/p>\n<pre>try (CisTransaction txn =tm.createNew()) {\nbyte[] key = UnitOfMeasure.buildByCodeKey(code);\n\/\/Laden der Instanz zum \u00c4ndern\/Anlegen\nUnitOfMeasure unitOfMeasure = (UnitOfMeasure) om.getObject(key, CisObjectManager.READ_WRITE);\n\/\/Setzen der Attribute unitOfMeasure.setDescription(description); ...\n\/\/Registrieren der \u00c4nderungen im Transaction-Cache\nom.putObject(unitOfMeasure);\n\/\/Beenden der Transaktion, Schreiben der\n\u00c4nderungen\ntxn.commit();\n}<\/pre>\n<p><\/div><\/section>\n<h4 id=\"metoda-deleteobject\" ><span class=\"ez-toc-section\" id=\"Metoda_deleteObject-2\"><\/span>Metoda deleteObject()<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Metoda <em>deleteObject()<\/em> usuwa instancj\u0119 obiektu biznesowego z bazy danych.<\/p>\n<p>Aby usun\u0105\u0107 instancj\u0119, najpierw nale\u017cy otworzy\u0107 transakcj\u0119 Top Level. Obiekt biznesowy, kt\u00f3ry ma zosta\u0107 zmieniony, jest nast\u0119pnie pobierany za pomoc\u0105 <em>getObject() <\/em>\u00a0w trybie dost\u0119pu READ_UPDATE.\u00a0Wywo\u0142anie <em>deleteObject()<\/em> z instancj\u0105 obiektu biznesowego jako parametrem powoduje zaznaczenie instancji do usuni\u0119cia w aktualnej pami\u0119ci Transaktion Cache. Operacja na bazie danych nie jest wykonywana a\u017c do commit() transakcji najwy\u017cszego poziomu.<br \/>\nJe\u015bli wyst\u0105pi b\u0142\u0105d przed lub w trakcie commit() bie\u017c\u0105cej transakcji<br \/>\nnale\u017cy wywo\u0142a\u0107 jawn\u0105 funkcj\u0119 rollback(), je\u015bli transakcja zosta\u0142a otwarta za pomoc\u0105 funkcji beginNew(), a nie createNew(). Operacja na bazie danych zostanie wykonana dopiero przy <em>commit()<\/em> transakcji Top Level. W przypadku wyst\u0105pienia b\u0142\u0119du przed lub podczas wykonywania <em>commit()<\/em> dla bie\u017c\u0105cej transakcji, nale\u017cy wywo\u0142a\u0107 jawny <em>rollback()<\/em>, je\u015bli transakcja zosta\u0142a otwarta za pomoc\u0105 <em>beginNew()<\/em>, a nie za pomoc\u0105 <em>createNew()<\/em>.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><\/p>\n<p>Poni\u017cszy fragment kodu \u017ar\u00f3d\u0142owego pobiera instancj\u0119 obiektu biznesowego UnitOfMeasure z bazy danych.\u00a0Je\u015bli<br \/>\ninstancja nie zostanie znaleziona, zwracana jest warto\u015b\u0107 null. Znaleziona instancja b\u0119dzie oznaczona do usuni\u0119cia. Wykonanie <em>commit()<\/em> powoduje usuni\u0119cie instancji.<\/p>\n<pre>byte[] transGuid= tm.beginNew();\ntry {\nbyte[] key = UnitOfMeasure.buildByCodeKey(code);\n\/\/Laden der Instanz zum \u00c4ndern\/Anlegen\nUnitOfMeasure unitOfMeasure = (UnitOfMeasure) om.getObject(key,\nCisObjectManager.READ_UPDATE);\nif (unitOfMeasure==null) {\n\/\/nicht gefunden\n...\n} else {\n\/\/ Markieren zum L\u00f6schen\nom.deleteObject(unitOfMeasure);\n}\n\/\/ Beenden der Transaktion, Schreiben der\n\u00c4nderungen\ntm.commit(transGuid);\n} catch (RuntimeException e) {\n\/\/ explizites Rollback bei Fehler\ntm.rollback(transGuid);\nthrow e;\n}<\/pre>\n<p>Ten sam przyk\u0142ad z u\u017cyciem funkcji <em>createNew():<\/em><\/p>\n<pre>try (CisTransaction txn =tm.createNew()) {\nbyte[] key = UnitOfMeasure.buildByCodeKey(code);\n\/\/Laden der Instanz zum \u00c4ndern\/Anlegen UnitOfMeasure\nunitOfMeasure = (UnitOfMeasure) om.getObject(key, CisObjectMan-ager.READ_UPDATE);\nif (unitOfMeasure==null) {\n\/\/nicht gefunden ...\n} else {\n\/\/Markieren zum L\u00f6schen\nom.deleteObject(unitOfMeasure);\n} \/\/Beenden der Transaktion, Schreiben der\n\u00c4nderungen\ntxn.commit(transGuid);\n}<\/pre>\n<p><\/div><\/section>\n<h3 id=\"obsluga-bledow-transakcji\" ><span class=\"ez-toc-section\" id=\"Obsluga_bledow_transakcji\"><\/span>Obs\u0142uga b\u0142\u0119d\u00f3w transakcji<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Nale\u017cy pami\u0119ta\u0107, \u017ce transakcja otwarta za pomoc\u0105 <em>begin()<\/em> lub <em>beginNew()<\/em> anulowana jest zawsze za pomoc\u0105 <em>rollback() <\/em>lub zamykana za pomoc\u0105 <em>commit()<\/em>. Dlatego konieczna jest obs\u0142uga wyj\u0105tk\u00f3w wyst\u0119puj\u0105cych w ramach bloku transakcji. Ponadto w okre\u015blonych miejscach programu nale\u017cy unika\u0107 ewentualnego wyst\u0105pienia wyj\u0105tk\u00f3w. W przypadku zagnie\u017cd\u017conych transakcji nale\u017cy zadba\u0107 o to, aby nie doprowadzi\u0107 do wymieszania stosu transakcji, np. je\u015bli przez pomy\u0142k\u0119 zamkni\u0119ta zostanie r\u00f3wnie\u017c transakcja nadrz\u0119dna. Aby zminimalizowa\u0107 ryzyko, \u017ce Rollback lub Commit zostanie wykonany dla niew\u0142a\u015bciwej transakcji, mo\u017cna wykorzysta\u0107 identyfikator transakcji Guid. <em>beginNew()\/begin()<\/em> zwraca jako warto\u015b\u0107 identyfikator GUID bie\u017c\u0105cej transakcji, kt\u00f3ry mo\u017ce zosta\u0107 przekazany jako parametr dla<em> rollback()<\/em> i <em>commit()<\/em>. Je\u015bli podczas wykonywania <em>commit()<\/em> identyfikator nie odpowiada identyfikatorowi bie\u017c\u0105cej transakcji, w\u00f3wczas wyst\u0119puje wyj\u0105tek, a nieprawid\u0142owa transakcja nie zostanie utrwalona. W przypadku funkcji <em>rollback()<\/em> pojawia si\u0119 tylko ostrze\u017cenie, \u017ce identyfikatory transakcji nie s\u0105 zgodne. Ka\u017cda transakcja Top Level ma sw\u00f3j w\u0142asny identyfikator transakcji, podczas gdy transakcje Sub Level zawieraj\u0105 identyfikator transakcji Top Level. Obecnie zastosowanie identyfikatora transakcji chroni przed niezamierzonym zamkni\u0119ciem niew\u0142a\u015bciwej transakcji Top Level, ale takie b\u0142\u0119dy s\u0105 nadal mo\u017cliwe w przypadku transakcji podrz\u0119dnych. W kolejnym wydaniu wersji ten mechanizm ochrony mo\u017ce zosta\u0107 rozszerzony r\u00f3wnie\u017c na transakcje podrz\u0119dne, tak aby ka\u017cda z tych transakcji posiada\u0142a sw\u00f3j w\u0142asny identyfikator transakcji. Dlatego r\u00f3wnie\u017c w przypadku transakcji podrz\u0119dnych powinny by\u0107 stosowane identyfikatory Guid. Transakcje tworzone za pomoc\u0105 <em>create()<\/em> lub <em>createNew()<\/em> w &#8222;try&#8221; jako &#8222;AutoClosable&#8221; s\u0105 automatycznie zamykane po opuszczeniu bloku <em>try. <\/em>Je\u015bli transakcja jest u\u017cywana jako &#8222;AutoClosable&#8221;, w\u00f3wczas nie ma mo\u017cliwo\u015bci nieprawid\u0142owego u\u017cycia, poniewa\u017c Java zapewnia prawid\u0142owe zamkni\u0119cie transakcji.<\/p>\n<h4 id=\"transakcja-odczytu-przez-begin\" ><span class=\"ez-toc-section\" id=\"Transakcja_odczytu_przez_begin\"><\/span>Transakcja odczytu przez <em>begin<\/em><span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Transakcja odczytu, kt\u00f3ra zosta\u0142a otwarta za pomoc\u0105 <em>begin()<\/em> lub <em>beginNew() <\/em>musi zawsze odpowiada\u0107 przedstawionemu poni\u017cej szablonowi. W punktach oznaczonych \/*xx*\/ nie mo\u017ce zosta\u0107 wywo\u0142any \u017caden wyj\u0105tek. Oznacza to, \u017ce te miejsca powinny zawiera\u0107 kodu, ale tylko instrukcje, kt\u00f3re nie mog\u0105 wywo\u0142a\u0107 wyj\u0105tku. Transakcja tylko do odczytu powinna by\u0107 zawsze wycofana za pomoc\u0105 <em>rollback()<\/em>, poniewa\u017c \u017cadne zmiany nie s\u0105 wprowadzane na bazie danych. Blok <em>try finally <\/em>gwarantuje, \u017ce zawsze wykonywany jest <em>rollback()<\/em>, niezale\u017cnie od tego,\u00a0czy wyj\u0105tek wyst\u0105pi w bloku transakcji, czy nie.<\/p>\n<p>Szablon dla transakcji odczytu:<\/p>\n<pre>byte[] transGuid= tm.begin...(..);\n\/*xx*\/\ntry {\n...\n} finally {\n\/*xx*\/\ntm.rollback(transGuid);\n...\n}<\/pre>\n<p>Wyj\u0105tek w oznaczonych miejscach m\u00f3g\u0142by skutkowa\u0107 tym, \u017ce transakcja nie zostanie wycofana przez <em>rollback().\u00a0<\/em><br \/>\nTransakcja pozosta\u0142aby zatem otwarta i zosta\u0142aby zamkni\u0119ta dopiero przy wykonaniu nast\u0119pnych funkcji <em>commit()<\/em> lub <em>rollback()<\/em> przeznaczonych dla innej transakcji. Stos transakcji nie by\u0142by ju\u017c sp\u00f3jny, co prowadzi\u0142oby do utraty danych.<\/p>\n<h4 id=\"transakcja-odczytu-przez-create\" ><span class=\"ez-toc-section\" id=\"Transakcja_odczytu_przez_create\"><\/span>Transakcja odczytu przez <em>create<\/em><span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Transakcja odczytu otwarta za pomoc\u0105 <em>create<\/em> lub <em>createNew<\/em> musi zawsze odpowiada\u0107 przedstawionemu poni\u017cej szablonowi. Zawsze nale\u017cy stosowa\u0107 wygenerowan\u0105 transakcj\u0119 w &#8222;try&#8221; jako &#8222;AutoClosable&#8221;, poniewa\u017c w przeciwnym razie stos transakcji mo\u017ce by\u0107 niesp\u00f3jny.<\/p>\n<p>Szablon dla transakcji odczytu:<\/p>\n<pre>try (CisTransaction txn=tm.create...(..)) {\n...\n}<\/pre>\n<h4 id=\"transakcja-zapisu-przez-begin\" ><span class=\"ez-toc-section\" id=\"Transakcja_zapisu_przez_begin\"><\/span>Transakcja zapisu przez <em>begin<\/em><span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Transakcja zapisu, kt\u00f3ra zosta\u0142a otwarta za pomoc\u0105 <em>begin()<\/em> lub <em>beginNew() <\/em>musi zawsze odpowiada\u0107 przedstawionemu poni\u017cej szablonowi. W punktach oznaczonych \/*xx*\/ nie mo\u017ce zosta\u0107 wywo\u0142any \u017caden wyj\u0105tek. Oznacza to, \u017ce te miejsca powinny zawiera\u0107 kodu, ale tylko instrukcje, kt\u00f3re nie mog\u0105 wywo\u0142a\u0107 wyj\u0105tku. Transakcj\u0119 zapisu mo\u017cna przerwa\u0107 za pomoc\u0105 <em>rollback()<\/em> lub zako\u0144czy\u0107 za pomoc\u0105 commit(). W przypadku przerwania transakcji wszystkie zmiany wprowadzone w transakcji lub w transakcjach podrz\u0119dnych zostan\u0105 odrzucone. Za po\u015brednictwem us\u0142ugi trwa\u0142o\u015bci dozwolone s\u0105 dost\u0119py odczytu i modyfikacji. Blok<em> try catch<\/em> gwarantuje, \u017ce w przypadku wyst\u0105pienia wyj\u0105tku w bloku transakcji transakcja jest jawnie anulowana za pomoc\u0105 funkcji <em>rollback()<\/em>. W innym przypadku transakcja jest zamykana za pomoc\u0105 commit().<\/p>\n<p>Szablon dla transakcji zapisu:<\/p>\n<pre>byte[] transGuid= tm.begin...(..);\n\/*xx1*\/\ntry {\n...\ntm.commit(transGuid);\n\/*xx2*\/\n} catch (RuntimeException ex) {\n\/*xx3*\/\ntm.rollback(transGuid);\n...\n}<\/pre>\n<p>Wyj\u0105tek w miejscu \/*xx1*\/ prowadzi do tego, \u017ce otwarta transakcja nie zostanie zamkni\u0119ta za pomoc\u0105 instrukcji nale\u017c\u0105cej do bloku. Wyj\u0105tek w miejscu \/*xx2*\/ spowodowa\u0142by wykonanie <em>rollback()<\/em> w bloku <em>catchBlock<\/em>, co przerwa\u0142oby transakcj\u0119 nadrz\u0119dn\u0105. Bie\u017c\u0105ca transakcja zosta\u0142a ju\u017c zamkni\u0119ta za pomoc\u0105 <em>commit()<\/em>. Wyj\u0105tek w miejscu \/*xx3*\/ prowadzi do tego, \u017ce funkcja <em>rollback()<\/em> nie zostanie wykonana, a transakcja pozostanie otwarta.<\/p>\n<h4 id=\"transakcja-zapisu-przez-create\" ><span class=\"ez-toc-section\" id=\"Transakcja_zapisu_przez_create\"><\/span>Transakcja zapisu przez <em>create<\/em><span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Transakcja zapisu, kt\u00f3ra zosta\u0142a otwarta za pomoc\u0105 <em>create<\/em> lub <em>createNew\u00a0<\/em>musi zawsze odpowiada\u0107 przedstawionemu poni\u017cej szablonowi. W miejscach oznaczonych \/*xx*\/ nie jest dozwolony dost\u0119p do managera obiekt\u00f3w. Dlatego po <em>commit <\/em>nie powinien pojawia\u0107 si\u0119 \u017caden kod.<\/p>\n<p>Szablon dla transakcji zapisu:<\/p>\n<p>try (CisTransaction txn=tm.create&#8230;(..)) {<br \/>\n&#8230;<br \/>\ntxn.commit();<br \/>\n\/*xx*\/<br \/>\n}<\/p>\n<p>Transakcja otwarta za pomoc\u0105 <em>create<\/em> jest ju\u017c zamkni\u0119ta w miejscu \/*xx*\/. Manager obiekt\u00f3w nie u\u017cywa transakcji otwartej w &#8222;try&#8221; w miejscu \/* xx *\/.<\/p>\n<h4 id=\"transakcja-zapisu-blokowego-przez-create\" ><span class=\"ez-toc-section\" id=\"Transakcja_zapisu_blokowego_przez_create\"><\/span>Transakcja zapisu blokowego przez <em>create<\/em><span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Transakcja powinna mie\u0107 ograniczony rozmiar. Je\u015bli ma zosta\u0107 zapisana nieograniczona ilo\u015b\u0107 danych, to dane te powinny by\u0107 zapisywane w blokach o ograniczonym rozmiarze. Rozmiar bloku mo\u017ce by\u0107 narzucony jako sta\u0142a (np. 100 rekord\u00f3w danych na transakcj\u0119) lub obliczany dynamicznie przez managera transakcji. W miejscach oznaczonych \/*xx*\/ nie jest dozwolony dost\u0119p do managera obiekt\u00f3w. Dlatego po <em>commit<\/em> nie powinno by\u0107 \u017cadnego kodu.<\/p>\n<p>Szablon transakcji ze sta\u0142ymi rozmiarami blok\u00f3w z <em>commitBlock()<\/em>:<\/p>\n<pre>try (CisTransaction txn=tm.create...(..)) {\nint i=0;\nwhile (\u2026) {\n...\nOm.putObject(o);\nif (++i%100=0) {\ntxn.commitBlock();\n}\n}\ntxn.commit();\n\/*xx*\/\n}<\/pre>\n<p>Szablon transakcji z dynamicznymi rozmiarami blok\u00f3w z <em>commitIfSizeLimitExceeded<\/em>:<\/p>\n<pre>try (CisTransaction txn=tm.create...(..)) {\nint i=0;\nwhile (\u2026) {\n\u2026\nOm.putObject(o);\ntxn.commitIfSizeLimitExceeded();\n}\ntxn.commit();\n\/*xx*\/\n}<\/pre>\n<p>Transakcja otwarta za pomoc\u0105 <em>create<\/em> jest ju\u017c zamkni\u0119ta w miejscu \/*xx*\/. Manager obiekt\u00f3w nie u\u017cywa w miejscu<br \/>\n\/*xx *\/ transakcji otwartej w &#8222;try&#8221;.<\/p>\n<h3 id=\"trwale-i-przechodnie-obiekty-biznesowe\" ><span class=\"ez-toc-section\" id=\"Trwale_i_przechodnie_obiekty_biznesowe\"><\/span>Trwa\u0142e i przechodnie obiekty biznesowe<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Instancja obiektu biznesowego przyjmuje dwa ortogonalne stany w odniesieniu do bazy danych i przynale\u017cno\u015bci do transakcji. Zapytanie o te stany mo\u017cna wykona\u0107 za pomoc\u0105 metod <em>is_persistent() <\/em>oraz <em>is_transient()<\/em>.<\/p>\n<p>Metoda is_persistent() s\u0142u\u017cy do okre\u015blania, czy instancja obiektu biznesowego jest zapisana w bazie danych. Je\u015bli metoda zwr\u00f3ci warto\u015b\u0107 <em>true<\/em>, oznacza to, \u017ce instancja istnieje w bazie danych; je\u015bli wynikiem jest <em>false<\/em>, instancja nie istnieje w bazie danych. Metoda <em>is_transient()<\/em> s\u0142u\u017cy do okre\u015blenia, czy instancja obiektu biznesowego ma kontekst transakcji, tzn. czy instancja jest przechowywana w Transaction Cache bie\u017c\u0105cej transakcji. Warto\u015b\u0107 <em>false <\/em>wskazuje na istnienie kontekstu transakcji dla przedmiotowej instancji obiektu biznesowego i jej wa\u017cno\u015bci tylko w bie\u017c\u0105cej transakcji. Je\u015bli metoda zwraca warto\u015b\u0107 <em>true<\/em>, oznacza to, \u017ce instancja nie jest powi\u0105zana z transakcj\u0105. Dla nowo wygenerowanych instancji, kt\u00f3re zosta\u0142y zarejestrowane do zapisu za pomoc\u0105 <em>putObject()<\/em>, ale nie zosta\u0142y jeszcze zapisane w bazie (transakcja Top Level nie jest jeszcze <em>commited<\/em>), metoda <em>is_persistent<\/em> zwraca warto\u015b\u0107 <em>false<\/em>. Za pomoc\u0105 <em>is_newObject() <\/em>mo\u017cna ustali\u0107, czy nowo wygenerowana instancja zosta\u0142a ju\u017c zarejestrowana do zapisu. Ta metoda zwraca warto\u015b\u0107 <em>true<\/em>, je\u015bli obiekt nie jest ani trwa\u0142y, ani nie zosta\u0142 zarejestrowany za pomoc\u0105 putObject().<\/p>\n<p>Nale\u017cy przestrzega\u0107 tych znacznik\u00f3w podczas pracy z obiektami biznesowymi, aby m\u00f3c tworzy\u0107 aplikacje sp\u00f3jne z systemem ERP. Nieprzechodnia instancja obiektu biznesowego, kt\u00f3ra zosta\u0142a wczytana np. za pomoc\u0105 <em>getObject()<\/em>, <em>getObjectArray()<\/em> lub <em>getObjectIterator()<\/em>, jest zawsze powi\u0105zana z bie\u017c\u0105c\u0105 transakcj\u0105 i dlatego traci wa\u017cno\u015b\u0107 po zako\u0144czeniu transakcji. W przypadku transakcji podrz\u0119dnej instancje nieprzechodnie s\u0105 w\u0142\u0105czane do kontekstu transakcji nadrz\u0119dnej i mog\u0105 by\u0107 tam nadal u\u017cywane. Dalsze korzystanie z instancji poza transakcj\u0105 mo\u017ce<br \/>\nmo\u017ce prowadzi\u0107 do b\u0142\u0119d\u00f3w programu i dlatego jest zabronione.<\/p>\n<p>Dla metod <em>putObject()<\/em> i <em>deleteObject()<\/em> przewidziane s\u0105 nieprzechodnie instancje obiekt\u00f3w biznesowych jako jako parametry, za pomoc\u0105 kt\u00f3rych mo\u017cna za\u0142adowa\u0107 lub wygenerowa\u0107 metody <em>getObject(), getObjectIterator()<\/em><br \/>\ni<em> getObjectArray()<\/em> okre\u015blaj\u0105c odpowiednie flagi dost\u0119pu.<\/p>\n<p><em>Metoda getTransientCopy()<\/em><\/p>\n<p>Je\u015bli instancja obiektu biznesowego zosta\u0142a za\u0142adowana poprzez<em> getObject()<\/em> z okre\u015bleniem flagi READ, READ_UPDATE lub READ_WRITE (wczytywana instancja istnieje w bazie danych), w\u00f3wczas <em>is_persistent()<\/em> zwraca <em>true,<\/em> a <em>is_transient()<\/em> zwraca <em>false<\/em>. Aby zastosowa\u0107 instancj\u0119 dla wszystkich transakcji, nale\u017cy wygenerowa\u0107 now\u0105 przechodni\u0105 kopi\u0119 za pomoc\u0105 metody getTransientCopy() klasy obiektu biznesowego. Opr\u00f3cz warto\u015bci atrybut\u00f3w<br \/>\nkopiowana jest r\u00f3wnie\u017c flaga <em>persistent<\/em>, a flaga <em>transient <\/em>jest ustawiana na warto\u015b\u0107 <em>true<\/em>. Utworzona w ten spos\u00f3b przechodnia instancja obiektu biznesowego nie nale\u017cy do \u017cadnej transakcji i mo\u017ce by\u0107 u\u017cywana dla wszystkich transakcji. Ta metoda jest bardzo przydatna, je\u015bli chce si\u0119 zapami\u0119ta\u0107 zawarto\u015b\u0107 instancji obiektu biznesowego po zako\u0144czeniu transakcji, np. do wy\u015bwietlenia GUI.<\/p>\n<p><em>Metoda newTransientInstance()<\/em><\/p>\n<p>Ta metoda klasy obiektu biznesowego generuje pust\u0105 przej\u015bciow\u0105, nietrwa\u0142\u0105 instancj\u0119 obiektu biznesowego (<em>is_persistent()<\/em> zwraca warto\u015b\u0107 <em>false<\/em>, a <em>is_transient()<\/em> zwraca warto\u015b\u0107 <em>true<\/em>).<\/p>\n<p><em>Metoda copyTo()<\/em><\/p>\n<p>Ta metoda klasy obiekt\u00f3w biznesowych mo\u017ce by\u0107 u\u017cywana do kopiowania warto\u015bci atrybut\u00f3w danej instancji do innej instancji tego samego obiektu biznesowego. Obiektem \u017ar\u00f3d\u0142owym lub docelowym mog\u0105 by\u0107 zar\u00f3wno trwa\u0142e jak i przechodnie instancje. W ka\u017cdym przypadku <em>copyTo()<\/em> przenosi warto\u015bci atrybut\u00f3w i klucz biznesowy \u017ar\u00f3d\u0142a do obiektu docelowego. Specjalne post\u0119powanie wymagane jest w nast\u0119puj\u0105cych przypadkach:<\/p>\n<ul>\n<li>Je\u015bli obiekt docelowy jest instancj\u0105 przechodni\u0105, to kopiowane s\u0105 r\u00f3wnie\u017c flaga trwa\u0142o\u015bci i klucz podstawowy \u017ar\u00f3d\u0142a.<\/li>\n<li>Je\u015bli obiekt docelowy nie jest instancj\u0105 trwa\u0142\u0105, to kopiowany jest klucz podstawowy \u017ar\u00f3d\u0142a.<\/li>\n<li>Je\u015bli obiekt docelowy jest przechodni, a dla klasy obiekt\u00f3w biznesowych jest wymagana informacja i aktualizacji, to pe\u0142na informacja o aktualizacji jest r\u00f3wnie\u017c kopiowana ze \u017ar\u00f3d\u0142a. Funkcjonalne oznaczenie usuwania dla \u017ar\u00f3d\u0142a<br \/>\n(flaga <em>delete<\/em>) jest zawsze kopiowana do obiektu docelowego.<\/li>\n<li>Je\u015bli obiekt docelowy jest przechodni i zale\u017cny od czasu, kopiowane s\u0105 r\u00f3wnie\u017c atrybuty <em>validFrom <\/em>i<em> validUntil<\/em> \u017ar\u00f3d\u0142a.<\/li>\n<\/ul>\n<p>Og\u00f3lna zasada brzmi: Do nieprzechodniego, trwa\u0142ego obiektu docelowego nie jest kopiowany \u017caden atrybut ani flaga, kt\u00f3re mog\u0142yby zmieni\u0107 kontekst transakcji obiektu biznesowego. Na przechodni obiekt docelowy kopiowane jest wszystko.<\/p>\n<p>Poni\u017cszy rysunek przedstawia mo\u017cliwe kombinacje flag przechodnich i trwa\u0142ych flag instancji obiektu biznesowego<br \/>\ni okre\u015bla mo\u017cliwe metody wymiany danych mi\u0119dzy instancjami nieprzechodnimi i przechodnimi. Metoda <em>getObject()<\/em> jest tutaj u\u017cywana jako zamiennik dla metod <em>getObjectArray() <\/em>i <em>getObjectIterator()<\/em>, kt\u00f3re wewn\u0119trznie odwo\u0142uj\u0105 si\u0119 do metody <em>getObject()<\/em>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-8054\" src=\"https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2024\/02\/Persistente-und-transiente-Business-Objects.png\" alt=\"\" width=\"492\" height=\"396\" srcset=\"https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/02\/Persistente-und-transiente-Business-Objects.png 492w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/02\/Persistente-und-transiente-Business-Objects-300x241.png 300w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/02\/Persistente-und-transiente-Business-Objects-50x40.png 50w, https:\/\/pomoc.comarch.pl\/cee\/640\/wp-content\/uploads\/2024\/02\/Persistente-und-transiente-Business-Objects-320x258.png 320w\" sizes=\"auto, (max-width: 492px) 100vw, 492px\" \/><\/p>\n<h3 id=\"blokady-logiczne\" ><span class=\"ez-toc-section\" id=\"Blokady_logiczne\"><\/span>Blokady logiczne<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Blokady logiczne s\u0105 u\u017cywane do synchronizacji uruchomionych aplikacji, kt\u00f3re pracuj\u0105 na tych samych instancjach obiekt\u00f3w biznesowych. Nie maj\u0105 one nic wsp\u00f3lnego z blokadami ustawianymi przez transakcje na instancjach obiekt\u00f3w<br \/>\nbiznesowych. Blokady logiczne musz\u0105 by\u0107 zapewnione przez programist\u0119 aplikacji.<\/p>\n<p>Aplikacje dialogowe dzia\u0142aj\u0105 w nast\u0119puj\u0105cy spos\u00f3b:<\/p>\n<ul>\n<li>instancja obiektu biznesowego wybrana przez u\u017cytkownika jest wczytywana poprzez transakcj\u0119 odczytu<\/li>\n<li>u\u017cytkownik zmienia dane<\/li>\n<li>instancja jest zapisywana poprzez transakcj\u0119 zapisu<\/li>\n<\/ul>\n<p>Podczas gdy jeden u\u017cytkownik zmienia dane, drugi u\u017cytkownik mo\u017ce r\u00f3wnie\u017c za\u0142adowa\u0107, edytowa\u0107, a nieco wcze\u015bniej zapisa\u0107 t\u0119 sam\u0105 instancj\u0119 obiektu biznesowego. Pierwszy u\u017cytkownik m\u00f3g\u0142by nadpisa\u0107 zmiany wprowadzone przez drugiego u\u017cytkownika, poniewa\u017c zaczyta\u0142 stare dane. Nale\u017cy oczywi\u015bcie unika\u0107 tego typu sytuacji. Istniej\u0105 dwa sposoby\u00a0 rozwi\u0105zania tego konfliktu: blokowanie optymistyczne i blokowanie pesymistyczne.<\/p>\n<h4 id=\"blokowanie-optymistyczne\" ><span class=\"ez-toc-section\" id=\"Blokowanie_optymistyczne\"><\/span>Blokowanie optymistyczne<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>W wielu przypadkach wystarcza blokada optymistyczna. Instancja obiektu biznesowego, kt\u00f3ra ma zosta\u0107 zmieniona, jest wtedy wczytywana bez ustawiania blokady. Przed zapisaniem system sprawdza, czy instancja obiektu zosta\u0142a zmieniona w bazie danych od momentu ostatniego za\u0142adowania. Je\u015bli nie zosta\u0142a wprowadzona \u017cadna zmiana, w\u00f3wczas instancja obiektu jest zapisywana. W przeciwnym wypadku instancja nie jest zapisywana, a u\u017cytkownik otrzymuje komunikat, \u017ce dane zosta\u0142y w mi\u0119dzyczasie zmienione przez innego u\u017cytkownika i przed edycj\u0105 nale\u017cy aktualizowa\u0107 dane.<\/p>\n<h4 id=\"blokowanie-pesymistyczne\" ><span class=\"ez-toc-section\" id=\"Blokowanie_pesymistyczne\"><\/span>Blokowanie pesymistyczne<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>W przypadku z\u0142o\u017conych wielko\u015bci technicznych, np. zlecenia, zaleca si\u0119 mo\u017cliwie jak najwcze\u015bniejsze zablokowanie, aby unikn\u0105\u0107 wprowadzenia innych zmian, poniewa\u017c nie mo\u017cna oczekiwa\u0107, \u017ce u\u017cytkownik powt\u00f3rzy wpisy. W systemie ERP pesymistyczne blokady s\u0105 realizowane za pomoc\u0105 tak zwanych locks. S\u0105 one ustawiane przez aplikacje i zarz\u0105dzane centralnie za po\u015brednictwem managera aplikacji. Lock jest wyra\u017cony poprzez ci\u0105g znak\u00f3w stosowany przez aplikacj\u0119 jako nazwa dla zasobu. W ten spos\u00f3b aplikacja \u017c\u0105da od managera aplikacji blokady z odpowiednim lock string. Je\u015bli blokada ju\u017c istnieje pod t\u0105 nazwa, blokada nie mo\u017ce zosta\u0107 ustawiona. Je\u015bli natomiast nie ma jeszcze blokady pod t\u0105 nazw\u0105, lock string jest dodawany do listy blokad i blokada zostaje ustawiona. Od tego momentu \u017cadna inna aplikacja z tym samym lock string nie mo\u017ce otrzyma\u0107 blokady od managera aplikacji. Aplikacja musi jawnie zwolni\u0107 ustawion\u0105 blokad\u0119. Wszystkie ustawione locks s\u0105 niejawnie zwalniane po zako\u0144czeniu danej sesji (np. zamkni\u0119cie przegl\u0105darki). Je\u015bli kilka aplikacji u\u017cywa tych samych Lock strings dla zasob\u00f3w, trzeba upewni\u0107 si\u0119, \u017ce odnosz\u0105 si\u0119 one do tego samego zasobu. Dlatego najlepiej stosowa\u0107 zawsze unikalny string, np. dodaj\u0105c warto\u015b\u0107 klucza. Ponadto lock string powinien zawiera\u0107 numer GUID bazy danych, w kt\u00f3rej zmieniana jest instancja obiektu biznesowego, aby zagwarantowa\u0107 unikalno\u015b\u0107, w przypadku gdy ten obiekt biznesowy istnieje w wielu bazach danych.<\/p>\n<p>Aby korzysta\u0107 z centralnego zarz\u0105dzania blokadami w aplikacji, nale\u017cy najpierw wykona\u0107 przez \u015brodowisko sesji zapytanie o managera aplikacji (klasa com.cisag.pgm.appserver.CisApplicationManager):<\/p>\n<pre>CisEnvironment env = CisEnvironment.getInstance();\nCisApplicationManager am = env.getApplicationManager();<\/pre>\n<p>Poni\u017cszy fragment kodu \u017ar\u00f3d\u0142owego pokazuje \u017c\u0105danie blokady z managera aplikacji. Blokada ma zosta\u0107 ustawiona dla instancji obiektu biznesowego <em>PriceList<\/em>. Lock string jest tworzony z nazwy klasy obiektu biznesowego i klucza podstawowego instancji. Je\u015bli blokada jest ju\u017c ustawiona, system nie czeka na zwolnienie.<\/p>\n<pre>\/\/eindeutigen Lock-String erzeugen\nString lockString = PriceList.class.getName() +\nGuid.toHexString(priceListGuid) ;\n\/\/Datenbank-Information der aktiven OLTP-DB hinzuf\u00fcgen\nlockString = tm.buildDatabaseLock(lockString);\n\/\/Sperre anfordern\nboolean locked = am.acquireLock(lockString);\nif (locked) {\n\/\/lock success\n...\n} else {\n\/\/already locked\n\/\/User-Information der schon gehaltenen Sperre\nermitteln\nString user = am.getLockInformation(lockString);\n...\n}<\/pre>\n<p>Zwolnienie blokady odbywa si\u0119 w odpowiednim miejscu aplikacji za pomoc\u0105:<\/p>\n<pre>am.releaseLock(lockString);<\/pre>\n<p><em>Metoda acquireLock()<\/em><\/p>\n<p>Metoda <em>acquireLock()<\/em> w managerze aplikacji mo\u017ce by\u0107 u\u017cyta do ustawienia pesymistycznych blokad. Metoda ta ma kilka sygnatur, kt\u00f3rych mo\u017cna u\u017cy\u0107 do ustawienia jednej lub wi\u0119cej blokad:<\/p>\n<pre>public boolean acquireLock(String value);\npublic boolean acquireLock(String values[]);\npublic boolean acquireLock(String value, long\ntimeout);\npublic boolean acquireLock(String[] values,long\ntimeout);<\/pre>\n<p>Maksymalny czas oczekiwania na zwolnienie istniej\u0105cych ju\u017c blokad mo\u017cna okre\u015bli\u0107 za pomoc\u0105 parametru <em>timeout. <\/em>Warto\u015b\u0107 <em>true<\/em> jest zwracana, je\u015bli uda\u0142o si\u0119 ustawi\u0107 blokad\u0119, w przeciwnym wypadku zwracana jest warto\u015b\u0107 <em>false<\/em>. W przypadku \u017c\u0105dania blokad dla wielu zasob\u00f3w zwracana jest tylko warto\u015b\u0107 <em>true<\/em>, je\u015bli uda\u0142o si\u0119 \u017c\u0105danie wszystkich blokad. Mog\u0142a zosta\u0107 r\u00f3wnie\u017c zablokowana cz\u0119\u015b\u0107 zasob\u00f3w, wtedy musz\u0105 one zosta\u0107 pojedynczo i jawnie ponownie zwolnione.<\/p>\n<p><em>Metoda releaseLock()<\/em><\/p>\n<p>Metoda <em>releaseLock()<\/em> zwalnia ustawion\u0105 blokad\u0119. Okre\u015blony lock string jest usuwany z tabeli blokad managera aplikacji. Metoda ma nast\u0119puj\u0105c\u0105 sygnatur\u0119:<\/p>\n<pre>public void releaseLock(String value);<\/pre>\n<p><em>Metoda getLockInformation()<\/em><\/p>\n<p>Metoda ustala nazw\u0119 u\u017cytkownika dla istniej\u0105cej blokady i niejawnie ponownie zwalnia t\u0119 blokad\u0119. Z tego powodu metoda powinna by\u0107 u\u017cywana tylko po nieudanym \u017c\u0105daniu blokady, aby uzyska\u0107 informacje o tym, kto ustawi\u0142 istniej\u0105c\u0105 blokad\u0119. Metoda ma nast\u0119puj\u0105c\u0105 sygnatur\u0119:<\/p>\n<pre>public String getLockInformation(String value);<\/pre>\n<h2 id=\"dynamiczny-oql\" ><span class=\"ez-toc-section\" id=\"Dynamiczny_OQL\"><\/span>Dynamiczny OQL<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Sk\u0142adnia dost\u0119pnego j\u0119zyka zapyta\u0144 jest podobna do SQL. Zapytania s\u0105 formu\u0142owane na obiektach biznesowych, a nie na tabelach bazy danych. Atrybuty s\u0105 oddzielone od nazwy klasy znakiem&#8221;:&#8221;, tak jak w SQL. Potencja\u0142 wyra\u017ce\u0144 OQL, mo\u017cliwych do sformu\u0142owania, w du\u017cej mierze odpowiada potencja\u0142owi wyra\u017ce\u0144 SQL. I tak na przyk\u0142ad w klauzuli WHERE s\u0105 dozwolone Sub Selects, mo\u017cna formu\u0142owa\u0107 Joins.<\/p>\n<section class=\"document-alert-box indicator\"><div class=\"document-alert-title\">Wskaz\u00f3wka<\/div><div class=\"document-alert-content\">Atrybuty cz\u0119\u015bci musz\u0105 by\u0107 realizowane pojedynczo (select &#8230;<br \/>\nbo:part1.part2 jako x, bo:part1. part2.attr2 jako y &#8230;).<\/div><\/section>\n<p>Szczeg\u00f3\u0142owy opis sk\u0142adni OQL mo\u017cna znale\u017a\u0107 w dokumentacji OQL.<\/p>\n<h5 id=\"joins\" ><span class=\"ez-toc-section\" id=\"Joins\"><\/span><em><strong>Joins<\/strong><\/em><span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>OQL Joins pracuj\u0105 zawsze z dwiema definicjami obiekt\u00f3w biznesowych, kt\u00f3re s\u0105 po\u0142\u0105czone za pomoc\u0105 klauzuli atrybutu. Wynikiem jest wirtualna definicja obiektu biznesowego, kt\u00f3rej atrybuty s\u0105 pobierane od partner\u00f3w join.<br \/>\nTo, kt\u00f3re atrybuty s\u0105 przenoszone do wyniku pod jak\u0105 nazw\u0105, mo\u017cna wybra\u0107 za pomoc\u0105 klauzuli SELECT. Istnieje mo\u017cliwo\u015b\u0107 zagnie\u017cd\u017cania joins. Oznacza to, \u017ce mo\u017cna tworzy\u0107 bardzo z\u0142o\u017cone zapytania, kt\u00f3re<br \/>\nu\u017cywane na przyk\u0142ad dla wyszukiwania OQL lub widok\u00f3w OQL. Istnieje kilka wariant\u00f3w join, ich kr\u00f3tki opis znajduje si\u0119 poni\u017cej. W celu zachowania przejrzysto\u015bci podczas formu\u0142owania joins nale\u017cy stosowa\u0107 d\u0142ug\u0105 form\u0119 pisowni.<\/p>\n<h6 id=\"inner-join\" ><span class=\"ez-toc-section\" id=\"Inner_Join\"><\/span><em>Inner Join<\/em><span class=\"ez-toc-section-end\"><\/span><\/h6>\n<p>Sk\u0142adnia:<\/p>\n<pre>bo1 bo1_alias INNER JOIN bo2 bo2_alias\nON bo1_alias:attr = bo2_alias:attr<\/pre>\n<p>Zbi\u00f3r wynik\u00f3w jest okre\u015blany przez <em>bo1<\/em> i <em>bo2<\/em>. Powi\u0105zanie odbywa si\u0119 jest przy u\u017cyciu tych samych warto\u015bci dla atrybut\u00f3w okre\u015blonych w klauzuli <em>on<\/em>. Instancje <em>bo1<\/em> b\u0119d\u0105 uwzgl\u0119dniane w wyniku zawsze wtedy, gdy odpowiedni partner zosta\u0142 znaleziony <em>bo2.<\/em> Skr\u00f3cona forma pisowni to &#8222;JOIN&#8221;.<\/p>\n<h6 id=\"left-outer-join\" ><span class=\"ez-toc-section\" id=\"Left_Outer_Join\"><\/span><em>Left Outer Join<\/em><span class=\"ez-toc-section-end\"><\/span><\/h6>\n<p>Sk\u0142adnia:<\/p>\n<pre>bo1 bo1_alias LEFT OUTER JOIN bo2 bo2_alias\nON bo1_alias:attr = bo2_alias:attr<\/pre>\n<p>Zbi\u00f3r wynik\u00f3w jest okre\u015blany przez <em>bo1<\/em>. Powi\u0105zanie odbywa si\u0119 przy u\u017cyciu tych samych warto\u015bci dla atrybut\u00f3w okre\u015blonych w klauzuli <em>on<\/em>. Instancje <em>bo1<\/em> b\u0119d\u0105 uwzgl\u0119dniane w wyniku zawsze wtedy, gdy w <em>bo1 <\/em>istnia\u0142 partner<em>.<\/em> Skr\u00f3cona forma pisowni to &#8222;OUTER JOIN&#8221;.<\/p>\n<h6 id=\"right-outer-join\" ><span class=\"ez-toc-section\" id=\"Right_Outer_Join\"><\/span><em>Right Outer Join<\/em><span class=\"ez-toc-section-end\"><\/span><\/h6>\n<p>Sk\u0142adnia:<\/p>\n<pre>bo1 bo1_alias RIGHT OUTER JOIN bo2 bo2_alias\nON bo1_alias:attr = bo2_alias:attr<\/pre>\n<p>Zbi\u00f3r wynik\u00f3w jest okre\u015blany przez <em>bo2<\/em>. Powi\u0105zanie odbywa si\u0119 przy u\u017cyciu tych samych warto\u015bci dla atrybut\u00f3w okre\u015blonych w klauzuli <em>on<\/em>. Instancje <em>bo2<\/em> b\u0119d\u0105 uwzgl\u0119dniane w wyniku zawsze wtedy, gdy w <em>bo2 <\/em>istnia\u0142 partner<em>.<\/em><\/p>\n<h6 id=\"full-outer-join\" ><span class=\"ez-toc-section\" id=\"Full_Outer_Join\"><\/span><em>Full Outer Join<\/em><span class=\"ez-toc-section-end\"><\/span><\/h6>\n<p>Ten typ join nie jest obs\u0142ugiwany przez OQL.<\/p>\n<h2 id=\"schematy-numeracji\" ><span class=\"ez-toc-section\" id=\"Schematy_numeracji\"><\/span>Schematy numeracji<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Schematy numeracji to zakresy numer\u00f3w u\u017cywane podczas przypisywania unikalnych numer\u00f3w dla instancji<br \/>\nobiekt\u00f3w biznesowych, kt\u00f3re s\u0105 identyfikowane przez ten numer. Numer ten zwykle przedstawia klucz funkcjonalny. Numery przypisane za po\u015brednictwem schematu numeracji odpowiadaj\u0105 formatowi okre\u015blonemu w definicji schematu numeracji, a przyrost odbywa si\u0119 w okre\u015blonym odst\u0119pie.<\/p>\n","protected":false},"author":24,"comment_status":"closed","ping_status":"closed","template":"","format":"standard","meta":{"footnotes":""},"class_list":["post-7613","ht_kb","type-ht_kb","status-publish","format-standard","hentry","ht_kb_category-rozwoj-oprogramowania"],"_links":{"self":[{"href":"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/wp-json\/wp\/v2\/ht_kb\/7613","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/wp-json\/wp\/v2\/ht_kb"}],"about":[{"href":"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/wp-json\/wp\/v2\/types\/ht_kb"}],"author":[{"embeddable":true,"href":"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/wp-json\/wp\/v2\/users\/24"}],"replies":[{"embeddable":true,"href":"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/wp-json\/wp\/v2\/comments?post=7613"}],"version-history":[{"count":173,"href":"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/wp-json\/wp\/v2\/ht_kb\/7613\/revisions"}],"predecessor-version":[{"id":27267,"href":"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/wp-json\/wp\/v2\/ht_kb\/7613\/revisions\/27267"}],"wp:attachment":[{"href":"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/wp-json\/wp\/v2\/media?parent=7613"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}