19 kwietnia 2008

Nowości NetBeans 6.1 - Hibernate Framework Support w cięciu kosztów dostępu do danych relacyjnych

Otrzymałem prośbę o sprawdzenie artykułu, który napisałem jeszcze w 2006 roku o Hibernate - Hibernate - tniemy koszty dostępu do danych relacyjnych. Hibernate i jego wsparcie w NetBeans 6.1 było jedną z rzeczy, które niedawno postanowiłem sprawdzić, więc w czasach pieczenia wielu pieczeni na jednym ogniu tym razem nie będzie inaczej - sprawdzę aktualność artykułu i wsparcie NetBeans dla Hibernate.

Krótka lektura dokumentu NetBeans 6.1 Milestones New and Noteworthy i można zabrać się do pracy.

Instaluję wtyczkę NetBeans dla Hibernate - Tools > Plugins, zaznaczam Hibernate Support oraz Hibernate 3.2.5 Library.


i Install.

Ctrl+Shift+N i z kategorii Java wybieram Java Application. Next >. Definiuję szczegóły aplikacji


Tworzę klasę encji User. Ctrl+N, Java > Java Class. W edytorze klasy User wciskam Alt+Insert i wybieram Add Property...


i definiuję atrybuty id, a następnie imie i nazwisko.

Klasa prezentuje się następująco:
 package pl.jaceklaskowski.hibernate;

public class User {

private int id;
private String imie;
private String nazwisko;

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getImie() {
return imie;
}

public void setImie(String imie) {
this.imie = imie;
}

public String getNazwisko() {
return nazwisko;
}

public void setNazwisko(String nazwisko) {
this.nazwisko = nazwisko;
}
}
Dodaję bibliotekę Hibernate 3.2.5 do projektu. Wybieram Properties projektu i przechodzę do Libraries, gdzie korzystam z Add Library...


zatwierdzam wybór przyciskiem Add Library


i OK.

Przechodzę do klasy HibernateExample i kopiuję zawartość klasy z artykułu. Ctrl+Shift+I, aby uzupełnić pakiety klas Hibernate (uwaga na klasę Configuration, która powinna być org.hibernate.cfg.Configuration oraz Transaction z pakietu org.hibernate).

Ostatecznie klasa wygląda następująco:
 package pl.jaceklaskowski.hibernate;

import java.util.Iterator;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class HibernateExample {

private final static SessionFactory factory;

static {
// 1. Inicjalizacja Hibernate
Configuration cfg = new Configuration().configure();

// 2. Utworzenie fabryki sesji Hibernate
factory = cfg.buildSessionFactory();
}

public static void main(String[] args) {
HibernateExample m = new HibernateExample();
m.createUsers();
m.displayUsers();
}

public void createUsers() {
// 3. Otwarcie sesji Hibernate
Session session = factory.openSession();

// 4. Rozpoczęcie transakcji
Transaction tx = session.beginTransaction();

// 5. Utworzenie użytkownika
User u = new User();
u.setImie("Jacek");
u.setNazwisko("Laskowski");

// 6. Zapisanie użytkownika w bazie danych
session.save(u);

// 7. Zatwierdzenie transakcji
tx.commit();

// 8. Zamknięcie sesji Hibernate
session.close();
}

public void displayUsers() {
// 3. Otwarcie sesji Hibernate
Session session = factory.openSession();

// 4. Rozpoczęcie transakcji
Transaction tx = session.beginTransaction();

// 5. Utworzenie zapytania SQL do bazy o listę użytkowników
Criteria criteria = session.createCriteria(User.class);

// 6. Wykonanie zapytania SQL
List users = criteria.list();

// 7. Iterowanie po wyniku zapytania SQL
for (Iterator it = users.iterator(); it.hasNext();) {
User user = (User) it.next();
System.out.println(user);
}

// 8. Zatwierdzenie transakcji
tx.commit();

// 9. Zamknięcie sesji Hibernate
session.close();
}
}
Tworzę plik hibernate.cfg.xml - Ctrl+N, XML > XML Document. Nadaję mu nazwę hibernate.cfg (rozszerzenie xml dodawane jest automatycznie) i umieszczam w katalogu src.


Next i Finish.

