Skip to content

Gp 130 migrate photo comment dao exercise MAIN #21

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions 3-0-jpa-and-hibernate/3-2-2-photo-comment-dao/README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# <img src="https://raw.githubusercontent.com/bobocode-projects/resources/master/image/logo_transparent_background.png" height=50/>Photo comment DAO exercise :muscle:
Improve your *Hibernate ORM* and *JPA One-To-Many* relationship mapping skills
### Task
Each `Photo` has a list of `PhotoComments`. Comments cannot exits without photo associated. You job is to provide a mapping
for this **bidirectional *one to many* relationship** and **implement required DAO methods.** Please follow the instructions
in the todo sections.

To verify your mapping, run `PhotoCommentMappingTest.java`
To verify your DAO implementation, run `PhotoDaoTest.java`


### Pre-conditions :heavy_exclamation_mark:
You're supposed to be familiar with *JPA* mapping strategies and *Hibernate ORM*

### How to start :question:
* Just clone the repository and start implementing the **todo** section, verify your changes by running tests
* If you don't have enough knowledge about this domain, check out the [links below](#related-materials-information_source)
* Don't worry if you got stuck, checkout the **exercise/completed** branch and see the final implementation

### Related materials :information_source:
* [JPA and Hibernate basics tutorial](https://github.com/boy4uck/jpa-hibernate-tutorial/tree/master/jpa-hibernate-basics) <img src="https://raw.githubusercontent.com/bobocode-projects/resources/master/image/logo_transparent_background.png" height=20/>
* [@OneToMany association](http://docs.jboss.org/hibernate/orm/5.3/userguide/html_single/Hibernate_User_Guide.html#associations-one-to-many)<img src="https://upload.wikimedia.org/wikipedia/commons/2/22/Hibernate_logo_a.png" height=15/>
* [The best way to map a @OneToMany relationship with JPA and Hibernate](https://vladmihalcea.com/the-best-way-to-map-a-onetomany-association-with-jpa-and-hibernate/)


22 changes: 22 additions & 0 deletions 3-0-jpa-and-hibernate/3-2-2-photo-comment-dao/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?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">
<parent>
<artifactId>3-0-jpa-and-hibernate</artifactId>
<groupId>com.bobocode</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>3-2-2-photo-comment-dao</artifactId>

<dependencies>
<dependency>
<groupId>com.bobocode</groupId>
<artifactId>jpa-hibernate-util</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.bobocode.dao;

import com.bobocode.model.Photo;

import java.util.List;

/**
* {@link PhotoDao} defines and API of Data-Access Object for entity {@link Photo}
*/
public interface PhotoDao {

/**
* Saves photo into db and sets an id
*
* @param photo new photo
*/
void save(Photo photo);

/**
* Retrieves a photo from the database by its id
*
* @param id photo id
* @return photo instance
*/
Photo findById(long id);

/**
* Returns a list of all stored photos
*
* @return list of stored photos
*/
List<Photo> findAll();

/**
* Removes a photo from the database
*
* @param photo an instance of stored photo
*/
void remove(Photo photo);

/**
* Adds a new comment to an existing photo. This method does not require additional SQL select methods to load
* {@link Photo}.
*
* @param photoId
* @param comment
*/
void addComment(long photoId, String comment);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.bobocode.dao;

import com.bobocode.model.Photo;
import com.bobocode.util.ExerciseNotCompletedException;

import javax.persistence.EntityManagerFactory;
import java.util.List;

/**
* Please note that you should not use auto-commit mode for your implementation.
*/
public class PhotoDaoImpl implements PhotoDao {
private EntityManagerFactory entityManagerFactory;

public PhotoDaoImpl(EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
}

@Override
public void save(Photo photo) {
throw new ExerciseNotCompletedException(); // todo
}

@Override
public Photo findById(long id) {
throw new ExerciseNotCompletedException(); // todo
}

@Override
public List<Photo> findAll() {
throw new ExerciseNotCompletedException(); // todo
}

@Override
public void remove(Photo photo) {
throw new ExerciseNotCompletedException(); // todo
}

@Override
public void addComment(long photoId, String comment) {
throw new ExerciseNotCompletedException(); // todo
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.bobocode.model;

import com.bobocode.util.ExerciseNotCompletedException;
import lombok.Getter;
import lombok.Setter;

import java.util.List;

/**
* todo:
* - make a setter for field {@link Photo#comments} {@code private}
* - implement equals() and hashCode() based on identifier field
*
* - configure JPA entity
* - specify table name: "photo"
* - configure auto generated identifier
* - configure not nullable and unique column: url
*
* - initialize field comments
* - map relation between Photo and PhotoComment on the child side
* - implement helper methods {@link Photo#addComment(PhotoComment)} and {@link Photo#removeComment(PhotoComment)}
* - enable cascade type {@link javax.persistence.CascadeType#ALL} for field {@link Photo#comments}
* - enable orphan removal
*/
@Getter
@Setter
public class Photo {
private Long id;
private String url;
private String description;
private List<PhotoComment> comments;

public void addComment(PhotoComment comment) {
throw new ExerciseNotCompletedException();
}

public void removeComment(PhotoComment comment) {
throw new ExerciseNotCompletedException();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.bobocode.model;

import lombok.Getter;
import lombok.Setter;

import java.time.LocalDateTime;

/**
* todo:
* - implement equals and hashCode based on identifier field
*
* - configure JPA entity
* - specify table name: "photo_comment"
* - configure auto generated identifier
* - configure not nullable column: text
*
* - map relation between Photo and PhotoComment using foreign_key column: "photo_id"
* - configure relation as mandatory (not optional)
*/
@Getter
@Setter
public class PhotoComment {
private Long id;
private String text;
private LocalDateTime createdOn;
private Photo photo;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.1">

<persistence-unit name="PhotoComments">
<class>com.bobocode.model.Photo</class>
<class>com.bobocode.model.PhotoComment</class>

<properties>
<property name="hibernate.connection.url" value="jdbc:h2:mem:movie_db;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false"/>
<property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
<property name="hibernate.connection.username" value="movie_user"/>
<property name="hibernate.connection.password" value="movie_pass"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<property name="hibernate.hbm2ddl.auto" value="create"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
</properties>
</persistence-unit>

</persistence>
Loading