From e38839697aee33ca75d01584d1e21fb65c1d442a Mon Sep 17 00:00:00 2001 From: Andrey Chertykovtsev Date: Tue, 30 Jul 2024 11:45:52 +0200 Subject: [PATCH 1/4] Add Hibernate integration and Movie entity setup - Configured Hibernate with MySQL and HSQLDB, and updated dependencies in `pom.xml`. - Implemented `Movie` entity, DAOs, and service layers - Added utility classes and example property files for database connectivity. --- .gitignore | 1 + mem.log | 0 mem.properties | 5 ++ mem.script | 46 +++++++++++++++ pom.xml | 14 ++++- src/main/java/mate/academy/Main.java | 28 +++++++++ src/main/java/mate/academy/dao/MovieDao.java | 10 ++++ .../java/mate/academy/dao/MovieDaoImpl.java | 45 +++++++++++++++ src/main/java/mate/academy/entity/Movie.java | 57 +++++++++++++++++++ .../exception/DataProcessingException.java | 7 +++ .../mate/academy/service/MovieService.java | 9 +++ .../academy/service/MovieServiceImpl.java | 22 +++++++ .../java/mate/academy/util/HibernateUtil.java | 38 +++++++++++++ .../mate/academy/util/PropertiesUtil.java | 32 +++++++++++ .../resources/application.properties.example | 2 + src/main/resources/hibernate.cfg.xml | 16 ++++++ 16 files changed, 330 insertions(+), 2 deletions(-) create mode 100644 mem.log create mode 100644 mem.properties create mode 100644 mem.script create mode 100644 src/main/java/mate/academy/dao/MovieDao.java create mode 100644 src/main/java/mate/academy/dao/MovieDaoImpl.java create mode 100644 src/main/java/mate/academy/entity/Movie.java create mode 100644 src/main/java/mate/academy/exception/DataProcessingException.java create mode 100644 src/main/java/mate/academy/service/MovieService.java create mode 100644 src/main/java/mate/academy/service/MovieServiceImpl.java create mode 100644 src/main/java/mate/academy/util/HibernateUtil.java create mode 100644 src/main/java/mate/academy/util/PropertiesUtil.java create mode 100644 src/main/resources/application.properties.example create mode 100644 src/main/resources/hibernate.cfg.xml diff --git a/.gitignore b/.gitignore index 6366460f0..65ed00443 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .idea/* *.iml target/* +application.properties diff --git a/mem.log b/mem.log new file mode 100644 index 000000000..e69de29bb diff --git a/mem.properties b/mem.properties new file mode 100644 index 000000000..38a2e1f96 --- /dev/null +++ b/mem.properties @@ -0,0 +1,5 @@ +#HSQL Database Engine 2.7.3 +#Mon Jul 29 15:41:40 CEST 2024 +modified=no +tx_timestamp=28 +version=2.7.3 diff --git a/mem.script b/mem.script new file mode 100644 index 000000000..b31e4d694 --- /dev/null +++ b/mem.script @@ -0,0 +1,46 @@ +SET DATABASE UNIQUE NAME HSQLDB90FEA681B9 +SET DATABASE DEFAULT RESULT MEMORY ROWS 0 +SET DATABASE EVENT LOG LEVEL 0 +SET DATABASE TRANSACTION CONTROL LOCKS +SET DATABASE DEFAULT ISOLATION LEVEL READ COMMITTED +SET DATABASE TRANSACTION ROLLBACK ON CONFLICT TRUE +SET DATABASE TEXT TABLE DEFAULTS '' +SET DATABASE SQL NAMES FALSE +SET DATABASE SQL RESTRICT EXEC FALSE +SET DATABASE SQL REFERENCES FALSE +SET DATABASE SQL SIZE TRUE +SET DATABASE SQL TYPES FALSE +SET DATABASE SQL TDC DELETE TRUE +SET DATABASE SQL TDC UPDATE TRUE +SET DATABASE SQL SYS INDEX NAMES TRUE +SET DATABASE SQL CONCAT NULLS TRUE +SET DATABASE SQL UNIQUE NULLS TRUE +SET DATABASE SQL CONVERT TRUNCATE TRUE +SET DATABASE SQL AVG SCALE 0 +SET DATABASE SQL DOUBLE NAN TRUE +SET FILES WRITE DELAY 500 MILLIS +SET FILES BACKUP INCREMENT TRUE +SET FILES CACHE SIZE 10000 +SET FILES CACHE ROWS 50000 +SET FILES SCALE 32 +SET FILES LOB SCALE 32 +SET FILES DEFRAG 0 +SET FILES NIO TRUE +SET FILES NIO SIZE 256 +SET FILES LOG TRUE +SET FILES LOG SIZE 50 +SET FILES CHECK 28 +SET DATABASE COLLATION "SQL_TEXT" PAD SPACE +CREATE USER "root" PASSWORD DIGEST 'e64dd57aa7a1280ed52e3ca6b6867aef' +ALTER USER "root" SET LOCAL TRUE +CREATE SCHEMA PUBLIC AUTHORIZATION DBA +ALTER SEQUENCE SYSTEM_LOBS.LOB_ID RESTART WITH 1 +SET DATABASE DEFAULT INITIAL SCHEMA PUBLIC +GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.CARDINAL_NUMBER TO PUBLIC +GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.YES_OR_NO TO PUBLIC +GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.CHARACTER_DATA TO PUBLIC +GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.SQL_IDENTIFIER TO PUBLIC +GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.TIME_STAMP TO PUBLIC +GRANT DBA TO "root" +SET SCHEMA SYSTEM_LOBS +INSERT INTO BLOCKS VALUES(0,2147483647,0) diff --git a/pom.xml b/pom.xml index f2dbc0637..27ab08a94 100644 --- a/pom.xml +++ b/pom.xml @@ -20,6 +20,16 @@ + + org.hibernate.orm + hibernate-core + 6.5.2.Final + + + com.mysql + mysql-connector-j + 9.0.0 + org.apache.commons commons-lang3 @@ -28,7 +38,7 @@ junit junit - 4.12 + 4.13.2 test @@ -46,7 +56,7 @@ org.hsqldb hsqldb - 2.3.4 + 2.7.3 diff --git a/src/main/java/mate/academy/Main.java b/src/main/java/mate/academy/Main.java index 0058fbf96..31c3466e0 100644 --- a/src/main/java/mate/academy/Main.java +++ b/src/main/java/mate/academy/Main.java @@ -1,7 +1,35 @@ package mate.academy; +import java.util.List; +import mate.academy.entity.Movie; +import mate.academy.lib.Injector; +import mate.academy.service.MovieService; + public class Main { + private static final Injector injector = Injector.getInstance("mate.academy"); + public static void main(String[] args) { + Movie movie = new Movie(); + movie.setTitle("The Shawshank Redemption"); + movie.setDescription("Best movie ever"); + + Movie movie1 = new Movie(); + movie1.setTitle("Inception"); + movie1.setDescription("Mind-bending movie"); + + Movie movie2 = new Movie(); + movie2.setTitle("The Dark Knight"); + movie2.setDescription("Superhero movie"); + + Movie movie3 = new Movie(); + movie3.setTitle("Interstellar"); + movie3.setDescription("Space exploration movie"); + + List movies = List.of(movie, movie1, movie2, movie3); + + MovieService movieService = (MovieService) injector.getInstance(MovieService.class); + movies.forEach(movieService::add); + System.out.println(movieService.get(1L)); } } diff --git a/src/main/java/mate/academy/dao/MovieDao.java b/src/main/java/mate/academy/dao/MovieDao.java new file mode 100644 index 000000000..05a4541c6 --- /dev/null +++ b/src/main/java/mate/academy/dao/MovieDao.java @@ -0,0 +1,10 @@ +package mate.academy.dao; + +import java.util.Optional; +import mate.academy.entity.Movie; + +public interface MovieDao { + Movie add(Movie movie); + + Optional get(Long id); +} diff --git a/src/main/java/mate/academy/dao/MovieDaoImpl.java b/src/main/java/mate/academy/dao/MovieDaoImpl.java new file mode 100644 index 000000000..eca2452df --- /dev/null +++ b/src/main/java/mate/academy/dao/MovieDaoImpl.java @@ -0,0 +1,45 @@ +package mate.academy.dao; + +import java.util.Optional; +import mate.academy.entity.Movie; +import mate.academy.exception.DataProcessingException; +import mate.academy.lib.Dao; +import mate.academy.util.HibernateUtil; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; + +@Dao +public class MovieDaoImpl implements MovieDao { + @Override + public Movie add(Movie movie) { + Session session = null; + Transaction transaction = null; + try { + session = HibernateUtil.getSessionFactory().openSession(); + transaction = session.beginTransaction(); + session.persist(movie); + transaction.commit(); + } catch (Exception e) { + if (transaction != null) { + transaction.rollback(); + } + throw new DataProcessingException("Can't add new movie: " + movie, e); + } finally { + if (session != null) { + session.close(); + } + } + return movie; + } + + @Override + public Optional get(Long id) { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + try (Session session = sessionFactory.openSession()) { + return Optional.ofNullable(session.get(Movie.class, id)); + } catch (Exception e) { + throw new DataProcessingException("Can't receive a movie with id: " + id, e); + } + } +} diff --git a/src/main/java/mate/academy/entity/Movie.java b/src/main/java/mate/academy/entity/Movie.java new file mode 100644 index 000000000..5c456a6a8 --- /dev/null +++ b/src/main/java/mate/academy/entity/Movie.java @@ -0,0 +1,57 @@ +package mate.academy.entity; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; + +@Entity +public class Movie { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String title; + private String description; + + public Movie() { + } + + public Movie(Long id, String title, String description) { + this.id = id; + this.title = title; + this.description = description; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @Override + public String toString() { + return "Movie{" + + "id=" + id + + ", title='" + title + '\'' + + ", description='" + description + '\'' + + '}'; + } +} diff --git a/src/main/java/mate/academy/exception/DataProcessingException.java b/src/main/java/mate/academy/exception/DataProcessingException.java new file mode 100644 index 000000000..63b937dc4 --- /dev/null +++ b/src/main/java/mate/academy/exception/DataProcessingException.java @@ -0,0 +1,7 @@ +package mate.academy.exception; + +public class DataProcessingException extends RuntimeException { + public DataProcessingException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/mate/academy/service/MovieService.java b/src/main/java/mate/academy/service/MovieService.java new file mode 100644 index 000000000..c8e5ba4c6 --- /dev/null +++ b/src/main/java/mate/academy/service/MovieService.java @@ -0,0 +1,9 @@ +package mate.academy.service; + +import mate.academy.entity.Movie; + +public interface MovieService { + Movie add(Movie movie); + + Movie get(Long id); +} diff --git a/src/main/java/mate/academy/service/MovieServiceImpl.java b/src/main/java/mate/academy/service/MovieServiceImpl.java new file mode 100644 index 000000000..729d4fa11 --- /dev/null +++ b/src/main/java/mate/academy/service/MovieServiceImpl.java @@ -0,0 +1,22 @@ +package mate.academy.service; + +import mate.academy.dao.MovieDao; +import mate.academy.entity.Movie; +import mate.academy.lib.Inject; +import mate.academy.lib.Service; + +@Service +public class MovieServiceImpl implements MovieService { + @Inject + private MovieDao movieDao; + + @Override + public Movie add(Movie movie) { + return movieDao.add(movie); + } + + @Override + public Movie get(Long id) { + return movieDao.get(id).orElse(null); + } +} diff --git a/src/main/java/mate/academy/util/HibernateUtil.java b/src/main/java/mate/academy/util/HibernateUtil.java new file mode 100644 index 000000000..b55c9da81 --- /dev/null +++ b/src/main/java/mate/academy/util/HibernateUtil.java @@ -0,0 +1,38 @@ +package mate.academy.util; + +import mate.academy.entity.Movie; +import org.hibernate.SessionFactory; +import org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy; +import org.hibernate.cfg.Configuration; + +public class HibernateUtil { + private static final SessionFactory SESSION_FACTORY = initSessionFactory(); + private static final String USERNAME_KEY = "hibernate.connection.username"; + private static final String PASSWORD_KEY = "hibernate.connection.password"; + + private HibernateUtil() { + } + + public static SessionFactory getSessionFactory() { + return SESSION_FACTORY; + } + + private static SessionFactory initSessionFactory() { + try { + return buildConfiguration() + .configure() + .setProperty(USERNAME_KEY, PropertiesUtil.get(USERNAME_KEY)) + .setProperty(PASSWORD_KEY, PropertiesUtil.get(PASSWORD_KEY)) + .buildSessionFactory(); + } catch (Exception e) { + throw new RuntimeException("Can't create session factory ", e); + } + } + + private static Configuration buildConfiguration() { + Configuration configuration = new Configuration(); + configuration.setPhysicalNamingStrategy(new CamelCaseToUnderscoresNamingStrategy()); + configuration.addAnnotatedClass(Movie.class); + return configuration; + } +} diff --git a/src/main/java/mate/academy/util/PropertiesUtil.java b/src/main/java/mate/academy/util/PropertiesUtil.java new file mode 100644 index 000000000..7e7edffe2 --- /dev/null +++ b/src/main/java/mate/academy/util/PropertiesUtil.java @@ -0,0 +1,32 @@ +package mate.academy.util; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; +import mate.academy.exception.DataProcessingException; + +public class PropertiesUtil { + private static final String PROPERTIES_FILE = "application.properties"; + private static final Properties PROPERTIES = new Properties(); + + static { + loadProperties(); + } + + public PropertiesUtil() { + } + + public static String get(String key) { + return PROPERTIES.getProperty(key); + } + + private static void loadProperties() { + try (InputStream inputStream = PropertiesUtil.class.getClassLoader() + .getResourceAsStream(PROPERTIES_FILE)) { + PROPERTIES.load(inputStream); + } catch (IOException e) { + throw new DataProcessingException("Can't get data from PROPERTIES_FILE: " + + PROPERTIES_FILE, e); + } + } +} diff --git a/src/main/resources/application.properties.example b/src/main/resources/application.properties.example new file mode 100644 index 000000000..6aded0417 --- /dev/null +++ b/src/main/resources/application.properties.example @@ -0,0 +1,2 @@ +hibernate.connection.username=root +hibernate.connection.password=11111 diff --git a/src/main/resources/hibernate.cfg.xml b/src/main/resources/hibernate.cfg.xml new file mode 100644 index 000000000..ead7ab1e6 --- /dev/null +++ b/src/main/resources/hibernate.cfg.xml @@ -0,0 +1,16 @@ + + + + + + org.hibernate.dialect.MySQLDialect + jdbc:mysql://localhost:3306/ticket_app + com.mysql.cj.jdbc.Driver + root + 01Antpushk* + true + create-drop + + \ No newline at end of file From c134fb19484c9fe967702be21fb6f2e7ab9d846b Mon Sep 17 00:00:00 2001 From: Andrey Chertykovtsev Date: Tue, 30 Jul 2024 12:02:14 +0200 Subject: [PATCH 2/4] Change properties file reference for example - updated the reference to the properties file from "application.properties" to "application.properties.example". --- src/main/java/mate/academy/util/PropertiesUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/mate/academy/util/PropertiesUtil.java b/src/main/java/mate/academy/util/PropertiesUtil.java index 7e7edffe2..cd8d4aa5d 100644 --- a/src/main/java/mate/academy/util/PropertiesUtil.java +++ b/src/main/java/mate/academy/util/PropertiesUtil.java @@ -6,7 +6,7 @@ import mate.academy.exception.DataProcessingException; public class PropertiesUtil { - private static final String PROPERTIES_FILE = "application.properties"; + private static final String PROPERTIES_FILE = "application.properties.example"; private static final Properties PROPERTIES = new Properties(); static { From 09b7c83a0e45a0c491569017308d6e3314730e3c Mon Sep 17 00:00:00 2001 From: Andrey Chertykovtsev Date: Tue, 30 Jul 2024 12:39:11 +0200 Subject: [PATCH 3/4] Set up application properties for database configuration --- .gitignore | 1 - src/main/java/mate/academy/util/PropertiesUtil.java | 2 +- .../{application.properties.example => application.properties} | 0 src/main/resources/hibernate.cfg.xml | 2 -- 4 files changed, 1 insertion(+), 4 deletions(-) rename src/main/resources/{application.properties.example => application.properties} (100%) diff --git a/.gitignore b/.gitignore index 65ed00443..6366460f0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ .idea/* *.iml target/* -application.properties diff --git a/src/main/java/mate/academy/util/PropertiesUtil.java b/src/main/java/mate/academy/util/PropertiesUtil.java index cd8d4aa5d..7e7edffe2 100644 --- a/src/main/java/mate/academy/util/PropertiesUtil.java +++ b/src/main/java/mate/academy/util/PropertiesUtil.java @@ -6,7 +6,7 @@ import mate.academy.exception.DataProcessingException; public class PropertiesUtil { - private static final String PROPERTIES_FILE = "application.properties.example"; + private static final String PROPERTIES_FILE = "application.properties"; private static final Properties PROPERTIES = new Properties(); static { diff --git a/src/main/resources/application.properties.example b/src/main/resources/application.properties similarity index 100% rename from src/main/resources/application.properties.example rename to src/main/resources/application.properties diff --git a/src/main/resources/hibernate.cfg.xml b/src/main/resources/hibernate.cfg.xml index ead7ab1e6..5d7d17401 100644 --- a/src/main/resources/hibernate.cfg.xml +++ b/src/main/resources/hibernate.cfg.xml @@ -8,8 +8,6 @@ org.hibernate.dialect.MySQLDialect jdbc:mysql://localhost:3306/ticket_app com.mysql.cj.jdbc.Driver - root - 01Antpushk* true create-drop From 2c3a562aa2323d1980509c6e6e8514744e53e1e6 Mon Sep 17 00:00:00 2001 From: Andrey Chertykovtsev Date: Tue, 30 Jul 2024 11:45:52 +0200 Subject: [PATCH 4/4] Add Hibernate integration and Movie entity setup - Configured Hibernate with MySQL and HSQLDB, and updated dependencies in `pom.xml`. - Implemented `Movie` entity, DAOs, and service layers - Added utility classes and example property files for database connectivity. --- .gitignore | 1 + src/main/resources/application.properties.example | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 src/main/resources/application.properties.example diff --git a/.gitignore b/.gitignore index 6366460f0..65ed00443 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .idea/* *.iml target/* +application.properties diff --git a/src/main/resources/application.properties.example b/src/main/resources/application.properties.example new file mode 100644 index 000000000..6aded0417 --- /dev/null +++ b/src/main/resources/application.properties.example @@ -0,0 +1,2 @@ +hibernate.connection.username=root +hibernate.connection.password=11111