Plik konfiguracyjny aplikacji opartej o Hibernate - hibernate.cfg.xml - przedstawia się następująco (zmieniłem nazwę pakietu, a w zasadzie katalogu, gdzie Hibernate będzie poszukiwał pliku mapowania dla encji User):
 <?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">org.hsqldb.jdbcDriver
</property>
<property name="connection.url">jdbc:hsqldb:.
</property>
<property name="connection.username">sa
</property>
<property name="connection.password">
</property>
<property name="connection.pool_size">1
</property>
<property name="dialect">org.hibernate.dialect.HSQLDialect
</property>
<property name="current_session_context_class">thread
</property>
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider
</property>
<property name="show_sql">true
</property>
<property name="hbm2ddl.auto">create
</property>
<mapping resource="pl/jaceklaskowski/hibernate/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
(Ech to formatowanie w NetBeans - dlaczego znaczniki zamykające są w nowej linii?!)

Tworzę plik mapowania dla encji User w katalogu src/pl/jaceklaskowski/hibernate/User.hbm.xml - Ctrl+N, XML > XML Document i z wcześniej podświetlonym pakietem pl.jaceklaskowski.hibernate w oknie Projects mam już uzupełnione pole Folder w asystencie tworzenia pliku xml. Ostatecznie plik User.hbm.xml prezentuje się następująco:
 <?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="pl.jaceklaskowski.hibernate">
<class name="User" table="User">
<id name="id">
<generator class="native"/>
</id>
<property name="imie" column="T_IMIE" length="10" not-null="true"/>
<property name="nazwisko" column="T_NAZWISKO" length="25" not-null="true"/>
</class>
</hibernate-mapping>
Podczas edycji pojawił się błąd w NetBeans, który zgłosiłem jako 133253: AE: Token length=0 <= 0, który zanim opublikowałem wpis został oznaczony jako duplikat błędu poprawionego w najnowszej wersji rozwojowej NetBeans 6.1 - kolejny powód porzucenia RC1. Po wystąpieniu tego błędu, praca z edytorem XML należała do niezwykle nieprzyjemnych (delikatnie mówiąc).

Pora na dodanie kilku bibliotek pomocniczych dla Hibernate (i tutaj kolejny raz pojawia się zaleta stosowania narzędzia, które samodzielnie zadbałoby o zarządzanie zależnościami, np. Apache Maven 2). Ale moment, przecież dodanie biblioteki Hibernate w NetBeans to jest dokładnie ten krok - wszystkie konieczne zależności zostały również dodane (!) Do czegoś się jednak ten NetBeans 6.1 przydał ;-)

Pierwsze uruchomienie aplikacji za pomocą Run (skrót klawiszowy F6) kończy się błędem:
 java.lang.ClassNotFoundException: org.hsqldb.jdbcDriver
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
at org.hibernate.util.ReflectHelper.classForName(ReflectHelper.java:100)
at org.hibernate.connection.DriverManagerConnectionProvider.configure(DriverManagerConnectionProvider.java:61)
at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:124)
at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:56)
at org.hibernate.cfg.SettingsFactory.createConnectionProvider(SettingsFactory.java:414)
at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:62)
at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2009)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1292)
at pl.jaceklaskowski.hibernate.HibernateExample.(HibernateExample.java:21)
java.lang.ExceptionInInitializerError
Caused by: org.hibernate.HibernateException: JDBC Driver class not found: org.hsqldb.jdbcDriver
at org.hibernate.connection.DriverManagerConnectionProvider.configure(DriverManagerConnectionProvider.java:66)
at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:124)
at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:56)
at org.hibernate.cfg.SettingsFactory.createConnectionProvider(SettingsFactory.java:414)
at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:62)
at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2009)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1292)
at pl.jaceklaskowski.hibernate.HibernateExample.(HibernateExample.java:21)
Caused by: java.lang.ClassNotFoundException: org.hsqldb.jdbcDriver
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
at org.hibernate.util.ReflectHelper.classForName(ReflectHelper.java:100)
at org.hibernate.connection.DriverManagerConnectionProvider.configure(DriverManagerConnectionProvider.java:61)
... 7 more
Jak najbardziej zrozumiałe biorąc pod uwagę, że korzystam z HSQLDB, a nigdzie nie zadeklarowałem tej potrzeby poza plikiem konfiguracyjnym Hibernate'a - hibernate.cfg.xml (linia <property name="connection.driver_class">org.hsqldb.jdbcDriver</property>). Dodaję bibliotekę HSQLDB do projektu - Properties > Libraries > Add Library... i okazuje się, że nie ma wsparcia dla niego wsparcia w NetBeans 6.1. Jest jednak wsparcie (gotowa do użycia biblioteka) dla Java DB (Apache Derby) oraz MySQL. Zmieniam konfigurację Hibernate, tak aby w użyciu była baza danych Java DB (jestem zbyt leniwy, aby pobierać HSQLDB z sieci, skoro mogę skorzystać z czegoś co mam pod ręką).

