OpenJPA + HSQLDB z użyciem Maven2 i Eclipse

Ostatnio ktoś mi powiedział, że używanie takiej kobyły (Maven) do takiego programiku mija się z celem, może i tak, ale dobre praktyki się przydają, to raz, a dwa trochę bibliotek będzie potrzebnych do uruchomienia programu, więc aby nie było problemów, to Maven zrobi to za nas :D

Na początek odpalamy eclipse i tworzymy nowy projekt maven (do tego celu używam wtyczki m2eclipse) jako groupId podaje pl.xon.lewy jako artifactId openjpa i klikam finisz (wsześniej podczas tworzenia zaznaczyłem, że chcę pominąć sekcję z archetypami), podobny efekt do tego, który osiągnąłem można uzyskać poprzez wydanie w konsoli poleceń mvn archetype:create -DgroupId=pl.xon.lewy -DartifactId=openjpa -Dversion=1.0 następnie polecenie mvn eclipse:eclipse i już projekt jest gotowy do zaimportowania do eclipse.

Na początek dodajemy do projektu kilka niezbędnych bibliotek, pierwsza z nich odpowidzialna za głównego bohatera naszego wpisu, czyli OpenJPA, najprościej dokonać tego poprzez kliknięcie prawym przyciskiem myszy na nazwie projektu, nastepnie Maven i Add Dependency i wyszukujemy openjpa, ja wybieram wersję 2.0.0-M3, taki sam efekt uzyskać można poprzez dodanie wpisu w sekcji dependencies w pliku pom.xml

<dependencies>
	<dependency>
		<groupId>org.apache.openjpa</groupId>
		<artifactId>openjpa</artifactId>
		<version>2.0.0-M3</version>
	</dependency>
</dependencies>

Następny krok to biblioteka HSQLDB, dodaje się ją w taki sam sposób, w moim przypadku wersja 1.8.0.10

<dependency>
	<groupId>hsqldb</groupId>
	<artifactId>hsqldb</artifactId>
	<version>1.8.0.10</version>
</dependency>

No to dodanie zależności do naszego projektu mamy za sobą, kolejnym ważnym krokiem jest utworzenie pliku persistence.xml, w którym zapisujemy konfigurację dla JPA, jak wiadomo Maven ma ściśle określoną strukturę plików, tak więc plik presistence.xml też ma „swoje” miejsce i znajdować musi się w katalogu NASZ_PROJEKT/src/main/resources/META-INF/presistence.xml, jego wygląd uzależniony jest w pewnym sensie od bazy i dostawcy JPA jakiego używamy, dla HSQLDB i OpenJPA mój plik wygląda tak

<?xml version="1.0"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence">
	<persistence-unit name="default">
		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
		<class>pl.xon.lewy.Klasa</class>
		<properties>
			<property name="openjpa.ConnectionURL" value="jdbc:hsqldb:file:test.db;shutdown=true" />
			<property name="openjpa.ConnectionDriverName" value="org.hsqldb.jdbcDriver" />
			<property name="openjpa.ConnectionUserName" value="sa" />
			<property name="openjpa.ConnectionPassword" value="" />
			<property name="openjpa.jdbc.Schema" value="PUBLIC" />
			<property name="openjpa.Log" value="DefaultLevel=ERROR, Tool=INFO" />
			<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)" />
		</properties>
		</persistence-unit>
</persistence>

mam nadzieję, że większość linijek jest zrozumiała i nie trzeba ich omawiać, ważne na pewno jest name w presistence-unit, ponieważ po nim identyfikujemy baze jakiej używamy, gdyż w pliku presistence.xml możemy zdefiniować sobie ich więcej, kolejna ciekawa linijka to ta z <class> gdyż w tym miejscu definiujemy klasy, które będą mapowane w danej bazie (linijek takich może pojawić się wiecej niż jedna).

Dobra gdy wszystko skonfigurowane czas napisać jakąś encję (klasę, która będzie odzwierciedlana w bazie danych), u mnie ona oczywiście nazywa się Klasa i jest w paczce pl.xon.lewy, aby klasa stała się encją, przed jej nazwą należy dodać adnotacje @Entity, w klasie dodałem też jakieś zmienne, które będą kolumnami w bazie, plik wygląda mniej więcej tak

package pl.xon.lewy;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Klasa {
	@Id
	@GeneratedValue
	private int id;

	@Column
	private int jakasLiczba;

	@Column
	private String jakisNapis;

	public int getId() {
		return id;
	}

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

	public int getJakasLiczba() {
		return jakasLiczba;
	}

	public void setJakasLiczba(int jakasLiczba) {
		this.jakasLiczba = jakasLiczba;
	}

	public String getJakisNapis() {
		return jakisNapis;
	}

	public void setJakisNapis(String jakisNapis) {
		this.jakisNapis = jakisNapis;
	}
}

adnotacja @Column nie jest niezbędna, przydaje się, gdybyśmy chcieli jakąś zmienną umieszczać w kolumnie o innej nazwie (@Column(name=”liczba”)).

Gdy mamy już naszą klase, należy stworzyć jeszcze klasę główną programu (u mnie nazwa Main)

package pl.xon.lewy;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;

public class Main {
	private static EntityManagerFactory jpaFactory = Persistence.createEntityManagerFactory("default");

