Skip to content

Commit

Permalink
v2: Use H2 and Hibernate in backend module. Refactor UI Unit Tests to…
Browse files Browse the repository at this point in the history
… be side effect free.
  • Loading branch information
TatuJLund committed Oct 1, 2024
1 parent 78c4f4b commit 607bbc2
Show file tree
Hide file tree
Showing 43 changed files with 1,118 additions and 604 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<groupId>org.vaadin.tatu</groupId>
<artifactId>vaadincreate-root</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<version>2.0-SNAPSHOT</version>
<name>VaadinCreate 23 Root Project</name>

<prerequisites>
Expand Down
13 changes: 12 additions & 1 deletion vaadincreate-backend/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<artifactId>vaadincreate-root</artifactId>
<groupId>org.vaadin.tatu</groupId>
<version>1.0-SNAPSHOT</version>
<version>2.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down Expand Up @@ -35,6 +35,17 @@
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.6.0.Final</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.3.232</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.vaadin.tatu.vaadincreate.backend;

import org.vaadin.tatu.vaadincreate.backend.data.Message;
import org.vaadin.tatu.vaadincreate.backend.mock.MockAppDataService;
import org.vaadin.tatu.vaadincreate.backend.service.AppDataServiceImpl;

public interface AppDataService {

Expand All @@ -10,7 +10,7 @@ public interface AppDataService {
public abstract Message getMessage();

public static AppDataService get() {
return MockAppDataService.getInstance();
return AppDataServiceImpl.getInstance();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@

import org.vaadin.tatu.vaadincreate.backend.data.Category;
import org.vaadin.tatu.vaadincreate.backend.data.Product;
import org.vaadin.tatu.vaadincreate.backend.mock.MockProductDataService;
import org.vaadin.tatu.vaadincreate.backend.service.ProductDataServiceImpl;

/**
* Back-end service interface for retrieving and updating product data.
*/
public abstract class ProductDataService {
public interface ProductDataService {

/**
* Get all Products in the database.
Expand Down Expand Up @@ -46,7 +46,7 @@ public abstract class ProductDataService {
* @throws IllegalArgumentException
* if product did not exists
*/
public abstract void deleteProduct(int productId);
public abstract void deleteProduct(Integer productId);

/**
* Find a Product from database using id
Expand All @@ -55,7 +55,7 @@ public abstract class ProductDataService {
* id of the Product
* @return Product if it was found, otherwise null
*/
public abstract Product getProductById(int productId);
public abstract Product getProductById(Integer productId);

/**
* Saves a new category or updates an existing one.
Expand All @@ -72,7 +72,7 @@ public abstract class ProductDataService {
* @param categoryId
* the ID of the category to delete
*/
public abstract void deleteCategory(int categoryId);
public abstract void deleteCategory(Integer categoryId);

/**
* Find categories by their ids.
Expand Down Expand Up @@ -102,22 +102,7 @@ public abstract class ProductDataService {
*/
public abstract Product findDraft(String userName);

/**
* Only to be used in the tests.
*
* @return Products
*/
public abstract Collection<Product> backup();

/**
* Only to be used in the tests.
*
* @param data
* Products
*/
public abstract void restore(Collection<Product> data);

public static ProductDataService get() {
return MockProductDataService.getInstance();
return ProductDataServiceImpl.getInstance();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import java.util.Optional;

import org.vaadin.tatu.vaadincreate.backend.data.User;
import org.vaadin.tatu.vaadincreate.backend.mock.MockUserService;
import org.vaadin.tatu.vaadincreate.backend.service.UserServiceImpl;

public interface UserService {

Expand All @@ -14,12 +14,12 @@ public interface UserService {

public abstract List<User> getAllUsers();

public static UserService get() {
return MockUserService.getInstance();
}
public User getUserById(Integer userId);

public User getUserById(int userId);
void removeUser(Integer userId);

void removeUser(int userId);
public static UserService get() {
return UserServiceImpl.getInstance();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package org.vaadin.tatu.vaadincreate.backend.dao;

import java.util.function.Consumer;
import java.util.function.Function;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

/**
* Utility class for managing Hibernate sessions and transactions.
*/
public class HibernateUtil {

// Private constructor to prevent instantiation
private HibernateUtil() {
throw new UnsupportedOperationException("Utility class");
}

private static SessionFactory sessionFactory;

static {
try {
sessionFactory = new Configuration().configure()
.buildSessionFactory();
} catch (Exception ex) {
throw new ExceptionInInitializerError(ex);
}
}

/**
* Retrieves the singleton instance of the SessionFactory.
*
* @return the SessionFactory instance used for creating Hibernate sessions.
*/
public static SessionFactory getSessionFactory() {
return sessionFactory;
}

/**
* Executes a function within a database transaction.
*
* @param <T>
* The type of the result returned by the transaction function.
* @param transaction
* A function that takes a Hibernate {@link Session} and returns
* a result.
* @return The result of the transaction function.
* @throws Exception
* if the transaction fails and is rolled back.
*/
public static <T> T inTransaction(Function<Session, T> transaction) {
var session = getSessionFactory().openSession();
var tx = session.beginTransaction();
T result;
try {
result = transaction.apply(session);
tx.commit();
} catch (Exception e) {
tx.rollback();
throw e;
} finally {
session.close();
}
return result;
}

/**
* Executes a given transaction within a Hibernate session.
* <p>
* This method opens a new session, begins a transaction, and executes the
* provided {@link Consumer} with the session. If the transaction is
* successful, it commits the transaction. If an exception occurs, it rolls
* back the transaction and rethrows the exception. The session is closed in
* the finally block to ensure it is always closed.
*
* @param transaction
* the {@link Consumer} that contains the operations to be
* performed within the transaction
* @throws Exception
* if an error occurs during the transaction, it is propagated
* after rolling back the transaction
*/
public static void inTransaction(Consumer<Session> transaction) {
var session = getSessionFactory().openSession();
var tx = session.beginTransaction();
try {
transaction.accept(session);
tx.commit();
} catch (Exception e) {
tx.rollback();
throw e;
} finally {
session.close();
}
}

/**
* Executes a task within a Hibernate session and ensures the session is
* closed after the task is completed.
*
* @param <T>
* The type of the result returned by the task.
* @param task
* A function that takes a Hibernate {@link Session} and returns
* a result of type T.
* @return The result of the task.
*/
public static <T> T inSession(Function<Session, T> task) {
T result;
var session = getSessionFactory().openSession();
try {
result = task.apply(session);
} finally {
session.close();
}
return result;
}

/**
* Executes a task within a Hibernate session. The session is opened before
* the task is executed and closed after the task completes, ensuring proper
* resource management.
*
* @param task
* a {@link Consumer} that accepts a {@link Session} and performs
* operations within that session.
*/
public static void inSession(Consumer<Session> task) {
var session = getSessionFactory().openSession();
try {
task.accept(session);
} finally {
session.close();
}
}
}
Loading

0 comments on commit 607bbc2

Please sign in to comment.