Dodaję bibliotekę Java DB Driver do projektu.


Muszę również zmienić plik hibernate.cfg.xml (nie muszę oczywiście zmieniać innych części aplikacji, które są niezależne od wykorzystywanej bazy danych). Tutaj przyadłoby się wsparcie NetBeans dla pracy z Hibernate, w którym zdefiniowałbym źródło danych, a plik konfiguracyjny zostałby zmodyfikowany w odpowiedni sposób, ukrywając przede mną tajniki konfiguracji Hibernate i Java DB. Na razie muszę to zrobić ręcznie (podeprę się moim artykułem o OpenJPA z Derby - Java Persistence API z OpenJPA i Derby oraz TestNG z Eclipse IDE w tle oraz Hibernate jako dostawca JPA w samodzielnej aplikacji). Zmieniony plik hibernate.cfg.xml prezentuje sie następująco:
 <?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">org.apache.derby.jdbc.EmbeddedDriver
</property>
<property name="connection.url">jdbc:derby:derbyDB;create=true
</property>
<property name="connection.username">app
</property>
<property name="connection.password">app
</property>
<property name="connection.pool_size">1
</property>
<property name="dialect">org.hibernate.dialect.DerbyDialect
</property>
<property name="current_session_context_class">thread
</property>
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider
</property>
<property name="show_sql">true
</property>
<property name="hbm2ddl.auto">create
</property>
<mapping resource="pl/jaceklaskowski/hibernate/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Ponownie uruchamiam aplikację - F6 i...aplikacja kończy się błędem o braku poprawnej składni SQL.
 INFO: exporting generated schema to database