	@SuppressWarnings("unchecked")
	public static void main(String[] args) {
		if(args.length == 2) {
			EntityManager jpa = jpaFactory.createEntityManager();
			jpa.getTransaction().begin();
			Klasa k = new Klasa();
			k.setJakasLiczba(Integer.parseInt(args[0]));
			k.setJakisNapis(args[1]);
			jpa.persist(k);
			jpa.getTransaction().commit();
			jpa.close();
		} else {
			EntityManager jpa = jpaFactory.createEntityManager();
			Query zapytanie = jpa.createQuery("SELECT k FROM Klasa k");
			List<Klasa> wyniki = zapytanie.getResultList();
			for(Klasa k : wyniki) {
				System.out.println("[klasa]");
				System.out.println("id: " + k.getId());
				System.out.println("liczba: " + k.getJakasLiczba());
				System.out.println("napis: " + k.getJakisNapis());
			}
			jpa.close();
		}
	}
}

Na koniec pozostało jeszcze trochę konfiguracji Maven’a, dodanie kilku pluginów, które ulatwią życie ;)

Pierwszy z nich odpowiedzialny jest za stworzenie pliku jar, wraz z odpowiednim plikiem manifestu dla niego i wygląda mniej więcej tak

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-jar-plugin</artifactId>
	<version>2.2</version>
	<configuration>
		<archive>
			<manifest>
				<mainClass>pl.xon.lewy.Main</mainClass>
				<packageName>pl.xon.lewy</packageName>
				<addClasspath>true</addClasspath>
				<classpathPrefix>lib</classpathPrefix>
			</manifest>
		</archive>
	</configuration>
</plugin>

Kolejnym pluginem jest plugin ustawiający z jakiej wersji JAVY będziemy korzystać podczas kompilacji projektu, tutaj ważne jest aby była to JAVA w wersji minimum 5, ponieważ dopiero wtedy wprowadzono adnotacje

<plugin>
	<inherited>true</inherited>
	<artifactId>maven-compiler-plugin</artifactId>
	<version>2.0.2</version>
	<configuration>
		<source>1.6</source>
		<target>1.6</target>
	</configuration>
</plugin>

Teraz chyba najważniejszy dla naszej aplikacji plugin, który odpowiedzialny jest za OpenJPA

<plugin>
  	<groupId>org.codehaus.mojo</groupId>
	<artifactId>openjpa-maven-plugin</artifactId>
	<version>1.0</version>
	<configuration>
		<addDefaultConstructor>true</addDefaultConstructor>
		<enforcePropertyRestrictions>true</enforcePropertyRestrictions>
	</configuration>
	<executions>
		<execution>
			<id>enhancer</id>
			<phase>process-classes</phase>
			<goals>
				<goal>enhance</goal>
			</goals>
		</execution>
	</executions>
</plugin>

Ostatnim pluginem, który wykorzystam w mojej aplikacji jest plugin umożliwiający tworzenie wersji nadających się do rozpowszechnienia

<plugin>
	<artifactId>maven-assembly-plugin</artifactId>
	<version>2.2-beta-2</version>
	<configuration>
		<descriptor>src/main/assembly/src.xml</descriptor>
	</configuration>
</plugin>

jak widać wtyczka ta potrzebuje jeszcze odpowiednio napisanego pliku deskryptora, u mnie wygląda on mniej więcej tak

<assembly>
	<id>bin</id>
	<formats>
		<format>zip</format>
	</formats>
	<fileSets>
		<fileSet>
			<directory>target</directory>
			<outputDirectory>/</outputDirectory>
			<includes>
				<include>*.jar</include>
			</includes>
		</fileSet>
	</fileSets>

	<dependencySets>
		<dependencySet>
			<outputDirectory>/lib</outputDirectory>
			<includes>
				<include>*:jar</include>
			</includes>
		</dependencySet>
	</dependencySets>
</assembly>

w 4 linijce podane jest jakiego formatu ma być plik wynikowy, nastepna sekcja informuje o umieszczenie wszystkich plików z rozszerzeniem jar z folderu target w głównym folderze w archiwum, w dependency dodaje informację o umieszczeniu wszystkich potrzebnych bibliotek w katalogu lib

No i tak dotarliśmy do końca, pozostaje już tylko wywołanie polecenia mvn assembly:assembly, które możemy wykonać z poziomu eclipse, klikamy prawym przyciskiem myszy na nazwie projektu, nastepnie Run As i Maven assembly:assembly i w ten sposób otrzymujemy plik zip z naszym projektem, inną ciekawą opcją mvn assembly jest wywołanie mvn assembly:directory, które od poprzedniego różni się tym iż nie ładuje wszystkiego do pliku zip, który musimy wypadować i dopiero na nim działać, a poprostu zamiast archiwum tworzy folder z jego zawartością.

teraz możemy uruchomić program, np wywołanie
java -jar openjpa-1.0.jar 13 „to jest szczesliwa liczba”
doda do bazy instancję naszej klasa z liczbą 13 i napisem „to jest szczesliwa liczba”, sprawdzić to możemy poprzez wywołanie programu bez parametrów

17 listopada 2009 | JAVA

komentarze 2 do wpisu “OpenJPA + HSQLDB z użyciem Maven2 i Eclipse”

  1. koziolek napisał(a):

    Szybka uwaga co do tworzenia projektu. W Mavenie można użyć zamiast mvn archetype:create polecenia mvn archetype:generate. Mamy możliwość wybrania archetypu, a z utworzonego projektu zawsze można zrobić nowy.

  2. fantom napisał(a):

    Lol, właśnie robię zadanko z powyższego tematu i google mi Cię poleciło, jaki ten świat mały :P a co do artykułu do świetna robota, gratuluję

Zostaw odpowiedź