<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Blagi Bolka</title>
	<atom:link href="http://ziobrowski.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://ziobrowski.wordpress.com</link>
	<description></description>
	<lastBuildDate>Thu, 19 May 2011 06:46:24 +0000</lastBuildDate>
	<language>pl</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='ziobrowski.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Blagi Bolka</title>
		<link>http://ziobrowski.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://ziobrowski.wordpress.com/osd.xml" title="Blagi Bolka" />
	<atom:link rel='hub' href='http://ziobrowski.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Testowanie poleceń w Hibernate</title>
		<link>http://ziobrowski.wordpress.com/2010/05/16/testowanie-polecen-w-hibernate/</link>
		<comments>http://ziobrowski.wordpress.com/2010/05/16/testowanie-polecen-w-hibernate/#comments</comments>
		<pubDate>Sun, 16 May 2010 15:46:38 +0000</pubDate>
		<dc:creator>bziobrowski</dc:creator>
				<category><![CDATA[hibernate]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[testowanie]]></category>

		<guid isPermaLink="false">http://ziobrowski.wordpress.com/?p=60</guid>
		<description><![CDATA[I&#8217;m back, big as life and twice as ugly! (gen. Rancor) Reaktywacja. W czasie ostatnich kilku miesięcy  zajmowałem się moją pracą dyplomową, a że temat był trudny oraz bardzo ciekawy to nie miałem czasu na prowadzenie tego dziennika. Dopiero teraz, kiedy doprowadziłem sprawę prawie do końca,  w miarę krótkim czasie postaram się omówić kilka ciekawych [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ziobrowski.wordpress.com&amp;blog=10307678&amp;post=60&amp;subd=ziobrowski&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><em>I&#8217;m back, big as life and twice as ugly!</em> (gen. Rancor)</p>
<p>Reaktywacja. W czasie ostatnich kilku miesięcy  zajmowałem się moją pracą dyplomową, a że temat był trudny oraz bardzo ciekawy to nie miałem czasu na prowadzenie tego dziennika. Dopiero teraz, kiedy doprowadziłem sprawę prawie do końca,  w miarę krótkim czasie postaram się omówić kilka ciekawych tematów. Możliwe że po obronieniu pracy (w czerwcu) napiszę o niej coś więcej.</p>
<p>Pierwszy raz wrzucam tekst artykułu na stronę. Niestety edytor wordpressa strasznie miesza formatowanie, więc nie jest tak jak w OpenOffice, w którym dokument powstał. Postaram się znaleźć jakieś rozwiązanie, ale na razie jest jak jest. Tak jak w poprzednich wpisach &#8211; artykuł można ściągnąć w formacie pdf (<a href='http://ziobrowski.files.wordpress.com/2010/05/testy1.pdf'>Testowanie poleceń bazodanowych</a>).</p>
<p>W bieżącym wpisie chciałbym poruszyć problem testowania zapytań realizowanych w oparciu o Hibernate. Wszystkie przykłady wykorzystują encje wykorzystywane w poprzednich artykułach – dla przypomnienia są to:</p>
<pre>@Entity
@Table(name="customer")
public class User
{
  @Id
  @GeneratedValue
  private Integer id;

  @OneToMany(cascade={javax.persistence.CascadeType.PERSIST}, mappedBy="author")
  private Set entries = new HashSet();

  @OneToMany(cascade={javax.persistence.CascadeType.PERSIST}, mappedBy="author")
  private Set comments = new HashSet();

  private String name;

  User(){ /* required by hiberante */ }

  public User( String name )
  {
    this.name = name;
  }

  public void addEntry( Entry entry )
  {
    entries.add( entry );
    entry.setAuthor(this);
  }

  public Set getEntries()
  {
    return entries;
  }

  public void addComment( Comment comment )
  {
    comments.add( comment );
    comment.setAuthor(this);
  }

  public Integer getId()
  {
    return id;
  }
}

@Entity
public class Entry
{
  @Id
  @GeneratedValue
  private Integer id;

  @ManyToOne(optional=false, cascade={javax.persistence.CascadeType.PERSIST})
  private User author;

  @OneToMany(cascade={javax.persistence.CascadeType.PERSIST}, mappedBy="entry")
  private Set comments = new HashSet();

  private String content;

  @Temporal(TemporalType.TIMESTAMP)
  private Date creationDate;

  Entry() { /* required by hiberante */ }

  public Entry( String content )
  {
    this.content = content;
    creationDate = new Date();
  }

  public Entry( User author, String content )
  {
    this.author = author;
    this.content = content;
    creationDate = new Date();
  }

  public void addComment( Comment comment )
  {
    comments.add( comment );
    comment.setEntry(this);
  }

  public Set getComments()
  {
    return this.comments;
  }

  public void setAuthor(User author)
  {
    this.author = author;
  }
}

@Entity
public class Comment
{
  @Id
  @GeneratedValue
  private Integer id;

  @ManyToOne(cascade={javax.persistence.CascadeType.PERSIST},optional=false)
  private Entry entry;

  @ManyToOne(cascade={javax.persistence.CascadeType.PERSIST},optional=false)
  private User author;

  private String content;

  Comment() { /* required by hibernate */ }

  public Comment( String content )
  {
    this.content = content;
  }

  public Comment( Entry entry, User author, String content )
  {
    entry.addComment(this);
    author.addComment(this);
    this.content = content;
  }

  public void setAuthor(User author)
  {
    this.author = author;
  }

  public User getAuthor()
  {
    return this.author;
  }

  public void setEntry(Entry entry)
  {
    this.entry = entry;
  }
}</pre>
<p>Tylko i wyłącznie uproszczenia operacji zapisu wewnątrz testów, wszystkie związki między encjami propagują operację „persist”.<br />
Testy zapytań, których dotyczy artykuł,  mają charakter integracyjny, gdyż wykorzystujemy w nich bazę danych, potencjalnie znajdującą się na innym komputerze. Są one potrzebne, by sprawdzić czy zapytanie działa w pożądany sposób, jak zachowa się w skrajnych sytuacjach itd. Problemem charakterystycznym testów tego rodzaju jest: „skąd wziąć dane ?”. Jeśli dysponujemy lokalną maszyną „integracyjną” na której działa baza z danymi skopiowanymi z systemu produkcyjnego, bądź wygenerowanymi (tak by ich rozkłady, wartości, częstości itp. były zbliżone), to możemy spróbować wyszukać w niej dane, które nadają się do naszego testu i je wykorzystać. Ewentualnie możemy takie dane wpisać samemu w jakimś kliencie bazy danych. Wszystko może działać świetnie do chwili, gdy ktoś owych danych nie zmodyfikuje – przypadkiem, lub celowo – by pasowały do testów jego zapytań. A  do tego prędzej czy później dojdzie na pewno. Poza tą niewątpliwą „kruchością” testu, musimy liczyć się z tym, że będzie prawdopodobnie  mało czytelny a przez to trudniejszy w utrzymaniu i zrozumieniu w przypadku gdy zakończy się niepowodzeniem.   Trudność w odczytaniu testu wynika z tego, że ma on często taką postać:</p>
<pre>@org.junit.Test
public void testQuery()
{
  List results = query( 101010, "alamakota" );

  Assert.assertEquals( 5, results.size() );
  //...
}</pre>
<p>Aby zrozumieć co tak naprawdę jest testowane musimy zajrzeć do bazy i sprawdzić dane użytkownika o identyfikatorze 101010 i powiązanych z nim rekordów – a to może zająć dużo czasu, jeśli zapytanie które testujemy jest rozbudowane i sprawdza rekordy przechodząc przez wiele tabel. I teraz wyobraźmy sobie, że nagle okazuje się, że test nie działa, a jego twórca jest na urlopie/ zmienił pracę itp. No dobrze – nawet jeśli to ostatnie nie jest prawdą to i tak jest bardzo wątpliwe by autor kodu pamiętał co w tej chwili natchnienia miał na myśli, a nas czeka mozolne przeglądanie w kliencie bazy danych wyników różnych zapytań nierzadko zawierających setki kolumn i wierszy – po to tylko by się przekonać, że np. ktoś dodał jedną literę w jakimś polu. Jeśli  korzystamy z narzędzia do ciągłej integracji aplikacji ( np. Hudsona ), to może to cały proces może potrwać jeszcze dłużej, bo będziemy podejrzewać, że to ostatnio zatwierdzona zmiana kodu jest winna całej sytuacji, i dopiero po weryfikacji nowego kodu przejdziemy do szperania w bazie danych. W skrócie – dużo mozolnej pracy i straconego czasu.<br />
Przejdźmy zatem do drugiego rozwiązania, w którym w każdym teście tworzone są dane, na których testujemy zapytanie. Postępując w ten sposób nie musimy już się bać, że jakaś zmiana w bazie zepsuje nasz test, jest on dobrze izolowany od tych zmian. Niestety wiąże się to ze wzrostem złożoności samego testu, który teraz może prezentować się następująco:</p>
<pre>@org.junit.Test
public void test()
{
  User user = new User( "user" );

  User other1 = new User( "other" );
  Entry entry = new Entry();
  other1.addEntry(entry);

  Comment comment1 = new Comment( "tralala" );
  comment1.setEntry( entry );
  user.addComment(comment1);

  Entry userEntry = new Entry( "bumcykcyk" );
  user.addEntry(userEntry);

  User other2 = new User( "someUser" );
  Comment comment2 = new Comment( "alamakota" );
  comment2.setEntry( userEntry );
  other2.addComment( comment2 );
  //...

  //save all entities
  session.persist(user);
  //...

  List readers = getReadersOf( user, session );

  Assert.assertEquals( 5, results.size() ); ) );
  //...
}</pre>
<p>Już na powyższym, prostym przykładzie widzimy, że napisanie takiego testu wymaga dużo klepania, a rezultat jest mało czytelny. W rzeczywistej aplikacji utworzenie potrzebnych danych nierzadko wymaga utworzenia kilkudziesięciu obiektów, połączonych w skomplikowany sposób i których pola muszą spełniać  różnego rodzaju ograniczenia bazodanowe. To ostatnie potrafi nieźle skomplikować sprawę, w szczególności ograniczenia UNIQUE oraz wyzwalacze – w zamyśle test powinien działać niezależnie od zastanej zawartości bazy danych. Gdy już utworzymy niezbędne obiekty, przychodzi kolej na ich utrwalenie. W przedstawionych testach załatwia to ustawienie propagacji operacji „persist” w każdym związku encji – w rzeczywistej aplikacji tak wygodnie z reguły nie jest, więc musimy sprawdzić reguły propagacji w mapowaniu i utrwalić obiekty w odpowiedniej kolejności. Gdy mamy wiele encji proces ten może zająć trochę czasu – co prawda nie tak dużo jak kreowanie danych, ale wcale nie jest to takie hop-siup. W rezultacie powstaje test liczący kilkadziesiąt lub kilkaset linii kodu, mało czytelny i trudny w diagnozie, utrzymaniu. Cechy te powodują, że wielu programistów uważa pisanie takiego testu za stratę czasu i zwyczajnie tego nie robi.<br />
Wymienione wyżej wady testów tego rodzaju można jednak usunąć: znacznie zmniejszyć objętość oraz czas potrzebny na pisanie testu oraz zwiększyć jego czytelność. Aby to zrobić musimy wpierw zaobserwować dwie charakterystyczne cechy testów tego rodzaju. Po pierwsze – często w całej aplikacji lub pewnym jej  module istnieje swego rodzaju „centralna” encja – węzeł początkowy grafu obiektów, dla której reszta encji stanowi zbiór właściwości, rozszerzeń. Po drugie – najczęściej zapisujemy cały graf obiektów – czyli wszystkie obiekty, które możemy osiągnąć przechodząc od owej encji do jej „właściwości”. W oparciu o te spostrzeżenia uprościmy proces tworzenia testu zapytań w Hibernate.<br />
Gdy w aplikacji nad którą pracujemy istnieje „centralna” encja, to z reguły w testach zapytań najpierw musimy stworzyć właśnie obiekt tego tego typu, a dopiero potem owe właściwości, dodatkowe informacje, a skoro tak to tworzenie grafu obiektów możemy napisać (w możliwie konfigurowalny sposób) raz i opakować we wzorzec projektowy Budowniczy (ang. Builder) i wykorzystywać w każdym z testów. Dla opisanych wcześniej klas – encji, zakładając że to klasa User jest „najważniejsza”, rozwiązanie to może wyglądać następująco (metody createXXX tworzą obiekty odpowiedniego typu z jakimiś domyślnymi wartościami):</p>
<pre>public class UserBuilder
{
  private boolean withComment;
  private boolean withEntry;
  private boolean withEntryComment;

  public UserBuilder(){ }

  public UserBuilder withComment()
  {
    this.withComment = true;
    return this;
  }

  public UserBuilder withEntry()
  {
    this.withEntry = true;
    return this;
  }

  public UserBuilder withEntryComments()
  {
    this.withEntryComment = true;
    return this;
  }

  public User build()
  {
    verify();

    User user = createUser( "user" );
    if ( withComment )
    {
      User other = createUser( "other" );
      Entry entry = createEntry();
      other.addEntry(entry);

      Comment comment = createComment( entry, user );
      user.addComment(comment);
    }
    if ( withEntry )
    {
      Entry entry = createEntry();
      user.addEntry(entry);

      if ( withEntryComment )
      {
        User other = createUser( "someUser" );
        createComment( entry, other );
      }
    }

    return user;
  }

  private void verify()
  {
    if ( withEntryComment &amp;&amp; !withEntry )
    {
      throw new IllegalStateException( "Entry comment required but no entry available." );
    }
  }
  //...
}</pre>
<p>Teraz nasz test staje się krótszy i dużo bardziej czytelny:</p>
<pre>@org.junit.Test
public void simplifiedTest()
{
  User user = new UserBuilder()
                  .withComment()
                  .withEntry()
                  .withEntryComments()
                  .build();

  //save all entities
  session.persist(user);
  //...

  List readers = getReadersOf( user, session );

  Assert.assertEquals( 5, results.size() ); ) );
  //...
}</pre>
<p>Oczywiście nic nie stoi na przeszkodzie, by klasa przygotowująca graf obiektów była bardziej skomplikowana – np. pozwalała na tworzenie różnej liczby komentarzy, określała jakieś ważne pola klas itp. Gdy w przyszłości asercje testu nie zostaną spełnione to dużo łatwiej będzie zrozumieć sam test i zlokalizować przyczynę błędu.<br />
Rozwiązanie drugiego z problemów tworzenia testów zapytań, a mianowicie – utrwalania grafu obiektów osiągalnych od obiektu „centralnego” (ang. presistence by reachability) wymaga zaimplementowania odpowiedniej procedury. Jest to dużo trudniejsze niż tworzenie klasy budowniczego i może trochę spowolnić testy, ale gdy już to zrobimy nie będziemy musieli sprawdzać za każdym razem ustawień propagacji operacji w mapowaniu, a w praktyce czas narzut takiej metody jest znikomy. Treść takiej metody zostanie omówiona i możliwa do pobrania ze strony w jednym z przyszłych artykułów – kiedyś już napisałem coś takiego w trochę uproszczonym wydaniu, ale gdzieś mi się zapodziało, więc muszę to zrobić ponownie. Stosując metodę utrwalającą graf obiektów test zostaje  uproszczony do postaci:</p>
<pre>@org.junit.Test
public void simplifiedTest()
{
  User user = new UserBuilder()
                  .withComment()
                  .withEntry()
                  .withEntryComments()
                  .build();

  //save all entities
  save( user );

  List readers = getReadersOf( user, session );

  Assert.assertEquals( 5, results.size() ); ) );
  //...
}</pre>
<p>Zamiast pogmatwanego, wielo(set)linijkowego behemota, otrzymujemy prostą i bardzo czytelną metodą, która można bardzo szybko napisać. Aby to osiągnąć musimy jednak wpierw utworzyć odpowiednią klasę budującą oraz metodę utrwalającą  oraz dobrze je przetestować.<br />
Korzystając z budowniczego musimy mieć świadomość, że od domyślnych wartości pól obiektów może potencjalnie zależeć wiele testów, więc raz ustalone wartości powinny być rzadko zmieniane. Najlepiej w każdym teście samemu ustawiać wartości kluczowych pól wykorzystywanych w poleceniu bazodanowym, przez co uniezależniamy się od domyślnych wartości i zwiększamy czytelność testu – nie musimy wtedy zaglądać do implementacji budowniczego by poznać owe wartości. Jeśli będziemy postępować w ten sposób to możemy bez problemu zmieniać domyślne wartości, co może okazać się przydatne podczas refaktoryzacji bazy danych – zmiany definicji pól, długości itd., bo wystarczy to zrobić w jednym miejscu dla wszystkich testów.<br />
Omawiając budowniczego warto zahaczyć o zagadnienie niezależne od zaproponowanych w artykule rozwiązań, a mianowicie o to, jakimi danymi testować polecenie. Tworząc klasę–budowniczego, możemy co prawda przyjąć jakie zechcemy wartości domyślne pól &#8211; byle tylko spełniały ograniczenia zdefiniowane w bazie danych, ale jeśli postąpimy w ten sposób to będziemy wiedzieć jak polecenie zadziała na systemie produkcyjnym. Jeśli aplikacja została już zainstalowana na takowym systemie, to należy z tego skorzystać i sprawdzić charakterystyki wartości co ważniejszych kolumn w bazie i dopiero wtedy określić wartości domyślne. Przy okazji warto zbudować słownik zawierający po kilka wartości skrajnych i przeciętnych kolumn, tak by programiści mogli je z niego pobierać i ustawiać w miejsce kluczowych dla zapytania pól. Testowanie zapytania wydaje się proste, ale lepiej się upewnić co do tego, na jakie dane może ono trafić – zwłaszcza gdy ( broń Boże ) istnieją rozbieżności między lokalną i produkcyjną bazą danych. Gdy systemu produkcyjnego jeszcze nie ma, to w oparciu o schemat bazy danych musimy sami zgadywać, na jakie wartości polecenie może się w przyszłości nadziać – pamiętając o prawach Murphy&#8217;ego dla baz danych: jeśli na jakąś kolumnę lub grupę kolumn w bazie danych nie zostało nałożone ograniczenie, to może/mogą przyjąć najgorsze dla zapytania wartości.<br />
Tak na marginesie to gdy już wystarczająco zweryfikujemy za pomocą testów  poprawność polecenia a posiadamy w bazie dane możliwie zbliżone do tych z systemu produkcyjnego, to warto włączyć w Hibernate opcje show_sql, skopiować polecenie do klienta bazy danych (np. sqldeveloper firmy Oracle) i sprawdzić plan zapytania – czasami można w ten sposób szybko odkryć problemy wydajnościowe wynikające z błędów w Hibernate lub nawet w konfiguracji bazy danych (stwierdzono metodą empiryczną).<br />
Podsumowując – pisanie testów poleceń bazodanowych w oparciu o Hibernate nie musi być pracochłonne, żmudne, monotonne, a wyniki – nieczytelne i trudne w utrzymaniu. Stosując opisane wyżej metody można pisać dobre, niezależne stanu bazy testy szybko i łatwo, a gdy w przyszłości zasygnalizują błąd – to szybko go zidentyfikujemy.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ziobrowski.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ziobrowski.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/ziobrowski.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/ziobrowski.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/ziobrowski.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/ziobrowski.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/ziobrowski.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/ziobrowski.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/ziobrowski.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/ziobrowski.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/ziobrowski.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/ziobrowski.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/ziobrowski.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/ziobrowski.wordpress.com/60/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ziobrowski.wordpress.com&amp;blog=10307678&amp;post=60&amp;subd=ziobrowski&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ziobrowski.wordpress.com/2010/05/16/testowanie-polecen-w-hibernate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0615cb3fa097ba3e7114fbcc8e02e104?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">bziobrowski</media:title>
		</media:content>
	</item>
		<item>
		<title>Typy poleceń JDBC a Postgresql i Hibernate</title>
		<link>http://ziobrowski.wordpress.com/2009/12/02/typy-polecen-jdbc-a-postgresql-i-hibernate/</link>
		<comments>http://ziobrowski.wordpress.com/2009/12/02/typy-polecen-jdbc-a-postgresql-i-hibernate/#comments</comments>
		<pubDate>Wed, 02 Dec 2009 10:21:24 +0000</pubDate>
		<dc:creator>bziobrowski</dc:creator>
				<category><![CDATA[hibernate]]></category>
		<category><![CDATA[postgresql]]></category>
		<category><![CDATA[JDBC]]></category>
		<category><![CDATA[PreparedStatement]]></category>
		<category><![CDATA[Statement]]></category>

		<guid isPermaLink="false">http://ziobrowski.wordpress.com/?p=45</guid>
		<description><![CDATA[Po dwóch artykułach dotyczących zagadnień specyficznych dla narzędzia Hibernate przyszedł czas na temat dotyczący w większej mierze bazy danych (chociaż znalazło się w nim miejsce i dla Hibernate). Obecna publikacja opisuje to jak realizowane są w Postgresql dwa główne typy poleceń SQL w JDBC &#8211; Statement i PreparedStatement, jakie mają właściwości, wady i zalety. Staram [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ziobrowski.wordpress.com&amp;blog=10307678&amp;post=45&amp;subd=ziobrowski&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Po dwóch artykułach dotyczących zagadnień specyficznych dla narzędzia Hibernate przyszedł czas na temat dotyczący w większej mierze bazy danych (chociaż znalazło się w nim miejsce i dla Hibernate). Obecna publikacja opisuje to jak realizowane są w Postgresql dwa główne typy poleceń SQL w JDBC &#8211; Statement i PreparedStatement, jakie mają właściwości, wady i zalety. Staram się przedstawić w możliwie kompletny sposób zagadnienia powiązanie z poleceniami prekompilowanymi, które decydują o ich zastosowaniu bądź odrzuceniu. Kwestii tych jest całkiem sporo, dlatego też dokument jest obszerniejszy od poprzednich.</p>
<p><a href="http://ziobrowski.files.wordpress.com/2009/12/rodzajepolecenjdbcapostgresqlihibernate2.pdf">Typy Poleceń JDBC a Postgresql i Hibernate</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ziobrowski.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ziobrowski.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/ziobrowski.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/ziobrowski.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/ziobrowski.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/ziobrowski.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/ziobrowski.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/ziobrowski.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/ziobrowski.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/ziobrowski.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/ziobrowski.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/ziobrowski.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/ziobrowski.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/ziobrowski.wordpress.com/45/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ziobrowski.wordpress.com&amp;blog=10307678&amp;post=45&amp;subd=ziobrowski&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ziobrowski.wordpress.com/2009/12/02/typy-polecen-jdbc-a-postgresql-i-hibernate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0615cb3fa097ba3e7114fbcc8e02e104?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">bziobrowski</media:title>
		</media:content>
	</item>
		<item>
		<title>Operacje kaskadowe w Hibernate</title>
		<link>http://ziobrowski.wordpress.com/2009/11/16/operacje-kaskadowe-w-hibernate/</link>
		<comments>http://ziobrowski.wordpress.com/2009/11/16/operacje-kaskadowe-w-hibernate/#comments</comments>
		<pubDate>Mon, 16 Nov 2009 15:18:42 +0000</pubDate>
		<dc:creator>bziobrowski</dc:creator>
				<category><![CDATA[hibernate]]></category>
		<category><![CDATA[cascade]]></category>
		<category><![CDATA[operacje kaskadowe]]></category>
		<category><![CDATA[propagacja zmian]]></category>

		<guid isPermaLink="false">http://ziobrowski.wordpress.com/?p=30</guid>
		<description><![CDATA[Tym razem pokazuję jak radzić sobie z nieodpowiednimi ustawieniami operacji kaskadowych, jak działa ten mechanizm, oraz jak z niego korzystać. Operacje kaskadowe w Hibernate PS. Może w końcu zacznę umieszczać treść artykułów bezpośrednio na stronie, ale jak na razie toporny interfejs  edycji wpisów skutecznie mnie zniecęca.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ziobrowski.wordpress.com&amp;blog=10307678&amp;post=30&amp;subd=ziobrowski&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Tym razem pokazuję jak radzić sobie z nieodpowiednimi ustawieniami operacji kaskadowych, jak działa ten mechanizm, oraz jak z niego korzystać.</p>
<p><a href="http://ziobrowski.files.wordpress.com/2009/11/operacjekaskadowe.pdf">Operacje kaskadowe w Hibernate</a></p>
<p>PS. Może w końcu zacznę umieszczać treść artykułów bezpośrednio na stronie, ale jak na razie toporny interfejs  edycji wpisów skutecznie mnie zniecęca.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ziobrowski.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ziobrowski.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/ziobrowski.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/ziobrowski.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/ziobrowski.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/ziobrowski.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/ziobrowski.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/ziobrowski.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/ziobrowski.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/ziobrowski.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/ziobrowski.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/ziobrowski.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/ziobrowski.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/ziobrowski.wordpress.com/30/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ziobrowski.wordpress.com&amp;blog=10307678&amp;post=30&amp;subd=ziobrowski&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ziobrowski.wordpress.com/2009/11/16/operacje-kaskadowe-w-hibernate/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0615cb3fa097ba3e7114fbcc8e02e104?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">bziobrowski</media:title>
		</media:content>
	</item>
		<item>
		<title>Automatyczne pobieranie obiektów w hibernate</title>
		<link>http://ziobrowski.wordpress.com/2009/11/06/automatyczne-pobieranie-obiektow-w-hibernate/</link>
		<comments>http://ziobrowski.wordpress.com/2009/11/06/automatyczne-pobieranie-obiektow-w-hibernate/#comments</comments>
		<pubDate>Fri, 06 Nov 2009 22:13:16 +0000</pubDate>
		<dc:creator>bziobrowski</dc:creator>
				<category><![CDATA[hibernate]]></category>
		<category><![CDATA[fetch strategy]]></category>
		<category><![CDATA[pobieranie gorliwe]]></category>
		<category><![CDATA[pobieranie leniwe]]></category>
		<category><![CDATA[wczytywanie danych]]></category>
		<category><![CDATA[wydajność zapytań]]></category>

		<guid isPermaLink="false">http://ziobrowski.wordpress.com/?p=17</guid>
		<description><![CDATA[Jest to pierwszy z serii artykułów, które chciałbym poświęcić narzędziu Hibernate. Staram się w nim odpowiedzieć na pytanie jak konfigurować mapowanie tabel bazodanowych na obiekty, a w szczególności &#8211; czy dany związek między encjami powinien być gorliwy czy leniwy. hibernate-automatyczne-pobieranie-obiektow PS: nadchodząca wersja 3.5 ma, według zapowiedzi zespołu Hibernate (https://www.hibernate.org/357.html#A8), wprowadzić &#34;profile pobierania danych&#34;, czyli [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ziobrowski.wordpress.com&amp;blog=10307678&amp;post=17&amp;subd=ziobrowski&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://ziobrowski.files.wordpress.com/2009/11/hibernate-automatyczne-pobieranie-obiektow.pdf"></a>Jest to pierwszy z serii artykułów, które chciałbym poświęcić narzędziu Hibernate. Staram się w nim odpowiedzieć na pytanie jak konfigurować mapowanie tabel bazodanowych na obiekty, a w szczególności &#8211; czy dany związek między encjami powinien być gorliwy czy leniwy.</p>
<p><a href="../files/2009/11/hibernate-automatyczne-pobieranie-obiektow.pdf">hibernate-automatyczne-pobieranie-obiektow</a></p>
<p>PS: nadchodząca wersja 3.5 ma, według zapowiedzi zespołu Hibernate (<a href="//www.hibernate.org/357.html#A8">https://www.hibernate.org/357.html#A8</a>), wprowadzić &quot;profile pobierania danych&quot;, czyli możliwość definiowania wielu wersji ustawień pobierania obiektów, które można przeglądać w czasie wykonania aplikacji i wybierać ten najbardziej odpowedni do sytuacji. Postaram się zaktualizować artykuł po tym, gdy wersja 3.5 ujrzy światło dzienne.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ziobrowski.wordpress.com/17/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ziobrowski.wordpress.com/17/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/ziobrowski.wordpress.com/17/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/ziobrowski.wordpress.com/17/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/ziobrowski.wordpress.com/17/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/ziobrowski.wordpress.com/17/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/ziobrowski.wordpress.com/17/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/ziobrowski.wordpress.com/17/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/ziobrowski.wordpress.com/17/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/ziobrowski.wordpress.com/17/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/ziobrowski.wordpress.com/17/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/ziobrowski.wordpress.com/17/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/ziobrowski.wordpress.com/17/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/ziobrowski.wordpress.com/17/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ziobrowski.wordpress.com&amp;blog=10307678&amp;post=17&amp;subd=ziobrowski&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ziobrowski.wordpress.com/2009/11/06/automatyczne-pobieranie-obiektow-w-hibernate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0615cb3fa097ba3e7114fbcc8e02e104?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">bziobrowski</media:title>
		</media:content>
	</item>
	</channel>
</rss>