Apr 19, 2008 12:37:38 PM org.hibernate.tool.hbm2ddl.SchemaExport create
SEVERE: Unsuccessful: create table User (id integer not null, T_IMIE varchar(10) not null, T_NAZWISKO varchar(25) not null, primary key (id))
Apr 19, 2008 12:37:38 PM org.hibernate.tool.hbm2ddl.SchemaExport create
SEVERE: Syntax error: Encountered "User" at line 1, column 14.
Apr 19, 2008 12:37:38 PM org.hibernate.tool.hbm2ddl.SchemaExport execute
INFO: schema export complete
Hibernate: insert into User (T_IMIE, T_NAZWISKO, id) values (?, ?, ?)
Apr 19, 2008 12:37:38 PM org.hibernate.util.JDBCExceptionReporter logExceptions
WARNING: SQL Error: -1, SQLState: 42X01
Apr 19, 2008 12:37:38 PM org.hibernate.util.JDBCExceptionReporter logExceptions
SEVERE: Syntax error: Encountered "User" at line 1, column 13.
Apr 19, 2008 12:37:38 PM org.hibernate.event.def.AbstractFlushingEventListener performExecutions
SEVERE: Could not synchronize database state with session
org.hibernate.exception.SQLGrammarException: could not insert: [pl.jaceklaskowski.hibernate.User]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2267)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2660)
at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:56)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:234)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at pl.jaceklaskowski.hibernate.HibernateExample.createUsers(HibernateExample.java:46)
at pl.jaceklaskowski.hibernate.HibernateExample.main(HibernateExample.java:26)
Caused by: java.sql.SQLSyntaxErrorException: Syntax error: Encountered "User" at line 1, column 13.
at org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(Unknown Source)
at org.apache.derby.client.am.SqlException.getSQLException(Unknown Source)
at org.apache.derby.client.am.Connection.prepareStatement(Unknown Source)
at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:505)
at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:94)
at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:87)
at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:222)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2224)
... 12 more
Caused by: org.apache.derby.client.am.SqlException: Syntax error: Encountered "User" at line 1, column 13.
at org.apache.derby.client.am.Statement.completeSqlca(Unknown Source)
at org.apache.derby.client.net.NetStatementReply.parsePrepareError(Unknown Source)
at org.apache.derby.client.net.NetStatementReply.parsePRPSQLSTTreply(Unknown Source)
at org.apache.derby.client.net.NetStatementReply.readPrepareDescribeOutput(Unknown Source)
at org.apache.derby.client.net.StatementReply.readPrepareDescribeOutput(Unknown Source)
at org.apache.derby.client.net.NetStatement.readPrepareDescribeOutput_(Unknown Source)
at org.apache.derby.client.am.Statement.readPrepareDescribeOutput(Unknown Source)
at org.apache.derby.client.am.PreparedStatement.readPrepareDescribeInputOutput(Unknown Source)
at org.apache.derby.client.am.PreparedStatement.flowPrepareDescribeInputOutput(Unknown Source)
at org.apache.derby.client.am.PreparedStatement.prepare(Unknown Source)
at org.apache.derby.client.am.Connection.prepareStatementX(Unknown Source)
... 18 more
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not insert: [pl.jaceklaskowski.hibernate.User]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2267)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2660)
at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:56)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:234)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at pl.jaceklaskowski.hibernate.HibernateExample.createUsers(HibernateExample.java:46)
at pl.jaceklaskowski.hibernate.HibernateExample.main(HibernateExample.java:26)
Caused by: java.sql.SQLSyntaxErrorException: Syntax error: Encountered "User" at line 1, column 13.
at org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(Unknown Source)
at org.apache.derby.client.am.SqlException.getSQLException(Unknown Source)
at org.apache.derby.client.am.Connection.prepareStatement(Unknown Source)
at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:505)
at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:94)
at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:87)
at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:222)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2224)
... 12 more
Caused by: org.apache.derby.client.am.SqlException: Syntax error: Encountered "User" at line 1, column 13.
at org.apache.derby.client.am.Statement.completeSqlca(Unknown Source)
at org.apache.derby.client.net.NetStatementReply.parsePrepareError(Unknown Source)
at org.apache.derby.client.net.NetStatementReply.parsePRPSQLSTTreply(Unknown Source)
at org.apache.derby.client.net.NetStatementReply.readPrepareDescribeOutput(Unknown Source)
at org.apache.derby.client.net.StatementReply.readPrepareDescribeOutput(Unknown Source)
at org.apache.derby.client.net.NetStatement.readPrepareDescribeOutput_(Unknown Source)
at org.apache.derby.client.am.Statement.readPrepareDescribeOutput(Unknown Source)
at org.apache.derby.client.am.PreparedStatement.readPrepareDescribeInputOutput(Unknown Source)
at org.apache.derby.client.am.PreparedStatement.flowPrepareDescribeInputOutput(Unknown Source)
at org.apache.derby.client.am.PreparedStatement.prepare(Unknown Source)
at org.apache.derby.client.am.Connection.prepareStatementX(Unknown Source)
... 18 more
Patrząc na komentarze użytkowników do mojego wpisu Hibernate - tniemy koszty dostępu do danych relacyjnych wielu prosiło o możliwość podejrzenia struktury bazodanowej po uruchomieniu aplikacji, więc skorzystam z bazy dostarczanej przez NetBeans - sample. W międzyczasie musiałem zrestartować NetBeans i dopiero po tym zauważam, że NetBeans 6.1 rozpoznaje pliki hibernate i upraszcza ich edycję - działa podpowiadanie elementów pliku konfiguracyjnego Hibernate (!) Ctrl+Spacja działa i w dodatku podmienia starą konfigurację (elementy bez prefiksu hibernate na te, z prefiksem).


czy


Kolejną ciekawostką wsparcia NetBeans 6.1 dla projektów korzystających z Hibernate jest oznaczenie dedykowaną ikoną Hibernate plików konfiguracyjnych hibernate.cfg.xml oraz User.hbm.xml (wydaje mi się, że NetBeans początkowo ich nie rozpoznawał, ale dopiero po restarcie mam wrażenie, że pliki zostały rozpoznane jako hibernetowe i oznaczone odpowiednią ikoną).


oraz udostępnienie specjalizowanego edytora:


