Hibernate and c3p0 and Many to Many mapping using Sakila DB to show some information to the user based on selections!
This is the directory layout I have..
This time lets see the the application in action first, then show the code:
pom.xml
persistence.xml
hibernate.properties
PersistenceUtil.java
PersistenceUtilImpl.java
Actor.java
Film.java
ActorService.java
ActorServiceImpl.java
FilmService.java
FilmServiceImpl.java
ActorView.java
ActorViewImpl.java
FilmView.java
FilmViewImpl.java
ActorMenu.java
FilmMenu.java
MainMenu.java
App.java
Do you think this is a proper MVC implementation? Any comments? Please do contact me if you have any! Thank you!
Prerequisities
Make sure you are running MySQL Server in your local with Sakila database loaded..This is the directory layout I have..
This time lets see the the application in action first, then show the code:
<?xml version="1.0" encoding="UTF-8"?> <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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <packaging>jar</packaging> <groupId>biz.tugay</groupId> <artifactId>learningjpa</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>javax.persistence</artifactId> <version>2.1.1</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.1.0.Final</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>5.1.0.Final</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-c3p0</artifactId> <version>5.1.0.Final</version> <scope>runtime</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.39</version> <scope>runtime</scope> </dependency> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> <scope>runtime</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> <version>1.10.19</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.5.0</version> <executions> <execution> <goals> <goal>exec</goal> </goals> </execution> </executions> <configuration> <executable>mvn</executable> <mainClass>biz.tugay.learningjpa.App</mainClass> </configuration> </plugin> </plugins> </build> <properties> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> </project>
persistence.xml
<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd" version="2.1"> <persistence-unit name="sakiladb" transaction-type="RESOURCE_LOCAL"> <properties/> </persistence-unit> </persistence>
hibernate.properties
hibernate.connection.driver_class=com.mysql.jdbc.Driver hibernate.connection.url=jdbc:mysql://localhost:3306/sakila hibernate.connection.username=root hibernate.connection.password=root hibernate.connection.useUnicode=true hibernate.connection.characterEncoding=utf-8 hibernate.show_sql=false hibernate.hbm2ddl.auto=update hibernate.c3p0.min_size=5 hibernate.c3p0.max_size=10 hibernate.c3p0.timeout=300 hibernate.c3p0.max_statements=5 hibernate.c3p0.unreturnedConnectionTimeout=2
PersistenceUtil.java
package biz.tugay.learningjpa.persistence; import javax.persistence.EntityManager; /** * User: Koray Tugay (koray@tugay.biz) * Date: 10/23/2016 * Time: 12:49 PM */ public interface PersistenceUtil { EntityManager getEntityManager(); void closeFactory(); }
PersistenceUtilImpl.java
package biz.tugay.learningjpa.persistence; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; /** * User: Koray Tugay (koray@tugay.biz) * Date: 10/16/2016 * Time: 4:06 PM */ public class PersistenceUtilImpl implements PersistenceUtil { private EntityManagerFactory entityManagerFactory; public PersistenceUtilImpl(final String persistenceUnit) { entityManagerFactory = Persistence.createEntityManagerFactory(persistenceUnit); } public EntityManager getEntityManager() { final EntityManager entityManager = entityManagerFactory.createEntityManager(); return entityManager; } public void closeFactory() { entityManagerFactory.close(); } }
Actor.java
package biz.tugay.learningjpa.model; import javax.persistence.*; import java.util.List; /** * User: Koray Tugay (koray@tugay.biz) * Date: 10/23/2016 * Time: 9:49 AM */ @Entity public class Actor { private Integer id; private String firstname; private String lastname; private List<Film> films; @Id @Column(name = "actor_id") @GeneratedValue(strategy = GenerationType.AUTO) public Integer getId() { return id; } public void setId(Integer actor_id) { this.id = actor_id; } @Basic @Column(name = "first_name") public String getFirstname() { return firstname; } public void setFirstname(String first_name) { this.firstname = first_name; } @Basic @Column(name = "last_name") public String getLastname() { return lastname; } public void setLastname(String last_name) { this.lastname = last_name; } @ManyToMany @JoinTable(name = "film_actor", joinColumns = @JoinColumn(name = "actor_id"), inverseJoinColumns = @JoinColumn(name = "film_id") ) public List<Film> getFilms() { return films; } public void setFilms(List<Film> films) { this.films = films; } }
Film.java
package biz.tugay.learningjpa.model; import javax.persistence.*; import java.util.List; /** * User: Koray Tugay (koray@tugay.biz) * Date: 10/23/2016 * Time: 10:03 AM */ @Entity public class Film { private Integer id; private String title; private List<Actor> actors; @Id @Column(name = "film_id") @GeneratedValue(strategy = GenerationType.AUTO) public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } @Basic public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } @ManyToMany @JoinTable(name = "film_actor", joinColumns = @JoinColumn(name = "film_id"), inverseJoinColumns = @JoinColumn(name = "actor_id")) public List<Actor> getActors() { return actors; } public void setActors(List<Actor> actors) { this.actors = actors; } }
ActorService.java
package biz.tugay.learningjpa.service; import biz.tugay.learningjpa.model.Actor; import biz.tugay.learningjpa.model.Film; import java.util.List; /** * User: Koray Tugay (koray@tugay.biz) * Date: 10/23/2016 * Time: 1:40 PM */ public interface ActorService { List<Actor> allActors(); List<Actor> actorsLimitBy(int limit); Actor getActorById(int actorId); List<Actor> getActorsOfFilm(Film film); }
ActorServiceImpl.java
package biz.tugay.learningjpa.service.impl; import biz.tugay.learningjpa.model.Actor; import biz.tugay.learningjpa.model.Film; import biz.tugay.learningjpa.persistence.PersistenceUtil; import biz.tugay.learningjpa.service.ActorService; import javax.persistence.EntityManager; import javax.persistence.TypedQuery; import java.util.ArrayList; import java.util.List; /** * User: Koray Tugay (koray@tugay.biz) * Date: 10/23/2016 * Time: 12:03 PM */ public final class ActorServiceImpl implements ActorService { private final PersistenceUtil persistenceUtil; public ActorServiceImpl(PersistenceUtil persistenceUtil) { this.persistenceUtil = persistenceUtil; } @Override public List<Actor> allActors() { final EntityManager entityManager = persistenceUtil.getEntityManager(); final TypedQuery<Actor> query = entityManager.createQuery("SELECT a FROM Actor a", Actor.class); final List<Actor> allActors = query.getResultList(); entityManager.close(); return allActors; } @Override public List<Actor> actorsLimitBy(int limit) { final EntityManager entityManager = persistenceUtil.getEntityManager(); final TypedQuery<Actor> query = entityManager.createQuery("SELECT a FROM Actor a", Actor.class); query.setMaxResults(limit); final List<Actor> actorsLimitBy = query.getResultList(); entityManager.close(); return actorsLimitBy; } @Override public Actor getActorById(int actorId) { final EntityManager entityManager = persistenceUtil.getEntityManager(); final Actor actor = entityManager.find(Actor.class, actorId); entityManager.close(); return actor; } @Override public List<Actor> getActorsOfFilm(Film film) { final EntityManager entityManager = persistenceUtil.getEntityManager(); final Film persistFilm = entityManager.find(Film.class, film.getId()); // Load lazy fetched Actors of the film.. final ArrayList<Actor> actors = new ArrayList<Actor>(); actors.addAll(persistFilm.getActors()); entityManager.close(); return actors; } }
FilmService.java
package biz.tugay.learningjpa.service; import biz.tugay.learningjpa.model.Actor; import biz.tugay.learningjpa.model.Film; import java.util.List; /** * User: Koray Tugay (koray@tugay.biz) * Date: 10/23/2016 * Time: 1:40 PM */ public interface FilmService { List<Film> allFilms(); Film filmById(int filmId); List<Film> filmsOfActor(Actor actor); }
FilmServiceImpl.java
package biz.tugay.learningjpa.service.impl; import biz.tugay.learningjpa.model.Actor; import biz.tugay.learningjpa.model.Film; import biz.tugay.learningjpa.persistence.PersistenceUtil; import biz.tugay.learningjpa.service.FilmService; import javax.persistence.EntityManager; import javax.persistence.TypedQuery; import java.util.ArrayList; import java.util.List; /** * User: Koray Tugay (koray@tugay.biz) * Date: 10/23/2016 * Time: 12:40 PM */ public final class FilmServiceImpl implements FilmService { private final PersistenceUtil persistenceUtil; public FilmServiceImpl(final PersistenceUtil persistenceUtil) { this.persistenceUtil = persistenceUtil; } @Override public List<Film> allFilms() { final EntityManager entityManager = persistenceUtil.getEntityManager(); final TypedQuery<Film> query = entityManager.createQuery("SELECT f FROM Film f", Film.class); final List<Film> allFilms = query.getResultList(); entityManager.close(); return allFilms; } @Override public Film filmById(int filmId) { final EntityManager entityManager = persistenceUtil.getEntityManager(); final Film film = entityManager.find(Film.class, filmId); entityManager.close(); return film; } @Override public List<Film> filmsOfActor(Actor actor) { final EntityManager entityManager = persistenceUtil.getEntityManager(); final Actor persistentActor = entityManager.find(Actor.class, actor.getId()); final ArrayList<Film> films = new ArrayList<Film>(); films.addAll(persistentActor.getFilms()); entityManager.close(); return films; } }
ActorView.java
package biz.tugay.learningjpa.view; import biz.tugay.learningjpa.model.Actor; import java.util.List; /** * User: Koray Tugay (koray@tugay.biz) * Date: 10/23/2016 * Time: 2:17 PM */ public interface ActorView { void printActors(final List<Actor> actors); int askForActorId(); }
ActorViewImpl.java
package biz.tugay.learningjpa.view.impl; import biz.tugay.learningjpa.model.Actor; import biz.tugay.learningjpa.view.ActorView; import java.util.List; import java.util.Scanner; /** * User: Koray Tugay (koray@tugay.biz) * Date: 10/23/2016 * Time: 12:11 PM */ public class ActorViewImpl implements ActorView { @Override public void printActors(final List<Actor> actors) { System.out.println(""); System.out.println(""); System.out.println("== Printing Actors =="); System.out.println("ID\tFirstname\tLastname"); for (Actor actor : actors) { System.out.println(actor.getId() + "\t" + actor.getFirstname() + "\t" + actor.getLastname()); } } @Override public int askForActorId() { System.out.println(""); System.out.println(""); System.out.println("Please enter Actor ID:"); final Scanner scanner = new Scanner(System.in); int actorId = scanner.nextInt(); return actorId; } }
FilmView.java
package biz.tugay.learningjpa.view; import biz.tugay.learningjpa.model.Film; import java.util.List; /** * User: Koray Tugay (koray@tugay.biz) * Date: 10/23/2016 * Time: 2:19 PM */ public interface FilmView { void printFilms(List<Film> films); int askForFilmId(); }
FilmViewImpl.java
package biz.tugay.learningjpa.view.impl; import biz.tugay.learningjpa.model.Film; import biz.tugay.learningjpa.view.FilmView; import java.util.List; import java.util.Scanner; /** * User: Koray Tugay (koray@tugay.biz) * Date: 10/23/2016 * Time: 12:41 PM */ public class FilmViewImpl implements FilmView { @Override public void printFilms(List<Film> films) { System.out.println(""); System.out.println(""); System.out.println("== Printing Films =="); System.out.println("==ID==\t\t==Title=="); for (Film film : films) { System.out.println(film.getId() + "\t\t" + film.getTitle()); } System.out.println(""); System.out.println(""); } @Override public int askForFilmId() { System.out.println(""); System.out.println(""); System.out.println("Please Enter Film ID:"); final Scanner scanner = new Scanner(System.in); final int filmId = scanner.nextInt(); return filmId; } }
ActorMenu.java
package biz.tugay.learningjpa.controller; import biz.tugay.learningjpa.model.Actor; import biz.tugay.learningjpa.model.Film; import biz.tugay.learningjpa.service.ActorService; import biz.tugay.learningjpa.view.ActorView; import java.util.List; /** * User: Koray Tugay (koray@tugay.biz) * Date: 10/23/2016 * Time: 2:44 PM */ public class ActorMenu { private final ActorView actorView; private final ActorService actorService; public ActorMenu(ActorView actorView, ActorService actorService) { this.actorView = actorView; this.actorService = actorService; } public void listAllActors() { final List<Actor> actors = actorService.allActors(); actorView.printActors(actors); } public Actor askForActorId() { int actorId = actorView.askForActorId(); final Actor actor = actorService.getActorById(actorId); return actor; } public void printActorsOfFilm(Film film) { final List<Actor> actors = actorService.getActorsOfFilm(film); actorView.printActors(actors); } }
FilmMenu.java
package biz.tugay.learningjpa.controller; import biz.tugay.learningjpa.model.Actor; import biz.tugay.learningjpa.model.Film; import biz.tugay.learningjpa.service.FilmService; import biz.tugay.learningjpa.view.FilmView; import java.util.List; /** * User: Koray Tugay (koray@tugay.biz) * Date: 10/23/2016 * Time: 2:51 PM */ public class FilmMenu { private final FilmService filmService; private final FilmView filmView; public FilmMenu(FilmService filmService, FilmView filmView) { this.filmService = filmService; this.filmView = filmView; } public void printsFilmsOfActor(Actor actor) { final List<Film> films = filmService.filmsOfActor(actor); filmView.printFilms(films); } public void listAllFilms() { final List<Film> films = filmService.allFilms(); filmView.printFilms(films); } public Film askForFilmById() { final int filmId = filmView.askForFilmId(); final Film film = filmService.filmById(filmId); return film; } }
MainMenu.java
package biz.tugay.learningjpa.controller; import biz.tugay.learningjpa.model.Actor; import biz.tugay.learningjpa.model.Film; import java.io.IOException; import java.util.Scanner; /** * User: Koray Tugay (koray@tugay.biz) * Date: 10/23/2016 * Time: 2:26 PM */ public class MainMenu { private final ActorMenu actorMenu; private final FilmMenu filmMenu; public MainMenu(ActorMenu actorMenu, FilmMenu filmMenu) { this.actorMenu = actorMenu; this.filmMenu = filmMenu; } public void showMainMenu() throws IOException, InterruptedException { // Clear console.. new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor(); greetUser(); final int userInput = getUserInput(); if (userInput == -1) { System.exit(-1); } else { processUserInput(userInput); showMainMenu(); } } private void greetUser() { System.out.println("Please select:"); System.out.println("1 - Find Films by Actor"); System.out.println("2 - Find Actors of a Film"); System.out.println("Type -1 to Quit program.."); } private int getUserInput() { final Scanner scanner = new Scanner(System.in); final int userSelection = scanner.nextInt(); return userSelection; } private void processUserInput(int userInput) { switch (userInput) { case 1: actorMenu.listAllActors(); final Actor actor = actorMenu.askForActorId(); filmMenu.printsFilmsOfActor(actor); break; case 2: filmMenu.listAllFilms(); final Film film = filmMenu.askForFilmById(); actorMenu.printActorsOfFilm(film); break; } pressAnyKeyToContinue(); } void pressAnyKeyToContinue() { System.out.println("Press any key to continue.."); try { //noinspection ResultOfMethodCallIgnored System.in.read(); } catch (IOException ignored) { } } }
App.java
package biz.tugay.learningjpa; import biz.tugay.learningjpa.controller.ActorMenu; import biz.tugay.learningjpa.controller.FilmMenu; import biz.tugay.learningjpa.controller.MainMenu; import biz.tugay.learningjpa.persistence.PersistenceUtilImpl; import biz.tugay.learningjpa.service.ActorService; import biz.tugay.learningjpa.service.impl.ActorServiceImpl; import biz.tugay.learningjpa.service.FilmService; import biz.tugay.learningjpa.service.impl.FilmServiceImpl; import biz.tugay.learningjpa.view.ActorView; import biz.tugay.learningjpa.view.impl.ActorViewImpl; import biz.tugay.learningjpa.view.FilmView; import biz.tugay.learningjpa.view.impl.FilmViewImpl; import java.io.IOException; /** * User: Koray Tugay (koray@tugay.biz) * Date: 10/23/2016 * Time: 12:12 PM */ public class App { public static void main(String[] args) throws IOException, InterruptedException { final PersistenceUtilImpl persistenceUtil = new PersistenceUtilImpl("sakiladb"); final ActorService actorService = new ActorServiceImpl(persistenceUtil); final FilmService filmService = new FilmServiceImpl(persistenceUtil); final ActorView actorView = new ActorViewImpl(); final FilmView filmView = new FilmViewImpl(); final ActorMenu actorMenu = new ActorMenu(actorView, actorService); final FilmMenu filmMenu = new FilmMenu(filmService, filmView); final MainMenu mainMenu = new MainMenu(actorMenu, filmMenu); mainMenu.showMainMenu(); } }
Do you think this is a proper MVC implementation? Any comments? Please do contact me if you have any! Thank you!