diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..06fab23769d781a3c7233bc0c51a68aba5993c5c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,18 @@
+# Eclipse
+.classpath
+.project
+.settings/
+ 
+# Intellij
+.idea/
+*.iml
+*.iws
+ 
+# Mac
+.DS_Store
+ 
+# Maven
+log/
+target/
+
+db/
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f81e798564af7e7beadf3c2903c0fda576abecdd
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,150 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>cz.vsb.fei.java2</groupId>
+	<artifactId>lab06</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+
+	<name>lab06</name>
+
+	<packaging>jar</packaging>
+
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<maven.compiler.release>21</maven.compiler.release>
+		<JavaFX.version>22-ea+16</JavaFX.version>
+		<JUnit.version>5.10.1</JUnit.version>
+		<log4j.version>2.22.1</log4j.version>
+		<lombok.version>1.18.30</lombok.version>
+	</properties>
+	<dependencyManagement>
+		<dependencies>
+			<dependency>
+				<groupId>org.junit</groupId>
+				<artifactId>junit-bom</artifactId>
+				<version>${JUnit.version}</version>
+				<type>pom</type>
+				<scope>import</scope>
+			</dependency>
+		</dependencies>
+	</dependencyManagement>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.openjfx</groupId>
+			<artifactId>javafx-controls</artifactId>
+			<version>${JavaFX.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.openjfx</groupId>
+			<artifactId>javafx-fxml</artifactId>
+			<version>${JavaFX.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.junit.jupiter</groupId>
+			<artifactId>junit-jupiter</artifactId>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.logging.log4j</groupId>
+			<artifactId>log4j-core</artifactId>
+			<version>${log4j.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.logging.log4j</groupId>
+			<artifactId>log4j-api</artifactId>
+			<version>${log4j.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.projectlombok</groupId>
+			<artifactId>lombok</artifactId>
+			<version>${lombok.version}</version>
+			<scope>provided</scope>
+		</dependency>
+
+		<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
+		<dependency>
+			<groupId>org.hibernate</groupId>
+			<artifactId>hibernate-core</artifactId>
+			<version>6.4.4.Final</version>
+		</dependency>
+		<dependency>
+			<groupId>org.hibernate</groupId>
+			<artifactId>hibernate-jpamodelgen</artifactId>
+			<scope>provided</scope>
+			<version>6.4.4.Final</version>
+		</dependency>
+
+		<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
+		<dependency>
+			<groupId>com.h2database</groupId>
+			<artifactId>h2</artifactId>
+			<version>2.2.224</version>
+		</dependency>
+
+		<!--
+		https://mvnrepository.com/artifact/jakarta.persistence/jakarta.persistence-api -->
+		<dependency>
+			<groupId>jakarta.persistence</groupId>
+			<artifactId>jakarta.persistence-api</artifactId>
+			<version>3.1.0</version>
+		</dependency>
+
+
+	</dependencies>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>3.12.1</version>
+				<configuration>
+					<annotationProcessorPaths>
+						<path>
+							<groupId>org.projectlombok</groupId>
+							<artifactId>lombok</artifactId>
+							<version>${lombok.version}</version>
+						</path>
+						<path>
+							<groupId>org.hibernate</groupId>
+							<artifactId>hibernate-jpamodelgen</artifactId>
+							<version>6.4.4.Final</version>
+						</path>
+					</annotationProcessorPaths>
+				</configuration>
+				<executions>
+					<execution>
+						<id>process</id>
+						<phase>generate-sources</phase>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<groupId>org.codehaus.mojo</groupId>
+				<artifactId>build-helper-maven-plugin</artifactId>
+				<version>3.5.0</version>
+				<configuration>
+					<sources>
+						<source>target/generated-sources/annotations</source>
+					</sources>
+				</configuration>
+				<executions>
+					<execution>
+						<id>add-source</id>
+						<phase>process-resources</phase>
+						<goals>
+							<goal>add-source</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<artifactId>maven-surefire-plugin</artifactId>
+				<version>3.2.1</version>
+			</plugin>
+		</plugins>
+	</build>
+
+</project>
diff --git a/src/main/java/cz/vsb/fei/java2/lab06/App.java b/src/main/java/cz/vsb/fei/java2/lab06/App.java
new file mode 100644
index 0000000000000000000000000000000000000000..9f04b573bed73a7106e381bfb15d50389fd8c6c9
--- /dev/null
+++ b/src/main/java/cz/vsb/fei/java2/lab06/App.java
@@ -0,0 +1,78 @@
+package cz.vsb.fei.java2.lab06;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.List;
+
+import org.h2.tools.Server;
+
+import cz.vsb.fei.java2.lab06.entities.Car;
+import cz.vsb.fei.java2.lab06.entities.LegalPerson;
+import cz.vsb.fei.java2.lab06.entities.Route;
+import cz.vsb.fei.java2.lab06.entities.Vehicle;
+import cz.vsb.fei.java2.lab06.repositories.PersonRepsository;
+import cz.vsb.fei.java2.lab06.repositories.RouteRepsository;
+import cz.vsb.fei.java2.lab06.repositories.VehicleRepsository;
+import jakarta.persistence.EntityManager;
+import jakarta.persistence.EntityManagerFactory;
+import jakarta.persistence.Persistence;
+import lombok.extern.log4j.Log4j2;
+
+/**
+ * Class <b>App</b> - extends class Application and it is an entry point of the
+ * program
+ * 
+ * @author Java I
+ */
+@Log4j2
+public class App {
+
+	public static void main(String[] args) {
+		log.info("Launching Java application.");
+
+		EntityManagerFactory emf = Persistence.createEntityManagerFactory("java2");
+		EntityManager em = emf.createEntityManager();
+
+		
+		//TODO: Create repositories 
+
+    //TODO: generate vehicles and persons 
+
+		//TODO: add existing person to existing vehicle as owner 
+
+		//TODO: generate new vehicle with new owner  
+
+		//TODO: generate routes and assign vehicles 
+		// clear entity manager cache - start again with clear cache
+		em.clear();
+
+		//TODO: list routes, persons and vehicles
+		
+		em.close();
+		startDBWebServerAndWait();
+	}
+
+	private static void startDBWebServerAndWait() {
+		// Start HTTP server for access H2 DB for look inside
+		try {
+			Server server = Server.createWebServer();
+			log.info(server.getURL());
+			server.start();
+			log.info("Waitnig for Key press (ENTER)");
+			waitForKeyPress();
+			log.info("Ending DB web server BYE.");
+			server.stop();
+		} catch (SQLException e) {
+			log.error("Cannot create DB web server.", e);
+		}
+	}
+
+	private static void waitForKeyPress() {
+		try {
+			System.in.read();
+		} catch (IOException e) {
+			log.error("Cannot read input from keyboard.", e);
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/src/main/java/cz/vsb/fei/java2/lab06/Tools.java b/src/main/java/cz/vsb/fei/java2/lab06/Tools.java
new file mode 100644
index 0000000000000000000000000000000000000000..3ae8635991c4824769817efeed41477d99e4fb2a
--- /dev/null
+++ b/src/main/java/cz/vsb/fei/java2/lab06/Tools.java
@@ -0,0 +1,83 @@
+package cz.vsb.fei.java2.lab06;
+
+import java.time.LocalDate;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+
+public class Tools {
+
+	public static final Random RANDOM = new Random();
+
+	public static final List<String> FIRST_NAMES = Collections
+			.unmodifiableList(Arrays.asList("Petr", "Marie", "Jan", "Jana", "Tomáš", "Kateřina", "Lukáš", "Tereza",
+					"Martin", "Veronika", "David", "Eva", "Jakub", "Lucie", "Michal", "Anna", "Adam", "Monika", "Tom",
+					"Klára", "Robert", "Kristýna", "Marek", "Simona", "Filip", "Petra", "Ondřej", "Lenka", "Matěj",
+					"Markéta", "Pavel", "Hana", "Jakub", "Adéla", "Daniel", "Barbora", "Lukáš", "Eliška", "Josef"));
+	public static final List<String> LAST_NAMES = Collections.unmodifiableList(Arrays.asList("Novák", "Svoboda",
+			"Novotný", "Dvořák", "Černý", "Procházková", "Kučera", "Veselý", "Horák", "Němec", "Pokorný", "Mareš",
+			"Pospíšilová", "Hájek", "Jelínek", "Král", "Růžička", "Beneš", "Fiala", "Sedláček", "Kříž", "Němcová",
+			"Vlček", "Kolář", "Bartoš", "Bílý", "Veselá", "Kovařík", "Havelka", "Malý", "Urban", "Kopecký", "Vlach",
+			"Šimek", "Konečný", "Doležal", "Šťastný", "Kopečná", "Holub", "Pospíchal"));
+
+	public static final List<String> STREETS = Collections.unmodifiableList(
+			Arrays.asList("Panská", "Hlavní", "Ulice Nová", "Náměstí Svobody", "Hřbitovní", "Revoluční", "Sadová",
+					"Jiráskova", "Školní", "Vinohradská", "Komenského", "Mírová", "Křížová", "Masarykova",
+					"Třída Svobody", "Karlova", "Dlouhá", "Žižkova", "Purkyňova", "Rybářská", "Sokolská", "Rybníček",
+					"Vrchlického", "Štefánikova", "Veselá", "Lipová", "Na Hrázi", "Výšinná", "Nová Cesta", "Česká"));
+	public static final List<String> CITIES = Collections.unmodifiableList(
+			Arrays.asList("Praha", "Brno", "Ostrava", "Plzeň", "Liberec", "Olomouc", "České Budějovice",
+					"Hradec Králové", "Ústí nad Labem", "Pardubice", "Zlín", "Karlovy Vary", "Jihlava", "Tábor",
+					"Havířov", "Český Těšín", "Mladá Boleslav", "Trutnov", "Přerov", "Kladno", "Opava", "Frýdek-Místek",
+					"Děčín", "Karviná", "Jablonec nad Nisou", "Třebíč", "Žďár nad Sázavou", "Kolín", "Uherské Hradiště",
+					"Znojmo", "Prostějov", "Litoměřice", "Kroměříž", "Chomutov", "Příbram", "Příbram", "Cheb",
+					"Teplice", "Uherský Brod", "Sokolov", "Břeclav", "Litvínov", "Klatovy", "Vsetín", "Nový Jičín"));
+
+	public static final List<String> POST_NUMBER = Collections
+			.unmodifiableList(Arrays.asList("10000", "11000", "12000", "13000", "14000", "15000", "16000", "17000",
+					"18000", "19000", "20000", "21000", "22000", "23000", "24000", "25000", "26000", "27000", "28000",
+					"29000", "30000", "31000", "32000", "33000", "34000", "35000", "36000", "37000", "38000", "39000"));
+
+	public static final List<String> COMPANY_NAMES = Collections.unmodifiableList(Arrays.asList("Inova", "Sprint",
+			"Polaris", "Forte", "Nexus", "Vertex", "Synergie", "Horizon", "Astra", "Axiom", "Optima", "Integra",
+			"Evolve", "Apex", "Dynasty", "Eclipse", "Paragon", "Fusion", "Oasis", "Equinox", "Voyage", "Genesis",
+			"Zenith", "Elite", "Harmony", "Stratos", "Aurora", "Quantum", "Spectrum"));
+
+	public static String generateCompanyName() {
+		StringBuilder name = new StringBuilder();
+		int numberOfWords = RANDOM.nextInt(2) + 1;
+		for (int j = 0; j < numberOfWords; j++) {
+			name.append(randomElementFrom(COMPANY_NAMES));
+			if (j < numberOfWords - 1) {
+				name.append(" ");
+			}
+		}
+		return name.toString();
+	}
+
+	public static String generateAddress() {
+		return String.format("%s %d, %s, %s", randomElementFrom(STREETS), RANDOM.nextInt(99) + 1,
+				randomElementFrom(CITIES), randomElementFrom(POST_NUMBER));
+	}
+
+	public static <T> T randomElementFrom(List<T> list) {
+		return randomElementFrom(list, RANDOM);
+	}
+
+	public static <T> T randomElementFrom(List<T> list, Random r) {
+		if (list.isEmpty()) {
+			return null;
+		}
+		return list.get(r.nextInt(list.size()));
+	}
+
+	public static LocalDate generatePreviousDate() {
+		return LocalDate.of(LocalDate.now().getYear() - RANDOM.nextInt(80), RANDOM.nextInt(12) + 1, 1)
+				.plusDays(RANDOM.nextInt(31));
+	}
+
+	private Tools() {
+		/* hide public one - nothing to do */
+	}
+}
diff --git a/src/main/java/cz/vsb/fei/java2/lab06/entities/BaseEntity.java b/src/main/java/cz/vsb/fei/java2/lab06/entities/BaseEntity.java
new file mode 100644
index 0000000000000000000000000000000000000000..1156a706f76fe20e0ee378a2046142c6689ae62f
--- /dev/null
+++ b/src/main/java/cz/vsb/fei/java2/lab06/entities/BaseEntity.java
@@ -0,0 +1,26 @@
+package cz.vsb.fei.java2.lab06.entities;
+
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.MappedSuperclass;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.ToString;
+
+/**
+ * Implementation of design pattern layer supertype
+ * https://martinfowler.com/eaaCatalog/layerSupertype.html
+ */
+@EqualsAndHashCode(onlyExplicitlyIncluded = true)
+@ToString
+@MappedSuperclass
+public abstract class BaseEntity {
+
+	@EqualsAndHashCode.Include
+	@Getter
+	@Id
+	@GeneratedValue(strategy = GenerationType.AUTO)
+	private Long id;
+
+}
diff --git a/src/main/java/cz/vsb/fei/java2/lab06/entities/Car.java b/src/main/java/cz/vsb/fei/java2/lab06/entities/Car.java
new file mode 100644
index 0000000000000000000000000000000000000000..9d021181387dfbd4c28422e9908da69554644b2f
--- /dev/null
+++ b/src/main/java/cz/vsb/fei/java2/lab06/entities/Car.java
@@ -0,0 +1,68 @@
+package cz.vsb.fei.java2.lab06.entities;
+
+import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.DESTINATION;
+import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.START;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Random;
+import java.util.stream.Collectors;
+
+import cz.vsb.fei.java2.lab06.Tools;
+import cz.vsb.fei.java2.lab06.entities.Route.RoutePartType;
+import jakarta.persistence.Entity;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+
+@Getter
+@Setter
+@ToString(callSuper = true)
+public class Car extends Vehicle {
+
+	private static final List<String> COLORS = Collections.unmodifiableList((Arrays.asList("Černá perla",
+			"Diamantová bílá", "Lunární stříbro", "Kosmická šedá", "Azure modrá", "Rubinová červená",
+			"Smaragdově zelená", "Kávová krémová", "Sluneční oranžová", "Zlatá svítilna", "Ametystová fialová",
+			"Růžová sváteční", "Temná oceánská modř", "Měsíčně šedá", "Žárivě rudá", "Lesklá zelená",
+			"Hluboká čokoládová", "Myslínská oranžová", "Sluneční žlutá", "Šeříkově fialová")));
+
+	private int numberOfSeats;
+	private String color;
+
+	@Override
+	public String planeRoute(String start, String destination) {
+		List<RoutePartType> route = new ArrayList<>();
+		Random r = new Random(Objects.hash(start, destination));
+		int count = r.nextInt(20) + 5;
+		route.add(START);
+		List<RoutePartType> parts = new ArrayList<>(Arrays.asList(RoutePartType.values()));
+		parts.remove(START);
+		parts.remove(DESTINATION);
+		for (int i = 0; i < count; i++) {
+			route.add(parts.get(r.nextInt(parts.size())));
+		}
+		route.add(DESTINATION);
+		return route.stream().map(RoutePartType::getSign).collect(Collectors.joining());
+	}
+
+	@Override
+	public boolean isRouteAcceptable(String routeDescription) {
+		return true;
+	}
+
+	public Car(String registartionNumber, int maxSpeed, String producerName, int numberOfSeats, String color) {
+		super(registartionNumber, maxSpeed, producerName);
+		this.numberOfSeats = numberOfSeats;
+		this.color = color;
+	}
+
+	public static Car generate() {
+		return new Car(generateRegistrationNumber(), Tools.RANDOM.nextInt(100) + 120,
+				Tools.randomElementFrom(PRODUCERS), Tools.RANDOM.nextInt(5) + 2, Tools.randomElementFrom(COLORS));
+	}
+
+}
diff --git a/src/main/java/cz/vsb/fei/java2/lab06/entities/JuridicalPerson.java b/src/main/java/cz/vsb/fei/java2/lab06/entities/JuridicalPerson.java
new file mode 100644
index 0000000000000000000000000000000000000000..67bf5d793df970ea417c0c67c09723a6982b80fb
--- /dev/null
+++ b/src/main/java/cz/vsb/fei/java2/lab06/entities/JuridicalPerson.java
@@ -0,0 +1,46 @@
+package cz.vsb.fei.java2.lab06.entities;
+
+import java.util.Arrays;
+
+import cz.vsb.fei.java2.lab06.Tools;
+import jakarta.persistence.Entity;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+
+@Getter
+@Setter
+@ToString(callSuper = true)
+public class JuridicalPerson extends LegalPerson {
+
+	private String companyName;
+	private CompanyType type;
+
+	public JuridicalPerson(String companyName, String address, CompanyType type) {
+		super(address);
+		this.companyName = companyName;
+		this.type = type;
+	}
+
+	@AllArgsConstructor
+	@Getter
+	public enum CompanyType {
+		SPOLECNOST_S_RUCENIM_OMEYENZM("s.r.o."), AKCIOVA_SPOLECNOST("a.s."), ZAPSANY_SPOLEK("z.s."),
+		KOMANDITNI_SPOLECNOST("k.s."), VEREJNA_OBCHODNI_SPOLECNOST("v.o.s."), EVROPSKA_AKCIOVA_SPOLECNOST("SE");
+
+		private String description;
+	}
+
+	@Override
+	public String getFullName() {
+		return String.format("%s %s", getCompanyName(), getType().getDescription());
+	}
+
+	public static JuridicalPerson generate() {
+		return new JuridicalPerson(Tools.generateCompanyName(), Tools.generateAddress(),
+				Tools.randomElementFrom(Arrays.asList(CompanyType.values())));
+	}
+
+}
diff --git a/src/main/java/cz/vsb/fei/java2/lab06/entities/LegalPerson.java b/src/main/java/cz/vsb/fei/java2/lab06/entities/LegalPerson.java
new file mode 100644
index 0000000000000000000000000000000000000000..c35daad7566fe46493bb4bd19894e7a7e6374df7
--- /dev/null
+++ b/src/main/java/cz/vsb/fei/java2/lab06/entities/LegalPerson.java
@@ -0,0 +1,36 @@
+package cz.vsb.fei.java2.lab06.entities;
+
+import java.util.Set;
+
+import cz.vsb.fei.java2.lab06.Tools;
+import jakarta.persistence.Entity;
+import jakarta.persistence.OneToMany;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+
+@Getter
+@Setter
+@ToString(callSuper = true)
+public abstract class LegalPerson extends BaseEntity {
+
+	private String address;
+
+	@ToString.Exclude
+	private Set<Vehicle> ownedVewhicles;
+
+	protected LegalPerson(String address) {
+		this.address = address;
+	}
+
+	public abstract String getFullName();
+
+	public static LegalPerson generate() {
+		if (Tools.RANDOM.nextBoolean()) {
+			return JuridicalPerson.generate();
+		} else {
+			return NaturalPerson.generate();
+		}
+	}
+}
diff --git a/src/main/java/cz/vsb/fei/java2/lab06/entities/Motorbike.java b/src/main/java/cz/vsb/fei/java2/lab06/entities/Motorbike.java
new file mode 100644
index 0000000000000000000000000000000000000000..14d6074425409da3a81c84c3d4b5cc2d76353825
--- /dev/null
+++ b/src/main/java/cz/vsb/fei/java2/lab06/entities/Motorbike.java
@@ -0,0 +1,71 @@
+package cz.vsb.fei.java2.lab06.entities;
+
+import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.CROSSROAD;
+import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.DESTINATION;
+import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.SPEED_UP;
+import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.*;
+import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.START;
+import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.STRAIGHT;
+import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.TURN_LEFT;
+import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.TURN_RIGHT;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Random;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import cz.vsb.fei.java2.lab06.Tools;
+import cz.vsb.fei.java2.lab06.entities.Route.RoutePartType;
+import jakarta.persistence.Entity;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+
+@Getter
+@Setter
+@ToString(callSuper = true)
+public class Motorbike extends Vehicle {
+
+	private boolean storageBox;
+
+	private static Set<RoutePartType> allowedRouteParts = Collections.unmodifiableSet(new HashSet<>(Arrays
+			.asList(SLOW_DOWN, SPEED_UP, ROUNDABOUT, CROSSROAD, DESTINATION, START, STRAIGHT, TURN_LEFT, TURN_RIGHT)));
+
+	public Motorbike(String registartionNumber, int maxSpeed, String producerName, boolean storageBox) {
+		super(registartionNumber, maxSpeed, producerName);
+		this.storageBox = storageBox;
+	}
+
+	@Override
+	public String planeRoute(String start, String destination) {
+		List<RoutePartType> route = new ArrayList<>();
+		Random r = new Random(Objects.hash(start, destination));
+		int count = r.nextInt(30) + 8;
+		route.add(START);
+		List<RoutePartType> parts = Arrays.asList(CROSSROAD, SPEED_UP, SPEED_UP, SPEED_UP, SPEED_UP, SPEED_UP, SPEED_UP,
+				SPEED_UP, SPEED_UP, STRAIGHT, STRAIGHT, STRAIGHT, STRAIGHT, STRAIGHT, STRAIGHT, STRAIGHT, STRAIGHT,
+				STRAIGHT, STRAIGHT, STRAIGHT, STRAIGHT, STRAIGHT, TURN_LEFT, TURN_RIGHT);
+		for (int i = 0; i < count; i++) {
+			route.add(Tools.randomElementFrom(parts, r));
+		}
+		route.add(DESTINATION);
+		return route.stream().map(RoutePartType::getSign).collect(Collectors.joining());
+	}
+
+	@Override
+	public boolean isRouteAcceptable(String routeDescription) {
+		return RoutePartType.parse(routeDescription).stream().allMatch(part -> allowedRouteParts.contains(part));
+	}
+
+	public static Motorbike generateMotorbike() {
+		return new Motorbike(generateRegistrationNumber(), Tools.RANDOM.nextInt(150) + 180,
+				Tools.randomElementFrom(PRODUCERS), Tools.RANDOM.nextBoolean());
+	}
+
+}
diff --git a/src/main/java/cz/vsb/fei/java2/lab06/entities/NaturalPerson.java b/src/main/java/cz/vsb/fei/java2/lab06/entities/NaturalPerson.java
new file mode 100644
index 0000000000000000000000000000000000000000..4f4cc520786b8d40f560bcf5251a536f4a2cf8ea
--- /dev/null
+++ b/src/main/java/cz/vsb/fei/java2/lab06/entities/NaturalPerson.java
@@ -0,0 +1,42 @@
+package cz.vsb.fei.java2.lab06.entities;
+
+import java.time.LocalDate;
+
+import cz.vsb.fei.java2.lab06.Tools;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+
+@Getter
+@Setter
+@ToString(callSuper = true)
+public class NaturalPerson extends LegalPerson {
+
+  @Column(nullable = false)
+	private String firstName;
+  @Column(nullable = false)
+	private String lastName;
+
+	private LocalDate dayOfBirth;
+
+	public NaturalPerson(String firstName, String lastName, String address, LocalDate dayOfBirth) {
+		super(address);
+		this.firstName = firstName;
+		this.lastName = lastName;
+		this.dayOfBirth = dayOfBirth;
+	}
+
+	@Override
+	public String getFullName() {
+		return String.format("%s %s", getFirstName(), getLastName());
+	}
+
+	public static NaturalPerson generate() {
+		return new NaturalPerson(Tools.randomElementFrom(Tools.FIRST_NAMES), Tools.randomElementFrom(Tools.LAST_NAMES),
+				Tools.generateAddress(), Tools.generatePreviousDate());
+	}
+
+}
diff --git a/src/main/java/cz/vsb/fei/java2/lab06/entities/Route.java b/src/main/java/cz/vsb/fei/java2/lab06/entities/Route.java
new file mode 100644
index 0000000000000000000000000000000000000000..d9d126790a04b9b4f8a7cef2772ad86b3acc57a4
--- /dev/null
+++ b/src/main/java/cz/vsb/fei/java2/lab06/entities/Route.java
@@ -0,0 +1,60 @@
+package cz.vsb.fei.java2.lab06.entities;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import cz.vsb.fei.java2.lab06.Tools;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.ManyToMany;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+
+@Getter
+@Setter
+@AllArgsConstructor
+@ToString(callSuper = true)
+public class Route extends BaseEntity {
+
+	private String start;
+	private String destination;
+	private String description;
+
+	private List<Vehicle> assignedCars;
+
+	public static Route generate() {
+		return new Route(Tools.randomElementFrom(Tools.CITIES), Tools.randomElementFrom(Tools.CITIES), null,
+				new ArrayList<Vehicle>());
+	}
+
+	@AllArgsConstructor
+	@Getter
+	public enum RoutePartType {
+		START("↦"), STRAIGHT("➙"), TURN_LEFT("⬏"), TURN_RIGHT("↴"), U_TURN("⮌"), CROSSROAD("⤨"), ROUNDABOUT("⥁"),
+		SLOW_DOWN("⇝"), SPEED_UP("↠"), DESTINATION("⇥");
+
+		private String sign;
+
+		public static RoutePartType of(String part) {
+			for (RoutePartType type : values()) {
+				if (Objects.equals(type.getSign(), part)) {
+					return type;
+				}
+			}
+			return null;
+		}
+
+		public static List<RoutePartType> parse(String s) {
+			List<RoutePartType> result = new ArrayList<>(s.length());
+			for (int i = 0; i < s.length(); i++) {
+				result.add(of(String.valueOf(s.charAt(i))));
+			}
+			return result;
+		}
+	}
+
+}
diff --git a/src/main/java/cz/vsb/fei/java2/lab06/entities/Truck.java b/src/main/java/cz/vsb/fei/java2/lab06/entities/Truck.java
new file mode 100644
index 0000000000000000000000000000000000000000..913d58770c1709610df701673d4e92122fcd80f4
--- /dev/null
+++ b/src/main/java/cz/vsb/fei/java2/lab06/entities/Truck.java
@@ -0,0 +1,71 @@
+package cz.vsb.fei.java2.lab06.entities;
+
+import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.CROSSROAD;
+import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.DESTINATION;
+import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.SLOW_DOWN;
+import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.START;
+import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.STRAIGHT;
+import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.TURN_LEFT;
+import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.TURN_RIGHT;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Random;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import cz.vsb.fei.java2.lab06.Tools;
+import cz.vsb.fei.java2.lab06.entities.Route.RoutePartType;
+import jakarta.persistence.Entity;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+
+@Getter
+@Setter
+@ToString(callSuper = true)
+public class Truck extends Vehicle {
+
+	private static Set<RoutePartType> allowedRouteParts = Collections.unmodifiableSet(
+			new HashSet<>(Arrays.asList(SLOW_DOWN, CROSSROAD, DESTINATION, START, STRAIGHT, TURN_LEFT, TURN_RIGHT)));
+
+	private int maxLoadVolume;
+	private int maxLoadWeight;
+
+	public Truck(String registartionNumber, int maxSpeed, String producerName, int maxLoadVolume, int maxLoadWeight) {
+		super(registartionNumber, maxSpeed, producerName);
+		this.maxLoadVolume = maxLoadVolume;
+		this.maxLoadWeight = maxLoadWeight;
+	}
+
+	@Override
+	public String planeRoute(String start, String destination) {
+		List<RoutePartType> route = new ArrayList<>();
+		Random r = new Random(Objects.hash(start, destination));
+		int count = r.nextInt(30) + 8;
+		route.add(START);
+		List<RoutePartType> parts = Arrays.asList(CROSSROAD, SLOW_DOWN, STRAIGHT, STRAIGHT, STRAIGHT, STRAIGHT,
+				STRAIGHT, TURN_LEFT, TURN_LEFT, TURN_LEFT, TURN_RIGHT, TURN_RIGHT, TURN_RIGHT);
+		for (int i = 0; i < count; i++) {
+			route.add(Tools.randomElementFrom(parts, r));
+		}
+		route.add(DESTINATION);
+		return route.stream().map(RoutePartType::getSign).collect(Collectors.joining());
+	}
+
+	@Override
+	public boolean isRouteAcceptable(String routeDescription) {
+		return RoutePartType.parse(routeDescription).stream().allMatch(part -> allowedRouteParts.contains(part));
+	}
+
+	public static Truck generate() {
+		return new Truck(generateRegistrationNumber(), Tools.RANDOM.nextInt(100) + 80,
+				Tools.randomElementFrom(PRODUCERS), Tools.RANDOM.nextInt(500), Tools.RANDOM.nextInt(1000));
+	}
+
+}
diff --git a/src/main/java/cz/vsb/fei/java2/lab06/entities/Vehicle.java b/src/main/java/cz/vsb/fei/java2/lab06/entities/Vehicle.java
new file mode 100644
index 0000000000000000000000000000000000000000..b8b0c7485d2bf0e93393857dcddd575b5f0c2938
--- /dev/null
+++ b/src/main/java/cz/vsb/fei/java2/lab06/entities/Vehicle.java
@@ -0,0 +1,68 @@
+package cz.vsb.fei.java2.lab06.entities;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import cz.vsb.fei.java2.lab06.Tools;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.ManyToMany;
+import jakarta.persistence.ManyToOne;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+
+@Getter
+@Setter
+@ToString(callSuper = true)
+public abstract class Vehicle extends BaseEntity {
+
+	protected static final List<String> PRODUCERS = Collections.unmodifiableList(Arrays.asList("Toyota", "Volkswagen",
+			"BMW", "Mercedes-Benz", "Ford", "Audi", "Honda", "Chevrolet", "Nissan", "Hyundai", "Kia", "Tesla", "Subaru",
+			"Mazda", "Fiat", "Volvo", "Peugeot", "Renault", "Porsche", "Jaguar", "Land Rover", "Mitsubishi", "Suzuki",
+			"Citroën", "Dodge", "Jeep", "Chrysler", "Lexus", "Infiniti", "Acura", "Buick", "Cadillac", "Lincoln", "GMC",
+			"Alfa Romeo", "Mini", "Smart", "Dacia", "Seat", "Ĺ koda"));
+
+	protected String registartionNumber;
+
+	private int maxSpeed;
+
+	private String producerName;
+
+	private LegalPerson owner;
+
+	@ToString.Exclude
+	private List<Route> planedRoute;
+
+	protected Vehicle(String registartionNumber, int maxSpeed, String producerName) {
+		super();
+		this.registartionNumber = registartionNumber;
+		this.maxSpeed = maxSpeed;
+		this.producerName = producerName;
+	}
+
+	public abstract String planeRoute(String start, String destination);
+
+	public abstract boolean isRouteAcceptable(String routeDescription);
+
+	public static String generateRegistrationNumber() {
+		return String.format("%d%c%d-%04d", Tools.RANDOM.nextInt(9) + 1, Tools.RANDOM.nextInt('Z' - 'A') + 'A',
+				Tools.RANDOM.nextInt(9) + 1, Tools.RANDOM.nextInt(9999) + 1);
+	}
+
+	public static Vehicle generate() {
+		switch (Tools.RANDOM.nextInt(3)) {
+		case 0:
+			return Car.generate();
+		case 1:
+			return Truck.generate();
+		case 2:
+			return Motorbike.generateMotorbike();
+		default:
+			return null;
+		}
+	}
+}
diff --git a/src/main/java/cz/vsb/fei/java2/lab06/repositories/BaseRepository.java b/src/main/java/cz/vsb/fei/java2/lab06/repositories/BaseRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..42e64c115cb74c6674372f15a0713367040613a2
--- /dev/null
+++ b/src/main/java/cz/vsb/fei/java2/lab06/repositories/BaseRepository.java
@@ -0,0 +1,51 @@
+package cz.vsb.fei.java2.lab06.repositories;
+
+import java.util.List;
+
+import cz.vsb.fei.java2.lab06.entities.BaseEntity;
+import jakarta.persistence.EntityManager;
+
+public class BaseRepository<T extends BaseEntity> {
+
+	protected EntityManager em;
+	private Class<T> clazz;
+
+	public BaseRepository(EntityManager em, Class<T> clazz) {
+		this.em = em;
+		this.clazz = clazz;
+	}
+
+	public T find(Long id) {
+		return em.find(clazz, id);
+	}
+
+	public List<T> findAll() {
+		return em.createQuery(String.format("SELECT e FROM %s e", clazz.getName()), clazz).getResultList();
+	}
+
+	public T saveInTranasction(T entity) {
+		em.getTransaction().begin();
+		entity = save(entity);
+		em.getTransaction().commit();
+		return entity;
+	}
+
+	public T save(T entity) {
+		if (entity.getId() == null || entity.getId() == 0) {
+			em.persist(entity);
+		} else {
+			entity = em.merge(entity);
+		}
+		return entity;
+	}
+
+	public void remove(T entity) {
+		em.remove(entity);
+	}
+
+	public void removeInTransaction(T entity) {
+		em.getTransaction().begin();
+		remove(entity);
+		em.getTransaction().commit();
+	}
+}
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..d7baa2d08767ddf0ae7031cdf9f10e312da876e5
--- /dev/null
+++ b/src/main/java/module-info.java
@@ -0,0 +1,15 @@
+module cz.vsb.fei.java2.lab05 {
+    requires transitive javafx.controls;
+    requires javafx.fxml;
+    opens cz.vsb.fei.java2.lab06 to javafx.fxml;
+    exports cz.vsb.fei.java2.lab06;
+
+    requires static lombok;
+    requires org.apache.logging.log4j;
+    
+    requires jakarta.persistence;
+    requires jakarta.annotation;
+    requires com.h2database;
+    opens cz.vsb.fei.java2.lab06.entities;
+    requires org.hibernate.orm.core;
+}
\ No newline at end of file
diff --git a/src/main/resources/META-INF/persistence.xml b/src/main/resources/META-INF/persistence.xml
new file mode 100644
index 0000000000000000000000000000000000000000..010c3ffcca548866c2185ec1c96eaaf19b264c5c
--- /dev/null
+++ b/src/main/resources/META-INF/persistence.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- JBoss, Home of Professional Open Source Copyright 2013, Red Hat, Inc. 
+	and/or its affiliates, and individual contributors by the @authors tag. See 
+	the copyright.txt in the distribution for a full listing of individual contributors. 
+	Licensed under the Apache License, Version 2.0 (the "License"); you may not 
+	use this file except in compliance with the License. You may obtain a copy 
+	of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required 
+	by applicable law or agreed to in writing, software distributed under the 
+	License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 
+	OF ANY KIND, either express or implied. See the License for the specific 
+	language governing permissions and limitations under the License. -->
+<persistence version="2.0"
+	xmlns="http://java.sun.com/xml/ns/persistence"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="
+        http://java.sun.com/xml/ns/persistence
+        http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
+	<persistence-unit name="java2"
+		transaction-type="RESOURCE_LOCAL">
+		<!-- <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> -->
+
+		<!-- If you are running in a production environment, add a managed data 
+			source, this example data source is just for development and testing! -->
+		<properties>
+			<!-- Properties for JPA (for any provider) -->
+			<!-- DB Apache Derby <property name="jakarta.persistence.jdbc.url" value="jdbc:derby:db/lab05;create=true" 
+				/> <property name="jakarta.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" 
+				/> -->
+
+			<property name="jakarta.persistence.jdbc.url"
+				value="jdbc:h2:file:./db/java2" />
+			<!-- In memory DB no store to disk <property name="jakarta.persistence.jdbc.url" 
+				value="jdbc:h2:mem:java2" /> -->
+			<property name="jakarta.persistence.jdbc.driver"
+				value="org.h2.Driver" />
+
+			<property name="jakarta.persistence.jdbc.user" value="app" />
+			<property name="jakarta.persistence.jdbc.password"
+				value="app" />
+			<property
+				name="jakarta.persistence.schema-generation.database.action"
+				value="create"></property>
+
+			<!-- Properties for Hibernate -->
+			<!-- property name="hibernate.enable_lazy_load_no_trans"
+				value="true" /-->
+			<property name="hibernate.show_sql" value="false" />
+			<property name="hibernate.format_sql" value="true" />
+			<!-- <property name="hibernate.hbm2ddl.auto" value="update" /> -->
+
+		</properties>
+	</persistence-unit>
+
+</persistence>
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
new file mode 100644
index 0000000000000000000000000000000000000000..acb3514078f6fb73f4f09ffd7a172b47f184e961
--- /dev/null
+++ b/src/main/resources/log4j2.xml
@@ -0,0 +1,13 @@
+<Configuration>
+	<Appenders>
+		<Console name="Console">
+			<PatternLayout
+				pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
+		</Console>
+	</Appenders>
+	<Loggers>
+		<Root level="info">
+			<AppenderRef ref="Console"></AppenderRef>
+		</Root>
+	</Loggers>
+</Configuration>
diff --git a/src/test/java/cz/vsb/fei/java2/lab06/AppTest.java b/src/test/java/cz/vsb/fei/java2/lab06/AppTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..7203982548d688f8fee68e8cefa3a55be91cfb9b
--- /dev/null
+++ b/src/test/java/cz/vsb/fei/java2/lab06/AppTest.java
@@ -0,0 +1,19 @@
+package cz.vsb.fei.java2.lab06;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * Unit test for simple App.
+ */
+class AppTest {
+
+	/**
+	 * Rigorous Test :-)
+	 */
+	@Test
+	void shouldAnswerWithTrue() {
+		assertTrue(true);
+	}
+}