Dodam do tego, że w Hibernate - tniemy koszty dostępu do danych relacyjnych miałem w pliku hibernate.cfg.xml zdefiniowane <property name="hbm2ddl.auto">create</property>, a w Hibernate jako dostawca JPA w samodzielnej aplikacji <property name="hibernate.hbm2ddl.auto" value="update"/> i jako że nie pamiętałem, jaką wartość powinien mieć ten parametr, aby baza była każdorazowo tworzona przy startcie aplikacji skorzystałem z pomocy NetBeans 6.1 (zamiast, jak to w takich momentach robię, Google. Zdaje się, że rośnie nam ciekawa konkurencja dla Google w postaci NetBeans 6.1 ;-)).


Po tych zachwytach i pomocy ze strony NetBeans plik hibernate.cfg.xml wygląda następująco:
 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">org.apache.derby.jdbc.ClientDriver
</property>
<property name="hibernate.connection.url">jdbc:derby://localhost:1527/sample
</property>
<property name="hibernate.connection.username">app
</property>
<property name="hibernate.connection.password">app
</property>
<property name="hibernate.connection.pool_size">1
</property>
<property name="hibernate.current_session_context_class">thread
</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider
</property>
<property name="hibernate.dialect">org.hibernate.dialect.DerbyDialect
</property>
<property name="hibernate.show_sql">true
</property>
<property name="hibernate.format_sql">true
</property>
<property name="hibernate.hbm2ddl.auto">create-drop</property>
<mapping resource="pl/jaceklaskowski/hibernate/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Uruchamiam Java DB - w oknie Services, kategoria Databases i na Java DB wybieram Start Server (niestety poza nieaktywnym menu Start Server nie ma wizualnego oznaczenia, np. w postaci zielonej strzałki jak na serwerach, że baza już jest uruchomiona).

Ponowne uruchomienie i ponowny błąd. Co jest?! Po kilku próbach okazuje się, że Java DB nie akceptuje nazwy tabeli USER (nawet edytor SQL nie podświetla USER na zielono, co już wskazuje na jakiś błąd).


Sprawdzam w dokumentacji Apache Derby 10.2 CREATE TABLE statement i sama struktura polecenia jest dobra, a w dodatku nic nie widzę o zakazie stosowania USER jako nazwy bazy danych. Hmmm, coś tu jest nie tak. Ale co?! Nie zastanawiając się długo zmieniam nazwę tabeli, na którą jest mapowana klasa User na UZYTKOWNIK w pliku User.hbm.xml.
 <?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="pl.jaceklaskowski.hibernate">
<class name="User" table="UZYTKOWNIK">
<id name="id" >
<generator class="native"/>
</id>
<property name="imie" column="T_IMIE" length="10" not-null="true"/>
<property name="nazwisko" column="T_NAZWISKO" length="25" not-null="true"/>
</class>
</hibernate-mapping>
Ponownie F6 i już działa jak należy. W końcu! Teraz mógłbym wrócić do konfiguracji z wbudowaną bazą danych, ale to pozostawiam jako zadanie domowe dla zainteresowanych.

Pytanie konkursowe: Jaka jest domyślna nazwa pliku konfiguracyjnego Hibernate? (nagród proszę nie oczekiwać).

Pełna aplikacja HibernateExample dostępna jest do pobrania jako HibernateExample.zip. Miłej hibernacji!

3 komentarze:

  1. Witam Panie Jacku. Dziękuję, że tak szybko odpowiedział Pan na moją prośbę. Wszystko opisane krok po kroku także nie ma możliwości żeby ktoś nie zrozumiał. Ja dopiero zaczynam swoją przygodę z Hibernate i dzięki takim artykułom jak ten widzę już światełko w ciemnym tunelu. Odpowiadając na pytanie konkursowe ten plik nazywa się hibernate.properties:)
    Pozdrawiam Panie Jacku i życzę dalszych sukcesów a sobie i wszystkim innym początkującym programistom życzę jak najwięcej takich artykułow.

    OdpowiedzUsuń
  2. Wsparcie dla hibernate w "NetGroszku" ;) - to apropos "RUSZTOWANIA" :) jest naprawdę niezłe nie wiedziałem o nim wcześniej - dobry artykuł pozdrawiam!

    OdpowiedzUsuń
  3. wszystko ok - niezły artykuł - tylko jak zmusić netbeans do korzystania z hibernate przy łączeniu komponentów swing z bazą danych np JTable - poprzez TopLink całą robotę robią netbeans - jak to zrobić z hibernatem

    OdpowiedzUsuń